Created
March 10, 2021 08:58
-
-
Save jmarsh24/f7fe39440b278bf25bb1c0df61ae917e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Video::MusicRecognition::AcrCloud | |
class << self | |
def fetch(youtube_id) | |
new(youtube_id).update_video | |
end | |
end | |
def initialize(youtube_id) | |
@youtube_id = youtube_id | |
@video = Video.find_by(youtube_id: youtube_id) | |
end | |
def update_video | |
@video.update(video_params) | |
end | |
private | |
def file_path | |
@file_path ||= Audio.import(@youtube_id) | |
end | |
def acr_cloud_response | |
@acr_cloud_reponse ||= Client.send_audio(file_path) | |
end | |
def video_params | |
{ | |
acr_response_code: acr_response_code, | |
spotify_album_id: spotify_album_id, | |
spotify_album_name: spotify_album_name, | |
spotify_artist_id: spotify_artist_id, | |
spotify_artist_id_1: spotify_artist_id_1, | |
spotify_artist_id_2: spotify_artist_id_2, | |
spotify_artist_name: spotify_artist_name, | |
spotify_artist_name_1: spotify_artist_name_1, | |
spotify_artist_name_2: spotify_artist_name_2, | |
spotify_track_id: spotify_track_id, | |
spotify_track_name: spotify_track_name, | |
acr_cloud_artist_name: acr_cloud_artist_name, | |
acr_cloud_artist_name_1: acr_cloud_artist_name_1, | |
acr_cloud_album_name: acr_cloud_album_name, | |
acr_cloud_track_name: acr_cloud_track_name, | |
youtube_song_id: youtube_song_id, | |
isrc: isrc | |
} | |
end | |
def acr_response_code | |
return if parsed_acr_cloud_data.dig("status", "code").blank? | |
@acr_response_code ||= parsed_acr_cloud_data.dig("status", "code") | |
end | |
def youtube_song_id | |
return if parsed_acr_cloud_data.deep_find("youtube").blank? | |
@youtube_song_id ||= parsed_acr_cloud_data.deep_find("youtube")["vid"] | |
end | |
def isrc | |
return if parsed_acr_cloud_data.deep_find("external_ids").blank? | |
@isrc ||= parsed_acr_cloud_data.deep_find("external_ids")["isrc"] | |
end | |
def spotify_params | |
return if parsed_acr_cloud_data.deep_find("spotify").blank? | |
@spotify_params ||= parsed_acr_cloud_data.deep_find("spotify") | |
end | |
def spotify_album_id | |
return if spotify_params.blank? | |
@spotify_album_id ||= spotify_params.dig("album", "id") | |
end | |
def spotify_artist_id | |
return if spotify_params.blank? | |
@spotify_artist_id ||= spotify_params.dig("artists", 0, "id") | |
end | |
def spotify_artist_id_1 | |
return if spotify_params.blank? | |
@spotify_artist_id_1 ||= spotify_params.dig("artists", 1, "id") | |
end | |
def spotify_artist_id_2 | |
return if spotify_params.blank? | |
@spotify_artist_id_2 ||= spotify_params.dig("artists", 2, "id") | |
end | |
def spotify_track_id | |
return if spotify_params.blank? | |
@spotify_track_id ||= spotify_params.dig("track", "id") | |
end | |
def spotify_album_name | |
return if spotify_album_id.blank? | |
@spotify_album_name ||= RSpotify::Album.find(@spotify_album_id).name | |
end | |
def spotify_artist_name | |
return if spotify_artist_id.blank? | |
@spotify_artist_name ||= RSpotify::Artist.find(@spotify_artist_id).name | |
end | |
def spotify_artist_name_1 | |
return if spotify_artist_id_1.blank? | |
@spotify_artist_name_1 ||= RSpotify::Artist.find(@spotify_artist_id_1).name | |
end | |
def spotify_artist_name_2 | |
return if @spotify_artist_id_2.blank? | |
@spotify_artist_name_2 ||= RSpotify::Artist.find(@spotify_artist_id_2).name | |
end | |
def spotify_track_name | |
return if @spotify_track_id.blank? | |
@spotify_track_name ||= RSpotify::Track.find(@spotify_track_id).name | |
end | |
def acr_cloud_artists | |
return if parsed_acr_cloud_data.deep_find("artists").blank? | |
parsed_acr_cloud_data.deep_find("artists") | |
end | |
def acr_cloud_artist_name | |
return if acr_cloud_artists.blank? | |
acr_cloud_artists.dig(0, "name") | |
end | |
def acr_cloud_artist_name_1 | |
return if acr_cloud_artists.blank? | |
acr_cloud_artists.dig(1, "name") | |
end | |
def acr_cloud_album_name | |
return if parsed_acr_cloud_data.deep_find("album").blank? | |
parsed_acr_cloud_data.deep_find("album").dig("name") | |
end | |
def acr_cloud_track_name | |
return if parsed_acr_cloud_data.deep_find("title").blank? | |
parsed_acr_cloud_data.deep_find("title") | |
end | |
def parsed_acr_cloud_data | |
@parsed_acr_cloud_data ||= JSON.parse(acr_cloud_response).extend Hashie::Extensions::DeepFind | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class AcrMusicMatchWorker | |
include Sidekiq::Worker | |
sidekiq_options queue: :default, retry: false | |
def perform(youtube_id) | |
Video::MusicRecognition::AcrCloud.fetch(youtube_id) | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Video::MusicRecognition::AcrCloud::Audio | |
class << self | |
def import(youtube_id) | |
new(youtube_id).import | |
end | |
end | |
def initialize(youtube_id) | |
@youtube_id = youtube_id | |
@youtube_video_audio = fetch_by_id(youtube_id) | |
@video = Video.find_by(youtube_id: youtube_id) | |
end | |
def import | |
transcode | |
output_file_path | |
end | |
private | |
def fetch_by_id(_youtube_id) | |
YoutubeDL.download( | |
"https://www.youtube.com/watch?v=#{@youtube_id}", | |
{ format: "140", output: "~/environment/data/audio/%(id)s.mp3" } | |
) | |
end | |
def audio_file_path | |
@youtube_video_audio.filename.to_s | |
end | |
def output_file_path | |
calculate_time | |
audio_file_path.gsub(/.mp3/, "_#{@time_1}_#{@time_2}.mp3") | |
end | |
def calculate_time | |
@time_1 = @youtube_video_audio.duration / 2 | |
@time_2 = @time_1 + 20 | |
end | |
def transcode | |
song = FFMPEG::Movie.new(audio_file_path) | |
song.transcode(output_file_path, { custom: %W[-ss #{@time_1} -to #{@time_2}] }) | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Video::MusicRecognition::AcrCloud::Client | |
HTTP_METHOD = "POST".freeze | |
HTTP_URI = "/v1/identify".freeze | |
DATA_TYPE = "audio".freeze | |
SIGNATURE_VERSION = "1".freeze | |
TIMESTAMP = Time.now.utc.to_i.to_s.freeze | |
ACCESS_KEY = ENV["ACRCLOUD_ACCESS_KEY"] | |
ACCESS_SECRET = ENV["ACRCLOUD_SECRET_KEY"] | |
REQ_URL = "http://identify-eu-west-1.acrcloud.com/v1/identify".freeze | |
class << self | |
def send_audio(file_path) | |
new(file_path).send_audio_file_to_acr_cloud | |
end | |
end | |
def initialize(file_path) | |
@file_path = file_path | |
end | |
def send_audio_file_to_acr_cloud | |
faraday = Faraday.new do |f| | |
f.request :multipart | |
f.request :url_encoded | |
f.adapter :net_http | |
end | |
response = faraday.post(url, body) | |
response.body | |
end | |
private | |
def body | |
{ | |
sample: sample_file, | |
access_key: ACCESS_KEY, | |
data_type: DATA_TYPE, | |
signature_version: SIGNATURE_VERSION, | |
signature: signature, | |
sample_bytes: sample_bytes, | |
timestamp: TIMESTAMP | |
} | |
end | |
def sample_file | |
Faraday::UploadIO.new(@file_path, "audio/mp3") | |
end | |
def url | |
URI.parse(REQ_URL) | |
end | |
def sample_bytes | |
File.size(@file_path) | |
end | |
def unsigned_string | |
"#{HTTP_METHOD}\n#{HTTP_URI}\n#{ACCESS_KEY}\n#{DATA_TYPE}\n#{SIGNATURE_VERSION}\n#{TIMESTAMP}" | |
end | |
def digest | |
OpenSSL::Digest.new("sha1") | |
end | |
def signature | |
Base64.encode64(OpenSSL::HMAC.digest(digest, ACCESS_SECRET, unsigned_string)).strip | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment