Written by: Rivaldi Last updated: 2025-07-24
Migrate all songs from Apple Music to Spotify without third-party tools like SongShift. Just Python and the Spotify API.
- Python 3.13 (use virtual environment)
- Spotipy (Spotify Web API library)
- Apple Music (manually exported playlists)
playlisttotxt.pyto parse Apple Music XMLmigrator.pyto transfer songs to Spotify
Run the following script to automatically set up the environment:
chmod +x initpyenv.sh
./initpyenv.shThis script will:
- Create a virtual environment
- Install dependencies:
spotipy,requests - Automatically activate the environment
-
Export Apple Music Playlist (Mac):
- Open
Music.app - Click playlist → File > Library > Export Playlist → choose XML
- Open
-
Run
playlisttotxt.py:python3 playlisttotxt.py path/to/exported_playlist.xml
Output:
playlist.txt -
Run
migrator.pyto transfer songs to Spotifypython3 migrator.py
The script will:
- Add songs to "Liked Songs"
- Skip songs that are already added
- Log failed songs in
gagal.txt - Log existing songs in
skipped.txt
To use this script, you must have access to the Spotify Developer Console to use their API.
Steps:
-
Log in with your Spotify account
-
Click Create App → enter name and description
-
Once created, you’ll get:
- Client ID
- Client Secret
migrator.py:
auth = SpotifyOAuth(
client_id="YOUR_CLIENT_ID",
client_secret="YOUR_CLIENT_SECRET",
redirect_uri="http://127.0.0.1:8888/callback",
scope="playlist-modify-public user-library-read user-library-modify"
)Without this, the script won’t be able to access your Spotify account.
Music-Migrator/
├── initpyenv.sh
├── playlisttotxt.py # parses XML to txt
├── migrator.py # reads playlist.txt and transfers the songs to Spotify
├── playlist.txt # output from playlisttotxt.py
├── gagal.txt # songs that failed to transfer
└── skipped.txt # songs already in your Spotify library
- Fuzzy search (matches based on similarity or typos)
- Auto-skip if song already exists
- Retry request on timeout
- Logging to txt files
- Auto-opens Spotify "Liked Songs" after migration
Issue:
403 Client Error: Forbidden for url: https://api.spotify.com/v1/me/tracks/contains
Solution: Ensure full scope is set:
scope="playlist-modify-public user-library-read user-library-modify"Then remove .cache* to re-login:
rm .cache*Issue:
Read timed out. (read timeout=5)
Solution:
- Set
requests_timeout=15 - Add
time.sleep(0.5)between requests - Retry song search up to 3 times if failed
Issue: Playlist seems empty even though it was processed successfully
Solution: Ensure migrator.py uses:
sp.current_user_saved_tracks_add([track_id])The script doesn't create a new playlist, it adds songs directly to "Liked Songs"
- Songs from Apple Music successfully added to "Liked Songs" in Spotify
- Failed songs →
gagal.txt - Skipped songs →
skipped.txt - Spotify "Liked Songs" opens automatically in browser
- Auto-parse XML without manual export
- GUI with drag-and-drop playlist
- Export logs to CSV
- Preview/dry-run mode before transfer
Since I'm the type of person who often switches between music streaming services and gets tired of transferring songs manually one by one, I finally created my own automation solution. The process is designed to be flexible and reusable anytime, with three main components:
initpyenv.shplaylisttotxt.pymigrator.py
