Last active
March 16, 2026 12:15
-
-
Save physhster/b7e7e0453796c27c4a429fe476b3afce to your computer and use it in GitHub Desktop.
Quick Apple Script to sort Apple Music Favorites based on an export from a different service
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
| tell application "Music" | |
| with timeout of 7200 seconds | |
| -- Detect which property to use | |
| set useProperty to missing value | |
| set testTrack to track 1 of playlist 1 | |
| try | |
| set favorited of testTrack to (favorited of testTrack) | |
| set useProperty to "favorited" | |
| end try | |
| if useProperty is missing value then | |
| try | |
| set loved of testTrack to (loved of testTrack) | |
| set useProperty to "loved" | |
| end try | |
| end if | |
| if useProperty is missing value then | |
| display dialog "Could not determine favourite property. Aborting." buttons {"OK"} default button 1 | |
| return | |
| end if | |
| display dialog "Using property: " & useProperty buttons {"OK"} default button 1 | |
| -- Find playlist | |
| set thePlaylist to missing value | |
| repeat with p in (get every playlist) | |
| if name of p is "Spotify Liked" then | |
| set thePlaylist to p | |
| exit repeat | |
| end if | |
| end repeat | |
| if thePlaylist is missing value then | |
| display dialog "Playlist 'Spotify Liked' not found!" buttons {"OK"} default button 1 | |
| return | |
| end if | |
| set trackIDs to (get database ID of every track of thePlaylist) | |
| set trackCount to count of trackIDs | |
| display dialog "Found " & trackCount & " tracks. Starting..." buttons {"OK"} default button 1 | |
| set successCount to 0 | |
| set failCount to 0 | |
| repeat with i from trackCount to 1 by -1 | |
| set aID to item i of trackIDs | |
| try | |
| set aTrack to (first track whose database ID is aID) | |
| if useProperty is "favorited" then | |
| set favorited of aTrack to true | |
| else | |
| set loved of aTrack to true | |
| end if | |
| set successCount to successCount + 1 | |
| on error | |
| set failCount to failCount + 1 | |
| end try | |
| if (i mod 50) is 0 then delay 1 | |
| end repeat | |
| display dialog "Done! Favourited: " & successCount & " | Failed: " & failCount buttons {"OK"} default button 1 | |
| end timeout | |
| end tell |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Why loved vs favorited matters
Apple Music exposes two different AppleScript properties for the same "heart/favourite" feature depending on your system region:
US English systems use loved (corresponding to the "Love" button in the UI)
UK, Australian, and other English systems use favorited (corresponding to the "Favourite" button)
Using the wrong property doesn't throw an obvious error — it either silently does nothing or returns a generic access error like Can't set «constant eClSkMat» to false. Access not allowed., which is extremely misleading as it implies a permissions issue rather than a naming mismatch. The same likely applies to non-English systems where the button has a different localised name entirely.
This script auto-detects which property works on your system before proceeding.
If the script fails:
Done! Favourited: 0 | Failed: X → The detection passed but tracks are still unwritable. Check that the tracks are actually in your Library (not just a shared/imported playlist). Cloud-only tracks that haven't been added to your library may be read-only.
"Could not determine favourite property" → Neither loved nor favorited works on your system. You may be on a non-English locale — open Script Editor, manually try set loved of track 1 of playlist 1 to true and set favorited of track 1 of playlist 1 to true to find which property name works, then hardcode it.
"Playlist 'Spotify Liked' not found" → The playlist name doesn't match exactly. Open Music, check the exact name and update the script accordingly.