| 1 | # The KaroKowe naming, i.e; camel-cased style, is only being used for branding. |
| 2 | # Inside the code, we refer this tool as Karokowe. |
| 3 | |
| 4 | class KarokoweJob < ApplicationJob |
| 5 | # TODO: Set priority based on account type. |
| 6 | queue_as :default |
| 7 | |
| 8 | def perform(audio_file_id) |
| 9 | # Get the file to split. |
| 10 | file = AudioFile.find_by(id: audio_file_id) |
| 11 | |
| 12 | # Make sure the actual file is attached. |
| 13 | # Otherwise, we don't want to do the job. |
| 14 | return if file.nil? || !file.source_file.attached? |
| 15 | |
| 16 | file_path = ActiveStorage::Blob.service.send(:path_for, file.source_file.key) |
| 17 | |
| 18 | # Change to spleeter working directory. |
| 19 | # TODO: Tidy up. |
| 20 | if Rails.env.production? |
| 21 | Dir.chdir('/home/deploy/apps/spleeter/') |
| 22 | else |
| 23 | Dir.chdir('../spleeter/') |
| 24 | end |
| 25 | |
| 26 | codec = 'mp3' |
| 27 | |
| 28 | # Always use the fullpath to the Spleeter. |
| 29 | # TODO: Tidy up. |
| 30 | if Rails.env.production? |
| 31 | system("/home/deploy/.local/bin/spleeter separate -p spleeter:2stems-16kHz -o ./output/ #{file_path} -c #{codec} >> karokowe_job_log.txt") |
| 32 | else |
| 33 | system("spleeter separate -p spleeter:2stems-16kHz -o ./output/ #{file_path} -c #{codec} >> karokowe_job_log.txt") |
| 34 | end |
| 35 | |
| 36 | file_output_directory = "output/#{file.source_file.blob.key}" |
| 37 | |
| 38 | # Compose results for karaoke |
| 39 | result_karaoke_path = "#{file_output_directory}/accompaniment.#{codec}" |
| 40 | |
| 41 | # Wait until the file exist... |
| 42 | until File.exist?(result_karaoke_path) |
| 43 | system("echo 'We are waiting for #{result_karaoke_path}...'") |
| 44 | sleep 60 |
| 45 | end |
| 46 | |
| 47 | # We only save the result if user doesn't cancel the process |
| 48 | # Ideally, we cancel the running process immediately |
| 49 | if !file.audio_file_karokowe_status.nil? && file.audio_file_karokowe_status.cancelled? |
| 50 | system("rm -rf #{file_output_directory}") |
| 51 | return |
| 52 | end |
| 53 | |
| 54 | result_karaoke_file = File.open(result_karaoke_path) |
| 55 | result_karaoke_filename = "karaoke-version-#{file.id}.#{codec}" |
| 56 | result_karaoke = KaraokeFile.new(audio_file_id: file.id) |
| 57 | |
| 58 | result_karaoke.source_file.attach(io: result_karaoke_file, filename: result_karaoke_filename) |
| 59 | result_karaoke.save |
| 60 | |
| 61 | # Cleanup Spleeter output folder |
| 62 | system("rm -rf #{file_output_directory}") |
| 63 | |
| 64 | if file.audio_file_karokowe_status.nil? |
| 65 | AudioFileKarokoweStatus.new(audio_file_id: audio_file_id, status: :done).save |
| 66 | elsif file.audio_file_karokowe_status.done! |
| 67 | end |
| 68 | end |
| 69 | end |