Last active
February 7, 2025 01:20
-
-
Save himenlinamarbric/255b6021c20eb0913dd274884b5f1ba3 to your computer and use it in GitHub Desktop.
This file contains 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
-- Requires a loopback audio device, try | |
-- - https://rogueamoeba.com/loopback/ | |
-- - https://github.com/ExistentialAudio/BlackHole | |
-- Needs https://github.com/wez/atomicparsley | |
property output_folder : "/Users/USER/Music/rec" | |
property atomicparsley_path : "/opt/homebrew/bin/atomicparsley" | |
property file_extension : ".m4a" | |
on format_filename(track_artist, track_album, track_name, track_number) | |
set track_str to "" & track_number | |
if (track_number < 10) then set track_str to ("0" & track_str) | |
set r to "" & track_str & " - " & track_name | |
set x to length of r | |
if (x > 250) then set x to 250 | |
return (((characters 1 thru x of r) as string) & file_extension) | |
end format_filename | |
on format_foldername(track_artist, track_album, track_name, track_number) | |
set r to "/" & track_artist & " - " & track_album & "/" | |
set x to length of r | |
if (x > 250) then set x to 250 | |
return ((characters 1 thru x of r) as string) | |
end format_foldername | |
tell application "Spotify" | |
if not running then activate | |
if player state is playing then pause | |
end tell | |
tell application "QuickTime Player" | |
display alert "Ready for recording. Please start playing the first song in the album / playlist, then click OK in this dialog." | |
end tell | |
tell application "Spotify" | |
set track_counter to 0 | |
set track_ids to my sp_get_tracks() | |
repeat with track_id in track_ids | |
play track track_id | |
delay 2 | |
pause | |
set track_counter to (track_counter + 1) | |
set metadata to my sp_current_metadata() | |
set track_length to (duration of current track) / 1000 | |
set player position to 0 | |
set sound volume to 100 | |
set qtrec to my qt_setup() | |
delay 2 | |
my qt_start_recording(qtrec) | |
play | |
delay track_length | |
my qt_stop_recording(qtrec, track_counter) | |
pause | |
my save_metadata(metadata, track_counter) | |
end repeat | |
end tell | |
on sp_get_tracks() | |
tell application "Spotify" | |
set track_ids to {} | |
set track_id to (id of current track) | |
repeat until track_id is equal to "" | |
set track_ids to track_ids & track_id | |
next track | |
pause | |
delay 0.5 | |
set track_id to (id of current track) | |
if track_ids contains track_id then set track_id to "" | |
end repeat | |
return track_ids | |
end tell | |
end sp_get_tracks | |
on qt_setup() | |
tell application "QuickTime Player" | |
set qtrec to new audio recording | |
return qtrec | |
end tell | |
end qt_setup | |
on qt_start_recording(qtrec) | |
tell application "QuickTime Player" | |
start qtrec | |
end tell | |
end qt_start_recording | |
on qt_stop_recording(qtrec, track_counter) | |
tell application "QuickTime Player" | |
stop qtrec | |
set filePath to a reference to POSIX file (my temp_filename(track_counter, false)) | |
export the front document in file filePath using settings preset "Audio Only" | |
close every document saving no | |
end tell | |
end qt_stop_recording | |
on sp_current_metadata() | |
tell application "Spotify" | |
try | |
set current_track to current track | |
set track_artist to artist of current_track | |
set track_album to album of current_track | |
set track_name to name of current_track | |
set track_number to track number of current_track | |
return {md_artist:track_artist, md_album:track_album, md_name:track_name, md_number:track_number} | |
on error number -1728 -- no current track | |
return {} | |
end try | |
end tell | |
end sp_current_metadata | |
on save_metadata(metadata, track_counter) | |
tell application "Spotify" | |
set track_artist to md_artist of metadata | |
set track_album to md_album of metadata | |
set track_name to md_name of metadata | |
set track_number to md_number of metadata | |
set new_filename to my format_filename(track_artist, track_album, track_name, track_number) | |
-- eliminate special characters from file name | |
-- TODO: keep brackets [], also other symbols | |
-- NOTE: 'do shell script' within a 'tell' block requires 'tell me to', https://developer.apple.com/library/mac/releasenotes/AppleScript/RN-AppleScript/RN-10_6/RN-10_6.html#//apple_ref/doc/uid/TP40000982-CH106-SW6 | |
tell me to set new_filename to do shell script ("echo \"" & new_filename & "\" | sed 's/[^a-zA-Z0-9 .äöüÄÖÜéèàç&(){}-]/_/g'") | |
my wait_file_exists(my temp_filename(track_counter, false)) | |
set current_file to my temp_filename(track_counter, true) | |
set subfolder to my format_foldername(track_artist, track_album, track_name, track_number) | |
set new_file to ("\"" & output_folder & subfolder & new_filename & "\"") | |
tell me to do shell script ("mkdir -p " & "\"" & output_folder & subfolder & "\"") | |
tell me to do shell script ("mv " & current_file & " " & new_file) | |
delay 5 -- file exists, but export might still be in progress... | |
-- update metadata (tags) | |
tell me to do shell script atomicparsley_path & " " & new_file & " --artist \"" & track_artist & "\" --album \"" & track_album & "\" --title \"" & track_name & "\" --tracknum " & track_number & " --overWrite" | |
end tell | |
end save_metadata | |
on temp_filename(track_counter, add_quote) | |
set filename to output_folder & "/" & track_counter & file_extension | |
if add_quote then | |
return ("\"" & filename & "\"") | |
else | |
return filename | |
end if | |
end temp_filename | |
on wait_file_exists(filename) | |
set c to 0 | |
repeat until c is equal to 10 | |
if file_exists(filename) then | |
return | |
end if | |
set c to c + 1 | |
delay 0.1 | |
end repeat | |
error "output file could not be found: " & filename | |
end wait_file_exists | |
on file_exists(filename) | |
tell application "System Events" | |
if exists file filename then | |
return true | |
else | |
return false | |
end if | |
end tell | |
end file_exists |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment