Vous possédez un iPhone ou un Mac, mais un téléphone Android ? Comme moi, vous avez peut-être toutes vos playlists soigneusement sélectionnées dans iTunes/Musique, mais vous avez du mal à les transférer sur votre appareil Android. Après des années à recréer manuellement vos playlists, j'ai enfin trouvé une solution : un script bash qui exporte et synchronise automatiquement vos playlists de macOS vers Android.
Remarque : Ce script supprime automatiquement tous les fichiers de votre dossier Musique lors de sa synchronisation. Tenez-en compte. Effectuez une sauvegarde avant de l'exécuter. Utilisez-le à vos risques et périls.
Ce que fait ce script
Ce script :
- Extrait les listes de lecture directement depuis l'application Musique de votre Mac (iTunes)
- Les exporte sous forme de fichiers de liste de lecture M3U standard
- Synchronise éventuellement les listes de lecture et les fichiers musicaux réels sur votre appareil Android
- Se souvient de vos préférences pour la prochaine fois
- Transfère uniquement les fichiers qui ne sont pas déjà sur votre appareil (pour gagner du temps)
Instructions d'installation
Clause de non-responsabilité: Ce script est particulièrement adapté aux développeurs et aux utilisateurs avertis qui maîtrisent les commandes du Terminal. Utilisez-le à vos risques et périls. Bien que le script ait été testé, je ne peux garantir son fonctionnement parfait avec toutes les configurations. Comme mentionné précédemment, il supprime toute la musique de votre téléphone Android.
Prérequis :
- Un Mac avec l'application Musique (anciennement iTunes)
- Un appareil Android
- Pont de débogage Android (ADB) installé
Étapes d'installation :
- Installer ADB si vous ne l'avez pas déjà. Le plus simple est d'utiliser Brassage maison:
brew installer android-platform-tools - Activer le débogage USB sur votre appareil Android :
- Accédez à Paramètres > À propos du téléphone
- Appuyez 7 fois sur « Numéro de build » pour activer les options du développeur
- Retournez dans Paramètres > Système > Options pour les développeurs
- Activer le « débogage USB »
- Créer le fichier de script:
- Ouvrir le terminal
- Créez un nouveau fichier à l'aide de votre éditeur de texte préféré (j'utiliserai nano) :
nano ~/music_playlist_sync.sh - Copiez et collez l'intégralité du script (le code en bas de ce blog)
- Enregistrer et quitter (dans nano, appuyez sur Ctrl+O, puis Entrée, puis Ctrl+X)
- Rendre le script exécutable:
chmod +x ~/music_playlist_sync.sh
Utilisation du script
Pour exécuter le script :
~/music_playlist_sync.shLa première fois que vous l'exécutez, le script va :
- Affichez toutes les listes de lecture disponibles depuis votre application Musique
- Demandez quelle(s) playlist(s) vous souhaitez exporter (vous pouvez en sélectionner plusieurs avec des numéros séparés par des virgules)
- Demandez où vous souhaitez enregistrer les listes de lecture exportées
- Demandez si vous souhaitez synchroniser avec un appareil Android
- Si oui, il recherchera les appareils connectés et aidera à localiser le dossier de musique
Toutes ces préférences sont enregistrées, donc la prochaine fois que vous exécuterez le script, il se souviendra de vos choix.
Conseils de dépannage
La musique ne s'affiche pas après la synchronisation
Parfois, Android ne reconnaît pas immédiatement les fichiers musicaux récemment ajoutés. Pour forcer une nouvelle analyse :
- Installer une application de réanalyse multimédia depuis Google Play Store, comme « Rescan Media » ou « SD Rescan »
- Exécutez l'application pour déclencher une nouvelle analyse de la bibliothèque multimédia
- Parfois, un redémarrage du téléphone fait l'affaire
Téléphones Samsung
Sur les appareils Samsung, vous devrez peut-être importer manuellement les listes de lecture :
- Ouvrez l'application Samsung Music
- Accédez à Paramètres > Listes de lecture > Importer des listes de lecture
- Vos nouvelles playlists devraient maintenant apparaître
Problèmes de connexion ADB
Si le script ne trouve pas votre appareil :
- Assurez-vous que le débogage USB est activé
- Essayez un autre câble USB (certains câbles ne prennent en charge que le chargement)
- Déverrouillez votre téléphone et acceptez toutes les invites de débogage USB
- Essayez de courir
appareils adbdans le Terminal pour vérifier si votre appareil est reconnu
Comment ça marche
Le script utilise AppleScript pour communiquer directement avec l'application Musique et extraire les informations des playlists. Il les convertit ensuite en playlists au format M3U standard, compatibles avec la plupart des lecteurs de musique. Si vous optez pour une synchronisation avec Android, il utilise ADB pour transférer les fichiers de playlist et les fichiers musicaux sur votre appareil.
Pour plus d'efficacité, il garde une trace des fichiers qui ont déjà été transférés et synchronise uniquement les fichiers nouveaux ou modifiés.
Limites
- Le script ne fonctionne que sur macOS avec l'application Musique
- Votre appareil Android doit être connecté via USB avec le débogage activé
- Il ne synchronise pas les métadonnées telles que le nombre de lectures ou les notes.
- La première synchronisation peut prendre beaucoup de temps si vous avez une grande bibliothèque musicale.
Réflexions finales
Ce script m'a épargné des heures de travail fastidieux pour recréer mes playlists sur Android. C'est une solution simple à un problème rencontré par de nombreuses personnes utilisant des écosystèmes mixtes Apple/Android. N'hésitez pas à le modifier pour l'adapter à vos besoins spécifiques ; le code est bien commenté pour faciliter la personnalisation.
Si vous en avez assez de maintenir des listes de lecture distinctes sur plusieurs appareils, essayez ce script et profitez de vos collections de musique soigneusement organisées sur votre appareil Android !
Le scénario
Appelez ça quelque chose comme musique_playlist_sync.sh
#!/bin/bash # Chemin du fichier de configuration dans le répertoire personnel CONFIG_FILE="$HOME/.music_playlist_export.conf" # Chemins de musique Android courants à essayer ANDROID_PATHS=( "/storage/emulated/0/Music" "/sdcard/Music" "/storage/sdcard0/Music" "/storage/sdcard1/Music" "/storage/self/primary/Music" ) # Fonction pour nettoyer les noms de fichiers sanitize_filename() { echo "$1" | sed 's/[^a-zA-Z0-9._-]/_/g' } # Vérifier si adb est installé if ! command -v adb &> /dev/null; then echo "Erreur : ADB n'est pas installé ou ne se trouve pas dans votre PATH" echo "Veuillez installer Android Debug Bridge (adb) pour utiliser la fonctionnalité de synchronisation" exit 1 fi # Vérifier la connexion de l'appareil check_device() { echo "Vérification des appareils Android connectés..." devices=$(adb devices | grep -v "List" | grep "device$") if [ -z "$devices" ]; then echo "Aucun appareil Android trouvé. Veuillez connecter votre appareil avec le débogage USB activé." exit 1 fi echo "Appareil connecté." } # Détection automatique du chemin de musique Android detect_android_music_path() { echo "Détection du chemin de musique Android..." for path in "${ANDROID_PATHS[@]}"; do exists=$(adb shell "[ -d \"$path\" ] && echo 'yes' || echo 'no'") if [ "$exists" = "yes" ]; then echo "Répertoire de musique trouvé : $path" ANDROID_MUSIC_PATH="$path" return 0 fi done echo "Impossible de détecter automatiquement le chemin de la musique. Utilisera la valeur par défaut." return 1 } # Obtenir des listes de lecture directement à l'aide d'AppleScript echo "Obtention des informations de la liste de lecture à partir de l'application Musique..." 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 # Obtenir la sélection de l'utilisateur avec prise en charge des valeurs séparées par des virgules if [ -n "$previous_selection" ]; then read -p "Entrez le(s) numéro(s) de playlist à exporter (séparés par des virgules pour plusieurs) [$previous_selection]: " selection_input selection_input="${selection_input:-$previous_selection}" else read -p "Entrez le(s) numéro(s) de playlist à exporter (séparés par des virgules pour plusieurs) : " selection_input fi # Répertoire d'exportation par défaut default_dir="${previous_dir:-$HOME/exported-playlists}" read -p "Entrez le répertoire d'exportation [$default_dir]: " user_dir export_dir="${user_dir:-$default_dir}" export_dir="${export_dir/#\~/$HOME}" # Demander des informations sur la synchronisation Android read -p "Synchroniser avec un appareil Android ? (y/n) : " android_sync if [[ "$android_sync" =~ ^[Yy]$ ]]; then check_device # Essayer de détecter le chemin de la musique Android ANDROID_MUSIC_PATH="${previous_android_path:-${ANDROID_PATHS[0]}}" detect_android_music_path read -p "Entrer le chemin de la musique Android [$ANDROID_MUSIC_PATH]: " android_path ANDROID_MUSIC_PATH="${android_path:-$ANDROID_MUSIC_PATH}" # Créer un répertoire de playlists sur l'appareil adb shell "mkdir -p \"$ANDROID_MUSIC_PATH/Playlists\"" fi # Enregistrer les sélections dans le fichier de configuration mkdir -p "$(dirname "$CONFIG_FILE")" echo "PLAYLIST_SELECTION=$selection_input" > "$CONFIG_FILE" echo "EXPORT_DIR=$export_dir" >> "$CONFIG_FILE" echo "LAST_RUN=$(date)" >> "$CONFIG_FILE" if [[ "$android_sync" =~ ^[Yy]$ ]]; then echo "ANDROID_MUSIC_PATH=$ANDROID_MUSIC_PATH" >> "$CONFIG_FILE" fi # Créer le répertoire s'il n'existe pas mkdir -p "$export_dir" # Tous les fichiers à synchroniser ALL_MUSIC_FILES="$export_dir/.all_music_files.txt" > "$ALL_MUSIC_FILES" # Traiter les sélections séparées par des virgules IFS=',' read -r -a selections <<< "$selection_input" for selection in "${selections[@]}"; do # Supprimer les espaces selection=$(echo "$selection" | xargs) if [[ "$selection" =~ ^[0-9]+$ ]]; alors index=$((selection-1)) si [ "$index" -ge 0 ] && [ "$index" -lt "${#playlist_array[@]}" ]; alors selected_playlist="${playlist_array[$index]}" # Ignorer les noms de playlist vides si [ -z "$selected_playlist" ]; puis echo "Ignorer la playlist vide à l'index $selection" continue fi safe_name=$(sanitize_filename "$selected_playlist") output_path="$export_dir/${safe_name}.m3u" echo "Exportation de la playlist : $selected_playlist" # Créer un fichier temporaire pour les chemins de piste playlist_tracks="$export_dir/.playlist_tracks_${safe_name}.txt" # Obtenir les pistes directement depuis l'application Musique 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" # Compter les pistes et afficher les informations de débogage track_count=$(grep -v "^$" "$playlist_tracks" | wc -l | tr -d ' ') echo "Débogage : $track_count pistes trouvées dans la playlist" echo "Débogage : Premières pistes :" head -n 3 "$playlist_tracks" # Créer le fichier M3U echo "#EXTM3U" > "$output_path" cat "$playlist_tracks" >> "$output_path" echo "Succès : $track_count pistes exportées vers $output_path" # Ajouter à la liste des fichiers à synchroniser cat "$playlist_tracks" >> "$ALL_MUSIC_FILES" # Créer une version Android si nécessaire 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" # Traiter chaque chemin de piste avec une meilleure gestion des erreurs 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 : Piste ajoutée à la playlist Android : $filename" else echo "Debug : Fichier de piste introuvable : $track_path" fi fi done < "$playlist_tracks" # Vérifier si la playlist Android a du contenu android_count=$(grep -v "^#" "$android_m3u" | grep -v "^$" | wc -l | tr -d ' ') if [ "$android_count" -gt 0 ]; then echo "Envoi de la playlist Android avec $android_count pistes..." adb push "$android_m3u" "$android_playlist" echo "Playlist Android créée avec succès" else echo "Aucune piste valide pour la playlist Android" fi fi else echo "Sélection non valide : $selection (hors limites)" fi else echo "Sélection non valide : $selection (pas un nombre)" fi done # Synchroniser les pistes si demandé if [[ "$android_sync" =~ ^[Yy]$ ]]; then echo "Synchronisation des fichiers musicaux sur l'appareil Android..." # Créer un répertoire musical sur l'appareil adb shell "mkdir -p \"$ANDROID_MUSIC_PATH\"" # Obtenir des pistes uniques et s'assurer qu'elles existent sort "$ALL_MUSIC_FILES" | uniq > "$ALL_MUSIC_FILES.unique" > "$ALL_MUSIC_FILES.valid" # Remplir la liste des fichiers valides echo "Vérification des fichiers musicaux valides..." while IFS= read -r track_path; do if [ -n "$track_path" ] && [ -f "$track_path" ]; then echo "$track_path" >> "$ALL_MUSIC_FILES.valid" fi done < "$ALL_MUSIC_FILES.unique" # Compter le nombre total de pistes total_tracks=$(grep -v "^$" "$ALL_MUSIC_FILES.valid" | wc -l | tr -d ' ') echo "$total_tracks pistes valides trouvées sur $(wc -l < "$ALL_MUSIC_FILES.unique" | tr -d ' ') pistes uniques" if [ "$total_tracks" -eq 0 ]; then echo "Aucune piste valide à synchroniser." else echo "$total_tracks pistes valides trouvées à synchroniser" echo "Débogage : 3 premières pistes à synchroniser :" head -n 3 "$ALL_MUSIC_FILES.valid" echo "Démarrage de la synchronisation de $total_tracks fichiers..." current=0 # Traiter chaque piste en utilisant une approche différente # Enregistrer d'abord les chemins des pistes dans un tableau track_paths=() while IFS= read -r line; do track_paths+=("$line") done < "$ALL_MUSIC_FILES.valid" echo "Débogage : ${#track_paths[@]} pistes chargées en mémoire" # Traitez maintenant chaque piste du tableau pour track_path dans "${track_paths[@]}"; do if [ -n "$track_path" ]; then current=$((current + 1)) filename=$(basename "$track_path") echo "[$current/$total_tracks] Synchronisation : $filename" # Vérification plus approfondie si le fichier existe sur l'appareil 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 " Taille locale : $local_size octets" echo " Taille distante : $file_exists octets" if [ "$file_exists" != "0" ]; then if [ "$file_exists" -eq "$local_size" ]; then echo " La taille du fichier correspond, saut..." else echo " La taille du fichier ne correspond pas, resynchronisation..." adb push "$track_path" "$ANDROID_MUSIC_PATH/$filename" fi else echo " Fichier introuvable sur l'appareil, transfert..." if ! adb push "$track_path" "$ANDROID_MUSIC_PATH/$filename"; then echo " Erreur lors du transfert du fichier, poursuite avec le suivant..." continue fi fi Sortie de débogage # if [ "$current" -eq 1 ]; then echo " Premier fichier traité, poursuite..." elif [ "$current" -eq 2 ]; then echo "Traitement du deuxième fichier, suite..." elif [ "$current" -eq 3 ]; then echo "Traitement du troisième fichier, suite..." elif [ "$current" -eq 4 ]; then echo "Traitement du quatrième fichier, suite..." elif [ "$current" -eq 5 ]; then echo "Traitement du cinquième fichier, suite..." fi fi done fi # Nettoyer les fichiers temporaires rm -f "$ALL_MUSIC_FILES" "$ALL_MUSIC_FILES.unique" "$ALL_MUSIC_FILES.valid" fi echo "Toutes les exportations vers $export_dir sont terminées" echo "Vos sélections ont été enregistrées. Exécutez à nouveau ce script pour utiliser les mêmes paramètres."Dernière mise à jour le 28 mars 2025


