ytdlcue.sh
· 3.5 KiB · Bash
Eredeti
#!/bin/bash
# CUE-sheet generator for youtube-dl
# Usage:
# 0. Install 'jq' utility
# 1. Download any audio file with metadata from YouTube or Youtube Music, e.g.
# $ youtube-dl \
# --extract-audio \
# --audio-format flac \
# --audio-quality 0 \
# --format bestaudio \
# --write-info-json \
# --output "/tmp/ytm/%(playlist_title)s/%(channel)s - %(title)s.%(ext)s" \
# https://www.youtube.com/watch?v=lVpDQnXz34M
#
# If audio file is already downloaded earlier then just fetch only its metadata:
# $ youtube-dl \
# --write-info-json \
# --skip-download \
# --output "/tmp/ytm/%(playlist_title)s/%(channel)s - %(title)s.%(ext)s" \
# https://www.youtube.com/watch?v=lVpDQnXz34M
#
# 2. Audio and metadata files MUST be named exactly similar (except extenstion),
# but it is not necessary to keep original names. Also they MUST be placed in
# the same directory. Example:
# /tmp/ytm/ABGT496.flac
# /tmp/ytm/ABGT496.info.json
#
# 3. To create CUE file run ytdlcue with a path to audio file:
# $ ytdlcue.sh /tmp/ytm/ABGT496.flac
#
# A new file will be created in the same directory:
# /tmp/ytm/ABGT496.cue
installed() {
command -v "$1" >/dev/null 2>&1
}
! installed 'jq' && {
echo "ERROR: you need to install jq!"
exit 1
}
audio_path="$1" # path to audiofile
audio_file=`basename "$audio_path"` # audiofile name with extension
audio_name=${audio_file%.*} # audiofile name without extension
audio_ext=${audio_file##*.} # audiofile name extension
path="`dirname "$audio_path"`/$audio_name" # path to audiofile and its name without ext
json_path="$path.info.json" # path to json file with metadata created by youtube-dl
cue_path="$path.cue" # path to cue sheet to be generated
# echo -e "audio_path:\t$audio_path"
# echo -e "audio_file:\t$audio_file"
# echo -e "audio_name:\t$audio_name"
# echo -e "audio_ext:\t$audio_ext"
# echo -e "path:\t\t$path"
# echo -e "json_path:\t$json_path"
# echo -e "cue_path:\t$cue_path"
[ ! -f "$audio_path" ] && {
echo "ERROR: File not found: $audio_path"
exit 2
}
[ ! -f "$json_path" ] && {
echo "ERROR: File not found: $json_path"
exit 3
}
echo "PERFORMER `cat "$json_path" | jq -Mc '.channel'`" > "$cue_path"
echo "TITLE `cat "$json_path" | jq -Mc '.title'`" >> "$cue_path"
echo "FILE \"$audio_file\" ${audio_ext^^}" >> "$cue_path"
counter=1 # track counter (works only inside loop!)
cat "$json_path" | jq -Mc '.chapters[]' \
| while read chapter; do
number=`printf %0.2d $counter` # pad current counter with zeros
time=`echo "$chapter" | jq -Mc '.start_time'` # get initial start time in seconds
time=`printf '%0.2d:%0.2d:00' $((time/60)) $((time%60))` # convert start time to minutes:seconds
title=`echo "$chapter" | jq -Mc '.title' | sed -r "s#[\"]##g"` # get initial chapter title
performer=`echo "$title" | cut -d "-" -f 1 | sed 's#^[[:space:]]*##g' | sed 's# *$##g'` # get and trim chapter's performer (before '-')
title2=`echo "$title" | cut -d "-" -f 2 | sed 's#^[[:space:]]*##g' | sed 's# *$##g'` # get and trim chapter's title (after '-')
#TODO: what if dash is not delimiter between performer and title?
#TODO: take $title2 if $performer and (or?) $title2 are empty
printf "%-2sTRACK $number AUDIO\n" >> "$cue_path"
printf "%-4sPERFORMER \"$performer\"\n" >> "$cue_path"
printf "%-4sTITLE \"$title2\"\n" >> "$cue_path"
printf "%-4sINDEX 01 $time\n" >> "$cue_path"
counter=`expr $counter + 1` # increase counter
done
echo "Done! Cue file:"
echo "$cue_path"
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" |
94 |