Последняя активность 1740033278

anthony's Avatar anthony ревизий этого фрагмента 1740033278. К ревизии

1 file changed, 93 insertions

ytdlcue.sh(файл создан)

@@ -0,0 +1,93 @@
1 + #!/bin/bash
2 + # CUE-sheet generator for youtube-dl
3 +
4 + # Usage:
5 + # 0. Install 'jq' utility
6 + # 1. Download any audio file with metadata from YouTube or Youtube Music, e.g.
7 + # $ youtube-dl \
8 + # --extract-audio \
9 + # --audio-format flac \
10 + # --audio-quality 0 \
11 + # --format bestaudio \
12 + # --write-info-json \
13 + # --output "/tmp/ytm/%(playlist_title)s/%(channel)s - %(title)s.%(ext)s" \
14 + # https://www.youtube.com/watch?v=lVpDQnXz34M
15 + #
16 + # If audio file is already downloaded earlier then just fetch only its metadata:
17 + # $ youtube-dl \
18 + # --write-info-json \
19 + # --skip-download \
20 + # --output "/tmp/ytm/%(playlist_title)s/%(channel)s - %(title)s.%(ext)s" \
21 + # https://www.youtube.com/watch?v=lVpDQnXz34M
22 + #
23 + # 2. Audio and metadata files MUST be named exactly similar (except extenstion),
24 + # but it is not necessary to keep original names. Also they MUST be placed in
25 + # the same directory. Example:
26 + # /tmp/ytm/ABGT496.flac
27 + # /tmp/ytm/ABGT496.info.json
28 + #
29 + # 3. To create CUE file run ytdlcue with a path to audio file:
30 + # $ ytdlcue.sh /tmp/ytm/ABGT496.flac
31 + #
32 + # A new file will be created in the same directory:
33 + # /tmp/ytm/ABGT496.cue
34 +
35 + installed() {
36 + command -v "$1" >/dev/null 2>&1
37 + }
38 +
39 + ! installed 'jq' && {
40 + echo "ERROR: you need to install jq!"
41 + exit 1
42 + }
43 +
44 + audio_path="$1" # path to audiofile
45 + audio_file=`basename "$audio_path"` # audiofile name with extension
46 + audio_name=${audio_file%.*} # audiofile name without extension
47 + audio_ext=${audio_file##*.} # audiofile name extension
48 + path="`dirname "$audio_path"`/$audio_name" # path to audiofile and its name without ext
49 + json_path="$path.info.json" # path to json file with metadata created by youtube-dl
50 + cue_path="$path.cue" # path to cue sheet to be generated
51 +
52 + # echo -e "audio_path:\t$audio_path"
53 + # echo -e "audio_file:\t$audio_file"
54 + # echo -e "audio_name:\t$audio_name"
55 + # echo -e "audio_ext:\t$audio_ext"
56 + # echo -e "path:\t\t$path"
57 + # echo -e "json_path:\t$json_path"
58 + # echo -e "cue_path:\t$cue_path"
59 +
60 + [ ! -f "$audio_path" ] && {
61 + echo "ERROR: File not found: $audio_path"
62 + exit 2
63 + }
64 + [ ! -f "$json_path" ] && {
65 + echo "ERROR: File not found: $json_path"
66 + exit 3
67 + }
68 +
69 + echo "PERFORMER `cat "$json_path" | jq -Mc '.channel'`" > "$cue_path"
70 + echo "TITLE `cat "$json_path" | jq -Mc '.title'`" >> "$cue_path"
71 + echo "FILE \"$audio_file\" ${audio_ext^^}" >> "$cue_path"
72 +
73 + counter=1 # track counter (works only inside loop!)
74 + cat "$json_path" | jq -Mc '.chapters[]' \
75 + | while read chapter; do
76 + number=`printf %0.2d $counter` # pad current counter with zeros
77 + time=`echo "$chapter" | jq -Mc '.start_time'` # get initial start time in seconds
78 + time=`printf '%0.2d:%0.2d:00' $((time/60)) $((time%60))` # convert start time to minutes:seconds
79 + title=`echo "$chapter" | jq -Mc '.title' | sed -r "s#[\"]##g"` # get initial chapter title
80 + performer=`echo "$title" | cut -d "-" -f 1 | sed 's#^[[:space:]]*##g' | sed 's# *$##g'` # get and trim chapter's performer (before '-')
81 + title2=`echo "$title" | cut -d "-" -f 2 | sed 's#^[[:space:]]*##g' | sed 's# *$##g'` # get and trim chapter's title (after '-')
82 + #TODO: what if dash is not delimiter between performer and title?
83 + #TODO: take $title2 if $performer and (or?) $title2 are empty
84 +
85 + printf "%-2sTRACK $number AUDIO\n" >> "$cue_path"
86 + printf "%-4sPERFORMER \"$performer\"\n" >> "$cue_path"
87 + printf "%-4sTITLE \"$title2\"\n" >> "$cue_path"
88 + printf "%-4sINDEX 01 $time\n" >> "$cue_path"
89 +
90 + counter=`expr $counter + 1` # increase counter
91 + done
92 + echo "Done! Cue file:"
93 + echo "$cue_path"
Новее Позже