-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexport_music_playlists.sh
More file actions
executable file
·168 lines (147 loc) · 5.14 KB
/
Copy pathexport_music_playlists.sh
File metadata and controls
executable file
·168 lines (147 loc) · 5.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#!/bin/bash
# export_music_playlists.sh — Export user playlists from Apple Music as M3U or TXT
#
# Usage:
# ./export_music_playlists.sh [-txt] [output_dir]
#
# Options:
# -txt Export as plain text instead of M3U (default: M3U)
# output_dir Directory for exported files (default: current directory)
#
# Examples:
# ./export_music_playlists.sh # M3U in current dir
# ./export_music_playlists.sh ~/Music/Exports # M3U in ~/Music/Exports
# ./export_music_playlists.sh -txt # TXT in current dir
# ./export_music_playlists.sh -txt ~/Playlists # TXT in ~/Playlists
set -euo pipefail
if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
sed -n '2,/^$/s/^# \?//p' "$0"
exit 0
fi
FORMAT="m3u"
OUTPUT_DIR="."
for arg in "$@"; do
if [[ "$arg" == "-txt" ]]; then
FORMAT="txt"
else
OUTPUT_DIR="$arg"
fi
done
mkdir -p "$OUTPUT_DIR"
echo "Fetching playlist names from Music app..."
playlist_data=$(osascript <<'APPLESCRIPT'
tell application "Music"
set output to ""
repeat with p in (every user playlist)
try
if (class of p is not folder playlist) then
set output to output & (name of p) & (ASCII character 10)
end if
end try
end repeat
return output
end tell
APPLESCRIPT
)
if [ -z "$playlist_data" ]; then
echo "No user playlists found."
exit 0
fi
count=0
while IFS= read -r name; do
[ -z "$name" ] && continue
count=$((count + 1))
done <<< "$playlist_data"
echo "Found $count playlist(s). Exporting as ${FORMAT}..."
echo ""
exported=0
while IFS= read -r playlist_name; do
[ -z "$playlist_name" ] && continue
safe_name=$(echo "$playlist_name" | tr '/:' '__')
if [ "$FORMAT" = "m3u" ]; then
outfile="$OUTPUT_DIR/${safe_name}.m3u"
osascript - "$playlist_name" <<'APPLESCRIPT' > "$outfile"
on run argv
set playlistName to item 1 of argv
tell application "Music"
set output to "#EXTM3U" & (ASCII character 10)
try
set p to user playlist playlistName
repeat with t in (every track of p)
try
set tName to name of t
set tArtist to ""
try
set tArtist to artist of t
end try
set durInt to 0
try
set durInt to round (duration of t) rounding down
end try
set output to output & "#EXTINF:" & durInt & "," & tArtist & " - " & tName & (ASCII character 10)
try
set tLoc to POSIX path of (location of t as alias)
set output to output & tLoc & (ASCII character 10)
on error
set output to output & "# No local file" & (ASCII character 10)
end try
end try
end repeat
end try
return output
end tell
end run
APPLESCRIPT
else
outfile="$OUTPUT_DIR/${safe_name}.txt"
osascript - "$playlist_name" <<'APPLESCRIPT' > "$outfile"
on run argv
set playlistName to item 1 of argv
tell application "Music"
set output to "Playlist: " & playlistName & (ASCII character 10) & (ASCII character 10)
try
set p to user playlist playlistName
set idx to 0
repeat with t in (every track of p)
set idx to idx + 1
try
set tName to name of t
set tArtist to ""
set tAlbum to ""
try
set tArtist to artist of t
end try
try
set tAlbum to album of t
end try
set durStr to "0:00"
try
set tDur to duration of t
set mins to (round (tDur / 60) rounding down)
set secs to (round (tDur mod 60) rounding down)
if secs < 10 then
set secStr to "0" & secs
else
set secStr to secs as text
end if
set durStr to mins & ":" & secStr
end try
set line_ to idx & ". " & tArtist & " - " & tName
if tAlbum is not "" then
set line_ to line_ & " (" & tAlbum & ")"
end if
set line_ to line_ & " [" & durStr & "]"
set output to output & line_ & (ASCII character 10)
end try
end repeat
end try
return output
end tell
end run
APPLESCRIPT
fi
exported=$((exported + 1))
echo " [$exported/$count] $playlist_name -> $(basename "$outfile")"
done <<< "$playlist_data"
echo ""
echo "Done. Exported $exported playlist(s) to: $OUTPUT_DIR"