Commit | Line | Data |
---|---|---|
cb0f307f SBS |
1 | #!/usr/bin/env bash |
2 | # Desc: Download YouTube videos | |
3 | # Usage: $ ./bkytpldl-generic | |
107b9c53 | 4 | # Version: 4.1.1 |
cb0f307f SBS |
5 | |
6 | declare -a args; # array for yt-dlp arguments | |
7 | declare -a urls urls_rand; # array for YouTube playlist URLs | |
8 | ||
2a4d0fe2 SBS |
9 | # Settings |
10 | dir_out="~/Videos/"; | |
107b9c53 SBS |
11 | urls+=("https://www.youtube.com/playlist?list=PLxxx"); # Adjust me. YouTube playlist URL goes here |
12 | urls+=("https://www.youtube.com/playlist?list=PLxxx"); # Adjust me. YouTube playlist URL goes here | |
13 | urls+=("https://www.youtube.com/playlist?list=PLxxx"); # Adjust me. YouTube playlist URL goes here | |
2a4d0fe2 | 14 | |
cb0f307f SBS |
15 | yell() { echo "$0: $*" >&2; } # print script path and all args to stderr |
16 | die() { yell "$*"; exit 111; } # same as yell() but non-zero exit status | |
17 | must() { "$@" || die "cannot $*"; } # runs args as command, reports args if command fails | |
18 | ||
19 | # check dependencies | |
20 | if ! command -v yt-dlp 1>/dev/random 2>&1; then die "FATAL:yt-dlp not found."; fi; | |
21 | ||
22 | # Donʼt run multiple yt-dlp instances | |
23 | if pgrep "^yt-dlp$" 1>/dev/random 2>&1; then die "FATAL:yt-dlp already running."; fi; | |
24 | ||
25 | # Check directories | |
26 | if [[ ! -d $dir_out ]]; then mkdir -p "$dir_out"; fi; | |
27 | ||
2a4d0fe2 | 28 | # == Assemble options == |
cb0f307f SBS |
29 | |
30 | # yt-dlp output options | |
31 | ## Restrict file name character set | |
32 | #args+=("--restrict-filenames"); # Remove non-ASCII characters | |
33 | args+=("--trim-filenames=120"); # Use in tandem with `%(title).120B` | |
34 | ||
35 | ## Request to write accompanying files | |
36 | args+=("--write-subs"); # Write subtitles file | |
37 | args+=("--write-auto-subs"); # Write subtitles file | |
38 | #args+=("--all-subs"); # Download all available subtitles (causes many requests) | |
39 | #subLangs="en.*,ja.*,id.*,es.*,zh-Hans.*,zh-Hant.*,sv.*,el.*,hi.*,ru.*,bn.*,fr.*,ko.*,ar.*,nv.*"; # custom language list | |
40 | subLangs="en,en-orig,en.*"; # custom language list | |
41 | args+=("--sub-langs" "$subLangs"); | |
42 | args+=("--write-info-json"); # Write accompanying json file | |
43 | args+=("--no-overwrites"); # Don't overwrite files | |
44 | args+=("--write-thumbnail"); # Write thumbnail | |
45 | ||
46 | ## Only download metadata | |
47 | #args+=("--no-download"); # Don't download video file. | |
48 | ||
49 | ## Save meta-data | |
50 | args+=("--write-comments"); # Get comments | |
51 | ### Limit comments | |
52 | ### comment_sort values: | |
53 | ### top : use YouTube top comment algorithm | |
54 | ### new : get newest comments (default) | |
55 | ### max_comments values: | |
56 | ### max-comments : max number of parent comments or replies | |
57 | ### max-parents : max number of comment threads | |
58 | ### max-replies : max number of replies across all threads | |
59 | ### max-replies-per-thread : max number of replies per thread | |
60 | args+=("--extractor-args" "youtube:comment_sort=top;max_comments=10000,100,10000,100"); | |
61 | ||
62 | ## Randomize order in which playlist items are downloaded | |
63 | args+=("--playlist-random"); | |
64 | ||
65 | ## Delay between downloads | |
66 | minSleep="30"; | |
67 | maxSleep="$(( minSleep + (RANDOM + RANDOM + RANDOM) / ( 3 * 400) ))"; # roughly 60 seconds | |
68 | args+=("--min-sleep-interval" "$minSleep"); | |
69 | args+=("--max-sleep-interval" "$maxSleep"); | |
70 | args+=("--sleep-requests" "2"); # delay on metadata requests | |
71 | args+=("--sleep-subtitles" "10"); # delay for subtitles | |
72 | ||
73 | ## Remember downloaded videos to avoid redownload attempts | |
74 | pathDA="$dir_out"/.bkytpldl_history.txt; | |
75 | args+=("--download-archive" "$pathDA"); | |
76 | ||
77 | ## Use firefox 'default-release' profile cookies | |
78 | ## Example: Linux: from ~/.mozilla/firefox/deadbeef.default-release/ | |
79 | #args+=("--cookies-from-browser"); | |
80 | #args+=("firefox:deadbeef.default-release"); Default Firefox profile name | |
81 | ||
82 | ## Specify output filename format | |
83 | ## Note: `$(title).120B` shortens title to 120 bytes (useful for | |
84 | ## titles with UTF-8 characters. | |
85 | args+=("-o"); | |
86 | args+=("%(playlist)s/%(upload_date)s.%(channel)s.%(channel_id)s.%(title).120B.%(id)s.%(ext)s"); | |
87 | ||
88 | ## Limit download resolution to 1080p | |
89 | args+=("-S" "res:1080"); | |
90 | ||
91 | ## Specify playlist URLs to download | |
cb0f307f SBS |
92 | ### Shuffle playlist download order |
93 | mapfile -t urls_rand < <(printf "%s\n" "${urls[@]}" | shuf); | |
94 | for url in "${urls_rand[@]}"; do | |
95 | args+=("$url"); | |
96 | done; | |
97 | ||
98 | # Change working directory to output dir | |
99 | pushd "$dir_out" || die "FATAL:Failed to change pwd to:dir_out:$dir_out"; | |
100 | ||
2a4d0fe2 SBS |
101 | # == Download videos == |
102 | ||
cb0f307f SBS |
103 | #yell "DEBUG:args:$(declare -p args)"; # debug command |
104 | must yt-dlp "${args[@]}"; # execute command | |
105 | popd || die "FATAL:Failed to return from dir_out:$dir_out"; | |
106 | ||
107 | # Author: Steven Baltakatei Sandoval | |
108 | # License; GPLv3+ |