-
Notifications
You must be signed in to change notification settings - Fork 0
/
dl
executable file
·175 lines (158 loc) · 13.6 KB
/
dl
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
169
170
171
172
173
174
175
#!/bin/bash
source /home/fabian/d/programs/bash_scripts/sane
wl_id=$(cat /home/fabian/d/programs/bash_scripts/wl_id.txt)
tm_id=$(cat /home/fabian/d/programs/bash_scripts/tm_id.txt)
yt_pw=$(cat /home/fabian/d/programs/bash_scripts/yt_pw.txt)
if [[ "$1" =~ ^(\-\-?|\/)?(h(elp)?|\?)$ && "$2" == "" ]]; then
wrap "WARNING: This script is currently getting refactored. This help text is ahead of development."
wrap "Downloads something using youtube-dlp."
echo "Usage:"
tablewrap "dl [-[-]|/](h[elp]|?)" "Shows this help. Example: dl --help"\
"dl [m|M|n|N|r|R|\e[3mINDEX\e[0m]…" "Downloads WL into Downloads or, with \"m\", temp_music into t."\
"dl [f|F|m|M|n|N|r|R]… (\e[3mFILE\e[0m|\e[3mURL\e[0m [f|F|m|M|n|N|r|R|\e[3mINDEX\e[0m]…)…" "Downloads all \e[3mURL\e[0ms listed as arguments or in \e[3mFILE\e[0ms with yt-dlp."
echo
wrap "Context-specific options:"
wrap "f: Create subfolders and download into them. Never set by default."
wrap "F: Do not create subfolders. Always set by default, so only useful to overwrite e.g. Bash aliases that specify \"f\"."
wrap "n: Number entries. Set by default for playlist URLs."
wrap "N: Do not number entries. Set by default for files and video/track URLs."
wrap "One number can be specified as a starting \e[3mINDEX\e[0m, a second one as an ending \e[3mINDEX\e[0m. Those indices are line numbers, if the entry is a file, or a playlist index, if it is a URL. Indices can have at most four digits (to differentiate them from numeric IDs). A third and further numbers do nothing."
wrap "These apply to the level where they are specified, for example \"dl n fileA fileB\" prepends all video filenames that come from fileA with \"0001_\" and all filenames from fileB with \"0002_\". \"dl fileA n fileB\" prepends the video from the first line of fileA with \"0001_\", the video from the second line of fileA with \"0002_\" and the videos from fileB with nothing. \"dl f plA plB\" creates two folders, named after the playlists behind plA and plB, and the video files will be put into those respective folders. \"dl fileA f\" creates one folder per line in fileA."
wrap "If these are used on multiple levels, then numbers for lower levels will come after numbers for higher levels and folders for lower levels will be inside folders for higher levels, for example \"dl n fileA n fileB\" will create videos with names like \"0001_0001_…\", \"0001_0002_…\", \"0001_0003_…\", … from fileA and videos with names like \"0002_…\" from fileB."
wrap "\"f\" and \"n\" together lead to numbered folders with unnumbered files inside (except if the entries also have \"n\", of course)."
wrap "When arguments conflict, the last one is applied, so e.g. \"dl f F urlA\" downloads urlA without creating a folder."
echo
wrap "General options:"
wrap "m: Download as audio only and convert to MP3. Set by default for SoundCloud and Bandcamp."
wrap "M: Download as video and convert to MP4. Set by default for everything except SoundCloud and Bandcamp."
wrap "r: Limit resolution to 1080p. Always set by default. If both \"m\" and \"r\"/\"R\" are specified, \"m\" takes precedence."
wrap "R: Download the best quality. Never set by default."
wrap "These apply to everything on their level and below. For example \"dl m urlA urlB M urlC\" downloads urlA and urlC as music and urlB as video. Every line in a file can override the parameters for the entire file, which then only applies to that line."
wrap "When arguments conflict, the last one is applied, so e.g. \"dl m M urlA\" downloads urlA as video."
wrap "Spaces between arguments are not necessary if the meaning is clear, so e.g. \"5fNR7\" works. \"m24\" would download index 24 and above as music, not 2 to 4."
echo
wrap "All lines in a given file are skipped that begin with any amount (including none) of whitespace and then one of these (case-insensitive):"
echo "# / \\ * ; % ! | ( { = ¢ £ ⍝ :: <# \$! \$\$ {- @c R: NB. ''' \"\"\" <!-- --[[ --[= (?#"
wrap "Multi-line comments are not supported (prefixes like /* still just apply to that one line). Closing of e.g. HTML comments is not necessary."
wrap "Comments starting with REM, -- and a few others are not supported because YouTube IDs could start with those. Comments starting with \" or ' are not supported because they can be used to prevent word splitting."
wrap "These comment indicators come from various programming languages and markdown formats. If you are used to a comment syntax that is not listed here, open an issue on GitHub."
echo
wrap "Each line in a file works just like another \"dl\" command, with the following exceptions:"
wrap "· Empty and commented out lines (see below) are ignored."
wrap "· If the first (not empty or commented out) line can be parsed completely as \"dl\" arguments ([m|n|N|r|\e[3mINDEX\e[0m]…), those will be applied to the entire file and the first line on its own does nothing."
wrap "· Writing the \"dl \" part is not necessary. If it's done anyway, it works just the same as without. This might be useful as a workaround in edge cases."
wrap "Recursion does work and is how this script works anyway, so files can reference other files, just like playlist-like things on YouTube and SoundCloud can contain other playlist-like things."
wrap "There is currently no easy way to disable numbering of inner layers of nested playlist. As a workaround, use \"yt-dlp --flat-playlist --get-id\" on the outer playlist(s) and put those IDs into \"dl\" with whatever parameters you want."
wrap "Files and playlists get expanded until only URLs are left, passing on the current m/M and r/R state."
echo
wrap "All folders in \$CDPATH are searched for files, additionally to the current folder."
wrap "IDs of YouTube, Vimeo and Imgur videos, SoundCloud and BandCamp tracks and BandCamp albums can be used instead of full URLs. If the ID looks just like other arguments could, use a full URL: youtu.be/fFmMnNrR059"
wrap "The special cases \"LL\"/\"liked\" for the liked YouTube videos and \"fav\" for the favourites list on YouTube can be used."
wrap "To specify a file that could be interpreted as other arguments, use a path: \"./m\""
wrap "English, German and Japanese non-automatic subtitles are included in video downloads."
wrap "yt-dlp and FFMPEG are both set to silent except for the progress indicator, in the ideal case the only output left at the end are success messages from the script. Errors and some warnings will still appear."
echo
wrap "Examples:"
tablewrap "dl" "Downloads the entire WL playlist into $HOME/Downloads. Already downloaded tracks are skipped, as usual."\
"dl m 4" "Downloads the temp_music playlist as MP3 into $drive/temp_music, skipping the first three tracks."\
"dl https://www.youtube.com/watch?v=lXMskKTw3Bc" "Downloads that video."\
"dl R list.txt 2 4 \"6mfosvqAqAw\" m '_qJHEPecdvg'" "Downloads videos from lines 2, 3 and 4 of file \"list.txt\" and the YouTube video with the ID \"_qJHEPecdvg\" at maximum resolution and the YouTube video with the ID \"6mfosvqAqAw\" as MP3."\
"dl LL 42 m 69 3141 k3RKPyJPMOY R" "Downloads videos 42 to 69 from the liked videos playlist as MP3 and the video with the ID \"k3RKPyJPMOY\" with maximum resolution."
echo
wrap "Source and issue tracker on GitHub: \e[34mhttps://github.com/Fabian42/bash_scripts/blob/master/dl\e[0m"
echo
wrap "Current contents of $HOME/.config/yt-dlp/config:"
cat ~/.config/yt-dlp/config
exit
fi
### MAIN PART START
# print start time only for initial call in recursion
if [[ "$dl_time_printed" == "" ]]; then date "+%H:%M:%S"; export dl_time_printed=1; fi
# preparation for later looking up files in all CDPATH locations
if [[ "$CDPATH" == "" ]]; then CDPATH="."; fi
# TODO: set default switch states
for arg in "$@"; do
if [[ "$arg" =~ ^[0-9fFmMnNrR]+$ && ! "$arg" =~ ^[0-9]{5,}$ ]]; then
# TODO: handle args
echo args
else
for folder in $(IFS=':'; echo $CDPATH); do
# TODO: check for file, continue 2
echo "file in $folder"
done
if [[ "$arg" == "fav" ]]; then
# TODO: --playlist-reverse ":ytfav"
echo fav
elif [[ "$arg" =~ ^liked?$ || "$arg" =~ ^[Ll]{2}$ ]]; then
# TODO: --playlist-reverse "youtube.com/playlist?list=LL"
echo LL
elif yt-dlp -qs "youtu.be/$arg" 2>/dev/null; then
# TODO: keep parsing, download video
echo "YT video"
elif yt-dlp -qs --flat-playlist --playlist-end 1 "youtube.com/playlist?list=$arg" 2>/dev/null; then
# TODO: keep parsing, download playlist
echo "YT playlist"
elif yt-dlp -qs "twitch.tv/videos/$arg" 2>/dev/null; then
# TODO: keep parsing, download video
echo "Twitch video"
elif yt-dlp -qs "clips.twitch.tv/$arg" 2>/dev/null; then
# TODO: keep parsing, download clip
echo "Twitch clip"
elif yt-dlp -qs "api.soundcloud.com/tracks/$arg" 2>/dev/null; then
# TODO: keep parsing, download track
echo "SC track"
elif wget -qO - "bandcamp.com/EmbeddedPlayer/album=$arg" 2>/dev/null | grep -q "linkback"; then
# TODO: $(wget -qO - "bandcamp.com/EmbeddedPlayer/album=$arg" 2>/dev/null | grep -Eo "\\"\\;linkback\\"\\;\\:\\"\\;https\\:\\/\\/[a-z0-9]+\\.bandcamp\\.com\\/album\\/[a-z0-9]+\\"\\;" | sed "s/\\"\\;linkback\\"\\;\\:\\"\\;//;s/\\"\\;//")
echo "BandCamp album"
elif wget -qO - "bandcamp.com/EmbeddedPlayer/track=$arg" 2>/dev/null | grep -q "linkback"; then
# TODO: $(wget -qO - "bandcamp.com/EmbeddedPlayer/track=$arg" 2>/dev/null | grep -Eo "\\"\\;linkback\\"\\;\\:\\"\\;https\\:\\/\\/[a-z0-9]+\\.bandcamp\\.com\\/track\\/[a-z0-9]+\\"\\;" | sed "s/\\"\\;linkback\\"\\;\\:\\"\\;//;s/\\"\\;//")
echo "BandCamp track"
elif yt-dlp -qs "imgur.com/$arg" 2>/dev/null; then
# TODO: keep parsing, download video
echo Imgur
elif yt-dlp -qs "vimeo.com/$arg" 2>/dev/null; then
# TODO: keep parsing, download video
echo Vimeo
else
# TODO: keep parsing, try it with yt-dlp
echo misc
fi
fi
done
# # old function
# dl(){
# if [[ "$1" =~ ^(\-\-?|\/)?(h(elp)?|\?)$ ]]; then
# /home/fabian/hdd/d/programs/bash_scripts/dl --help
# else
# date "+%H:%M:%S"
# if [ "$1" == "" ]; then
# youtube-dl --add-header 'Cookie:' -q --no-warnings -i --retries infinite --fragment-retries infinite -u "[email protected]" -p "$yt_pw" -o "/home/fabian/Downloads/%(playlist_index)04i_%(uploader)s_-_%(title)s_%(id)s.%(ext)s" --restrict-filenames --mark-watched --sub-lang "ja,ja-JP,de,de-DE,en-US,en,en-GB" --write-sub --embed-subs --exec "echo \"\$(date "+%H:%M:%S") {}\"" https://www.youtube.com/playlist?list=$wl_id
# else
# if [[ "$1" =~ ^[0-9]+$ ]]; then
# youtube-dl --add-header 'Cookie:' -q --no-warnings -i --retries infinite --fragment-retries infinite -u "[email protected]" -p "$yt_pw" -o "/home/fabian/Downloads/%(playlist_index)04i_%(uploader)s_-_%(title)s_%(id)s.%(ext)s" --restrict-filenames --mark-watched --sub-lang "ja,ja-JP,de,de-DE,en-US,en,en-GB" --write-sub --embed-subs --playlist-start $1 --exec "echo \"\$(date "+%H:%M:%S") {}\"" https://www.youtube.com/playlist?list=$wl_id
# else
# if [ "$2" == "" ]; then
# youtube-dl --add-header 'Cookie:' -q --no-warnings -i --retries infinite --fragment-retries infinite -o "%(playlist_index)04i_%(uploader)s_-_%(title)s_%(id)s.%(ext)s" --restrict-filenames --sub-lang "ja,ja-JP,de,de-DE,en-US,en,en-GB" --write-sub --embed-subs --exec "echo \"\$(date "+%H:%M:%S") {}\"" $1
# else
# if [[ "$2" =~ ^[0-9]+$ ]]; then
# youtube-dl --add-header 'Cookie:' -q --no-warnings -i --retries infinite --fragment-retries infinite -o "%(playlist_index)04i_%(uploader)s_-_%(title)s_%(id)s.%(ext)s" --restrict-filenames --sub-lang "ja,ja-JP,de,de-DE,en-US,en,en-GB" --write-sub --embed-subs --playlist-start $2 --exec "echo \"\$(date "+%H:%M:%S") {}\"" $1
# else
# if [ "$1" == "m" ]; then
# if [[ "$3" =~ ^[0-9]+$ ]]; then
# youtube-dl --add-header 'Cookie:' -q --no-warnings -i --retries infinite --fragment-retries infinite -o "%(playlist_index)04i_%(uploader)s_-_%(title)s_%(id)s.%(ext)s_temp" --restrict-filenames --playlist-start $3 -f bestaudio/best --exec "file=\"{}\"; if [[ \"\$(echo \"\$file\" | grep -E \".mp3_temp\$\")\" == \"\" ]]; then ffmpeg -i \"\$file\" -nostdin -map 0:a -map_metadata -1 -v 16 -q:a 0 -y \"\${file%.*}.mp3\"; else ffmpeg -i \"\$file\" -nostdin -map 0:a -map_metadata -1 -v 16 -c:a copy -y \"\${file%_temp}\"; fi; if (( \"\$?\" == 0 )); then rm \"\$file\"; echo \"\$(date \"+%H:%M:%S\") \${file%.*}.mp3\"; else echo \"WARNING: Problem encountered while converting \$file, downloaded file was left unchanged.\"; fi" $2
# else
# shift
# youtube-dl --add-header 'Cookie:' -q --no-warnings -i --retries infinite --fragment-retries infinite -o "%(playlist_index)04i_%(uploader)s_-_%(title)s_%(id)s.%(ext)s_temp" --restrict-filenames -f bestaudio/best --exec "file=\"{}\"; if [[ \"\$(echo \"\$file\" | grep -E \".mp3_temp\$\")\" == \"\" ]]; then ffmpeg -i \"\$file\" -nostdin -map 0:a -map_metadata -1 -v 16 -q:a 0 -y \"\${file%.*}.mp3\"; else ffmpeg -i \"\$file\" -nostdin -map 0:a -map_metadata -1 -v 16 -c:a copy -y \"\${file%_temp}\"; fi; if (( \"\$?\" == 0 )); then rm \"\$file\"; echo \"\$(date \"+%H:%M:%S\") \${file%.*}.mp3\"; else echo \"WARNING: Problem encountered while converting \$file, downloaded file was left unchanged.\"; fi" "$@"
# fi
# else
# youtube-dl --add-header 'Cookie:' -q --no-warnings -i --retries infinite --fragment-retries infinite -o "%(playlist_index)04i_%(uploader)s_-_%(title)s_%(id)s.%(ext)s" --restrict-filenames --sub-lang "en-GB,en,en-US,de,de-DE,ja,ja-JP" --write-sub --embed-subs --exec "echo \"\$(date "+%H:%M:%S") {}\"" "$@"
# fi
# fi
# fi
# fi
# fi
# if (( "$?" != 0 )); then
# echo "There were errors while downloading!"
# fi
# fi
# }