Hai un iPhone o un Mac ma un telefono Android? Se sei come me, potresti avere tutte le tue playlist attentamente curate in iTunes/Musica, ma avere difficoltà a trasferirle sul tuo dispositivo Android. Dopo anni di ricreazione manuale delle playlist, ho finalmente creato una soluzione: uno script bash che esporta e sincronizza automaticamente le tue playlist da macOS ad Android.
Nota: questo script elimina tutti i file nella tua cartella Musica per impostazione predefinita, poiché sincronizza la cartella Musica. Tienilo a mente. Quindi fai un backup prima di eseguirlo. Usalo a tuo rischio e pericolo.
Cosa fa questo script
Questo script:
- Estrae le playlist direttamente dall'app Musica del tuo Mac (iTunes)
- Esportali come file di playlist M3U standard
- Facoltativamente sincronizza sia le playlist che i file musicali effettivi sul tuo dispositivo Android
- Ricorda le tue preferenze per la prossima volta
- Trasferisce solo i file che non sono già presenti sul tuo dispositivo (per risparmiare tempo)
Istruzioni per l'installazione
Disclaimer: Questo script è più adatto a sviluppatori o utenti esperti di tecnologia che hanno dimestichezza con i comandi del Terminale. Usalo a tuo rischio e pericolo. Sebbene lo script sia stato testato, non posso garantire che funzionerà perfettamente con tutte le configurazioni. Come detto sopra, elimina tutta la tua musica sul tuo telefono Android.
Prerequisiti:
- Un Mac con l'app Musica (in precedenza iTunes)
- Un dispositivo Android
- Ponte di debug Android (ADB) installato
Fasi di installazione:
- Installa ADB se non ce l'hai già. Il modo più semplice è usare Birra fatta in casa:
brew installa android-platform-tools - Abilita il debug USB sul tuo dispositivo Android:
- Vai su Impostazioni > Informazioni sul telefono
- Tocca “Numero build” 7 volte per abilitare le Opzioni sviluppatore
- Torna a Impostazioni > Sistema > Opzioni sviluppatore
- Abilita “Debug USB”
- Creare il file script:
- Apri terminale
- Crea un nuovo file utilizzando il tuo editor di testo preferito (io userò nano):
nano ~/music_playlist_sync.sh - Copia e incolla l'intero script (il codice in fondo a questo blog)
- Salva ed esci (in nano, premi Ctrl+O, poi Invio, poi Ctrl+X)
- Rendere lo script eseguibile:
chmod +x ~/music_playlist_sync.sh
Utilizzo dello script
Per eseguire lo script:
~/music_playlist_sync.shLa prima volta che lo esegui, lo script:
- Visualizza tutte le playlist disponibili dalla tua app Musica
- Chiedi quali playlist vuoi esportare (puoi selezionarne più di una con numeri separati da virgole)
- Chiedi dove vuoi salvare le playlist esportate
- Chiedi se vuoi sincronizzare con un dispositivo Android
- In caso affermativo, cercherà i dispositivi connessi e aiuterà a individuare la cartella musicale
Tutte queste preferenze vengono salvate, quindi la prossima volta che eseguirai lo script, le tue scelte saranno memorizzate.
Suggerimenti per la risoluzione dei problemi
La musica non viene visualizzata dopo la sincronizzazione
A volte Android non riconosce immediatamente i file musicali appena aggiunti. Per forzare una nuova scansione dei media:
- Installa un'app per la riscansione dei contenuti multimediali da Google Play Store, come "Rescan Media" o "SD Rescan"
- Esegui l'app per attivare una nuova scansione della libreria multimediale
- A volte riavviare il telefono risolve il problema
Telefoni Samsung
Sui dispositivi Samsung potrebbe essere necessario importare manualmente le playlist:
- Apri l'app Samsung Music
- Vai su Impostazioni > Playlist > Importa playlist
- Ora dovrebbero apparire le tue nuove playlist
Problemi di connessione ADB
Se lo script non riesce a trovare il tuo dispositivo:
- Assicurati che il debug USB sia abilitato
- Prova un cavo USB diverso (alcuni cavi supportano solo la ricarica)
- Sblocca il telefono e accetta tutte le richieste di debug USB
- Prova a correre
dispositivi adbnel Terminale per verificare se il tuo dispositivo è riconosciuto
Come funziona
Lo script usa AppleScript per comunicare direttamente con l'app Musica ed estrarre le informazioni della playlist. Quindi le converte in playlist in formato M3U standard che possono essere lette dalla maggior parte dei lettori musicali. Se scegli di sincronizzare con Android, usa ADB per trasferire sia i file della playlist che i file musicali veri e propri sul tuo dispositivo.
Per motivi di efficienza, tiene traccia dei file già trasferiti e sincronizza solo i file nuovi o modificati.
Limitazioni
- Lo script funziona solo su macOS con l'app Musica
- Il tuo dispositivo Android deve essere connesso tramite USB con il debug abilitato
- Non sincronizza i metadati come i conteggi delle riproduzioni o le valutazioni
- Potrebbe volerci molto tempo per la prima sincronizzazione se si dispone di una libreria musicale di grandi dimensioni
Considerazioni finali
Questo script mi ha risparmiato ore di noioso lavoro nel ricreare le mie playlist su Android. È una soluzione semplice a un problema che molte persone con ecosistemi misti Apple/Android affrontano. Sentiti libero di modificarlo per adattarlo alle tue esigenze specifiche: il codice è ben commentato per rendere più semplice la personalizzazione.
Se sei stanco di dover gestire playlist separate sui vari dispositivi, prova questo script e goditi le tue raccolte musicali attentamente selezionate sul tuo dispositivo Android!
La sceneggiatura
Chiamalo qualcosa del genere sincronizzazione_playlist_musicale.sh
#!/bin/bash # Percorso del file di configurazione nella directory home CONFIG_FILE="$HOME/.music_playlist_export.conf" # Percorsi musicali Android comuni da provare ANDROID_PATHS=( "/storage/emulated/0/Music" "/sdcard/Music" "/storage/sdcard0/Music" "/storage/sdcard1/Music" "/storage/self/primary/Music" ) # Funzione per sanificare i nomi dei file sanitize_filename() { echo "$1" | sed 's/[^a-zA-Z0-9._-]/_/g' } # Controlla se adb è installato if ! command -v adb &> /dev/null; then echo "Errore: ADB non è installato o non è nel tuo PATH" echo "Si prega di installare Android Debug Bridge (adb) per utilizzare la funzionalità di sincronizzazione" exit 1 fi # Controlla la connessione del dispositivo check_device() { echo "Controllo dei dispositivi Android connessi..." devices=$(adb devices | grep -v "List" | grep "device$") if [ -z "$devices" ]; then echo "Nessun dispositivo Android trovato. Si prega di collegare il dispositivo con il debug USB abilitato." exit 1 fi echo "Dispositivo connesso." } # Rilevamento automatico del percorso musicale Android detect_android_music_path() { echo "Rilevamento del percorso musicale Android..." for path in "${ANDROID_PATHS[@]}"; do exist=$(adb shell "[ -d \"$path\" ] && echo 'yes' || echo 'no'") if [ "$exists" = "yes" ]; then echo "Directory musicale trovata: $path" ANDROID_MUSIC_PATH="$path" return 0 fi done echo "Impossibile rilevare automaticamente il percorso musicale. Verrà utilizzato il valore predefinito." return 1 } # Ottieni le playlist direttamente tramite AppleScript echo "Ottenimento delle informazioni sulla playlist dall'app Musica..." playlist_output=$(osascript < <EOF
tell application "Music"
set output to ""
set playlists_list to user playlists
repeat with i from 1 to count of playlists_list
set pl to item i of playlists_list
set pl_name to name of pl
set output to output & pl_name & "|"
end repeat
return output
end tell
EOF
)
# Convert to array (macOS compatible)
IFS='|' read -r -a playlist_array <<< "$playlist_output"
# Check if we got any playlists
if [ ${#playlist_array[@]} -eq 0 ]; then
echo "Error: No playlists found in Music app. Try using 'all playlists' instead of 'user playlists'."
# Try again with all playlists
echo "Trying with all playlists instead..."
playlist_output=$(osascript <<EOF
tell application "Music"
set output to ""
set playlists_list to playlists
repeat with i from 1 to count of playlists_list
set pl to item i of playlists_list
set pl_name to name of pl
set output to output & pl_name & "|"
end repeat
return output
end tell
EOF
)
# Convert to array (macOS compatible)
IFS='|' read -r -a playlist_array << /dev/null) previous_dir=$(grep "^EXPORT_DIR=" "$CONFIG_FILE" | cut -d= -f2 2>/dev/null) previous_android_path=$(grep "^ANDROID_MUSIC_PATH=" "$CONFIG_FILE" | cut -d= -f2 2>/dev/null) fi # Ottieni la selezione utente con supporto per valori separati da virgole if [ -n "$previous_selection" ]; quindi leggi -p "Inserisci il/i numero/i della playlist da esportare (separati da virgole per più di una) [$previous_selection]: " selection_input selection_input="${selection_input:-$previous_selection}" altrimenti leggi -p "Inserisci il/i numero/i della playlist da esportare (separati da virgole per più di una): " selection_input fi # Directory di esportazione predefinita default_dir="${previous_dir:-$HOME/exported-playlists}" leggi -p "Inserisci la directory di esportazione [$default_dir]: " user_dir export_dir="${user_dir:-$default_dir}" export_dir="${export_dir/#\~/$HOME}" # Chiedi informazioni sulla sincronizzazione Android leggi -p "Sincronizzazione con dispositivo Android? (y/n): " android_sync se [[ "$android_sync" =~ ^[Yy]$ ]]; quindi check_device # Prova a rilevare il percorso musicale Android ANDROID_MUSIC_PATH="${previous_android_path:-${ANDROID_PATHS[0]}}" detect_android_music_path read -p "Inserisci il percorso musicale Android [$ANDROID_MUSIC_PATH]: " android_path ANDROID_MUSIC_PATH="${android_path:-$ANDROID_MUSIC_PATH}" # Crea la directory delle playlist sul dispositivo adb shell "mkdir -p \"$ANDROID_MUSIC_PATH/Playlists\"" fi # Salva le selezioni nel file di configurazione mkdir -p "$(dirname "$CONFIG_FILE")" echo "PLAYLIST_SELECTION=$selection_input" > "$CONFIG_FILE" echo "EXPORT_DIR=$export_dir" >> "$CONFIG_FILE" echo "LAST_RUN=$(data)" >> "$CONFIG_FILE" if [[ "$android_sync" =~ ^[Yy]$ ]]; quindi echo "ANDROID_MUSIC_PATH=$ANDROID_MUSIC_PATH" >> "$CONFIG_FILE" fi # Crea la directory se non esiste mkdir -p "$export_dir" # Tutti i file da sincronizzare ALL_MUSIC_FILES="$export_dir/.all_music_files.txt" > "$ALL_MUSIC_FILES" # Elabora selezioni separate da virgole IFS=',' read -r -a selections <<< "$selection_input" per la selezione in "${selections[@]}"; do # Rimuovi tutti gli spazi selection=$(echo "$selection" | xargs) if [[ "$selection" =~ ^[0-9]+$ ]]; quindi indice=$((selezione-1)) if [ "$index" -ge 0 ] && [ "$index" -lt "${#playlist_array[@]}" ]; then selected_playlist="${playlist_array[$index]}" # Salta i nomi delle playlist vuote if [ -z "$selected_playlist" ]; quindi echo "Salta playlist vuota all'indice $selection" continua fi safe_name=$(sanitize_filename "$selected_playlist") output_path="$export_dir/${safe_name}.m3u" echo "Esportazione playlist: $selected_playlist" # Crea un file temporaneo per i percorsi delle tracce playlist_tracks="$export_dir/.playlist_tracks_${safe_name}.txt" # Ottieni le tracce direttamente dall'app Musica osascript > "$playlist_tracks" < <EOF
tell application "Music"
set thePlaylist to (first playlist whose name is "$selected_playlist")
set theOutput to ""
repeat with aTrack in tracks of thePlaylist
try
if class of aTrack is file track then
set trackLoc to location of aTrack
if trackLoc is not missing value then
set trackPath to POSIX path of trackLoc
set theOutput to theOutput & trackPath & linefeed
log "Found track: " & trackPath
end if
end if
on error errMsg
log "Error processing track: " & errMsg
end try
end repeat
return theOutput
end tell
EOF
# Clean up the output file to ensure proper line breaks
tr -d '\r' "$playlist_tracks.tmp" && mv "$playlist_tracks.tmp" "$playlist_tracks" # Conta le tracce e mostra le informazioni di debug track_count=$(grep -v "^$" "$playlist_tracks" | wc -l | tr -d ' ') echo "Debug: trovate $track_count tracce nella playlist" echo "Debug: prime tracce:" head -n 3 "$playlist_tracks" # Crea il file M3U echo "#EXTM3U" > "$output_path" cat "$playlist_tracks" >> "$output_path" echo "Successo: esportate $track_count tracce in $output_path" # Aggiungi all'elenco dei file da sincronizzare cat "$playlist_tracks" >> "$ALL_MUSIC_FILES" # Crea la versione Android se necessario if [[ "$android_sync" =~ ^[Yy]$ ]] && [ "$track_count" -gt 0 ]; then android_playlist="$ANDROID_MUSIC_PATH/Playlists/${safe_name}.m3u" android_m3u="$export_dir/android_${safe_name}.m3u" echo "#EXTM3U" > "$android_m3u" # Elabora ogni percorso traccia con una migliore gestione degli errori while IFS= read -r track_path; do if [ -n "$track_path" ]; then if [ -f "$track_path" ]; then filename=$(basename "$track_path") echo "$ANDROID_MUSIC_PATH/$filename" >> "$android_m3u" echo "Debug: aggiunta traccia alla playlist Android: $filename" else echo "Debug: file traccia non trovato: $track_path" fi fi done < "$playlist_tracks" # Controlla se la playlist Android ha contenuti android_count=$(grep -v "^#" "$android_m3u" | grep -v "^$" | wc -l | tr -d ' ') if [ "$android_count" -gt 0 ]; quindi echo "Invio playlist Android con $android_count tracce..." adb push "$android_m3u" "$android_playlist" echo "Playlist Android creata correttamente" else echo "Nessuna traccia valida per la playlist Android" fi fi else echo "Selezione non valida: $selection (fuori intervallo)" fi else echo "Selezione non valida: $selection (non un numero)" fi done # Sincronizza le tracce se richiesto if [[ "$android_sync" =~ ^[Yy]$ ]]; quindi echo "Sincronizzazione dei file musicali sul dispositivo Android..." # Crea directory musicale sul dispositivo adb shell "mkdir -p \"$ANDROID_MUSIC_PATH\"" # Ottieni tracce univoche e assicurati che esistano sort "$ALL_MUSIC_FILES" | uniq > "$ALL_MUSIC_FILES.unique" > "$ALL_MUSIC_FILES.valid" # Popola l'elenco dei file validi echo "Controllo dei file musicali validi..." while IFS= read -r track_path; do if [ -n "$track_path" ] && [ -f "$track_path" ]; quindi echo "$track_path" >> "$ALL_MUSIC_FILES.valid" fi done < "$ALL_MUSIC_FILES.unique" # Conta le tracce totali total_tracks=$(grep -v "^$" "$ALL_MUSIC_FILES.valid" | wc -l | tr -d ' ') echo "Trovate $total_tracks tracce valide su $(wc -l < "$ALL_MUSIC_FILES.unique" | tr -d ' ') tracce uniche" if [ "$total_tracks" -eq 0 ]; quindi echo "Nessuna traccia valida da sincronizzare." else echo "Trovate $total_tracks tracce valide da sincronizzare" echo "Debug: Prime 3 tracce da sincronizzare:" head -n 3 "$ALL_MUSIC_FILES.valid" echo "Avvio della sincronizzazione dei file $total_tracks..." current=0 # Elabora ogni traccia utilizzando un approccio diverso # Salva prima i percorsi delle tracce in un array track_paths=() while IFS= read -r line; do track_paths+=("$line") done < "$ALL_MUSIC_FILES.valid" echo "Debug: Caricate ${#track_paths[@]} tracce in memoria" # Ora elabora ogni traccia nell'array per track_path in "${track_paths[@]}"; do if [ -n "$track_path" ]; then current=$((current + 1)) filename=$(basename "$track_path") echo "[$current/$total_tracks] Sincronizzazione: $filename" # Controllo più approfondito per verificare se il file esiste sul dispositivo file_exists=$(adb shell "if [ -f \"$ANDROID_MUSIC_PATH/$filename\" ]; then ls -l \"$ANDROID_MUSIC_PATH/$filename\" | awk '{print \$5}'; else echo '0'; fi") local_size=$(stat -f%z "$track_path") echo " Dimensione locale: $local_size byte" echo " Dimensione remota: $file_exists byte" if [ "$file_exists" != "0" ]; then if [ "$file_exists" -eq "$local_size" ]; then echo " La dimensione del file corrisponde, salta..." else echo " La dimensione del file non corrisponde, risincronizzazione..." adb push "$track_path" "$ANDROID_MUSIC_PATH/$filename" fi else echo " Il file non è stato trovato sul dispositivo, trasferimento in corso..." if ! adb push "$track_path" "$ANDROID_MUSIC_PATH/$filename"; then echo " Errore durante il trasferimento del file, si continua con il successivo..." continue fi fi Output di debug # if [ "$current" -eq 1 ]; then echo " Elaborato il primo file, si continua..." elif [ "$current" -eq 2 ]; then echo "Elaborato secondo file, continua..." elif [ "$current" -eq 3 ]; then echo "Elaborato terzo file, continua..." elif [ "$current" -eq 4 ]; then echo "Elaborato quarto file, continua..." elif [ "$current" -eq 5 ]; then echo "Elaborato quinto file, continua..." fi fi done fi # Pulisci i file temporanei rm -f "$ALL_MUSIC_FILES" "$ALL_MUSIC_FILES.unique" "$ALL_MUSIC_FILES.valid" fi echo "Tutte le esportazioni completate in $export_dir" echo "Le tue selezioni sono state salvate. Esegui di nuovo questo script per utilizzare le stesse impostazioni."Ultimo aggiornamento il 28 marzo 2025


