genevera (she/her) genevera commited on
Commit
1003226
·
unverified ·
1 Parent(s): 7391d4d

yt-wsp.sh : add unique filename generation (#495)

Browse files

Co-authored-by: genevera <[email protected]>

Files changed (1) hide show
  1. examples/yt-wsp.sh +129 -72
examples/yt-wsp.sh CHANGED
@@ -1,20 +1,10 @@
1
  #!/usr/bin/env bash
2
-
3
- # Small shell script to more easily automatically download and transcribe live stream VODs.
4
- # This uses YT-DLP, ffmpeg and the CPP version of Whisper: https://github.com/ggerganov/whisper.cpp
5
- # Use `./examples/yt-wsp.sh help` to print help info.
6
- #
7
- # Sample usage:
8
- #
9
- # git clone https://github.com/ggerganov/whisper.cpp
10
- # cd whisper.cpp
11
- # make
12
- # ./examples/yt-wsp.sh https://www.youtube.com/watch?v=1234567890
13
- #
14
 
15
  # MIT License
16
 
17
  # Copyright (c) 2022 Daniils Petrovs
 
18
 
19
  # Permission is hereby granted, free of charge, to any person obtaining a copy
20
  # of this software and associated documentation files (the "Software"), to deal
@@ -34,114 +24,181 @@
34
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
35
  # SOFTWARE.
36
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  set -Eeuo pipefail
38
 
39
- # You can find how to download models in the OG repo: https://github.com/ggerganov/whisper.cpp/#usage
40
- MODEL_PATH="${MODEL_PATH:-models/ggml-base.en.bin}" # Set to a multilingual model if you want to translate from foreign lang to en
41
- WHISPER_EXECUTABLE="${WHISPER_EXECUTABLE:-whisper}" # Where to find the whisper.cpp executable
42
- WHISPER_LANG="${WHISPER_LANG:-en}" # Set to desired lang to translate from
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
 
44
  msg() {
45
  echo >&2 -e "${1-}"
46
  }
47
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  cleanup() {
49
- msg "Cleaning up..."
50
- rm -rf "${temp_dir}" "vod-resampled.wav" "vod-resampled.wav.srt"
 
 
 
 
 
 
 
51
  }
52
 
53
  print_help() {
 
54
  echo "Usage: ./examples/yt-wsp.sh <video_url>"
55
- echo "See configurable env variables in the script"
56
- echo "This will produce an MP4 muxed file called res.mp4 in the working directory"
57
- echo "Requirements: ffmpeg yt-dlp whisper"
58
- echo "Whisper needs to be built into the main binary with make, then you can rename it to something like 'whisper' and add it to your PATH for convenience."
59
- echo "E.g. in the root of Whisper.cpp, run: 'make && cp ./main /usr/local/bin/whisper'"
 
 
60
  }
61
 
62
  check_requirements() {
63
  if ! command -v ffmpeg &>/dev/null; then
64
- echo "ffmpeg is required (https://ffmpeg.org)."
65
  exit 1
66
- fi
67
 
68
  if ! command -v yt-dlp &>/dev/null; then
69
- echo "yt-dlp is required (https://github.com/yt-dlp/yt-dlp)."
70
- exit 1
71
- fi
72
-
73
- if ! command -v "$WHISPER_EXECUTABLE" &>/dev/null; then
74
- WHISPER_EXECUTABLE="./main"
75
- if ! command -v "$WHISPER_EXECUTABLE" &>/dev/null; then
76
- echo "Whisper is required (https://github.com/ggerganov/whisper.cpp):"
77
- echo "Sample usage:"
78
- echo ""
79
- echo " git clone https://github.com/ggerganov/whisper.cpp"
80
- echo " cd whisper.cpp"
81
- echo " make"
82
- echo " ./examples/yt-wsp.sh https://www.youtube.com/watch?v=1234567890"
83
- echo ""
84
- exit 1
85
- fi
86
- fi
87
  }
88
 
89
- if [[ $# -lt 1 ]]; then
90
- print_help
91
- exit 1
92
  fi
93
 
94
- if [[ "$1" == "help" ]]; then
95
- print_help
96
- exit 0
97
  fi
98
 
99
- temp_dir="tmp"
100
- source_url="$1"
101
 
102
- check_requirements
103
 
104
- msg "Downloading VOD..."
105
-
106
- # Optionally add --cookies-from-browser BROWSER[+KEYRING][:PROFILE][::CONTAINER] for members only VODs
 
 
107
  yt-dlp \
108
  -f "bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best" \
 
 
 
 
 
109
  --embed-thumbnail \
110
  --embed-chapters \
111
  --xattrs \
112
- "${source_url}" -o "${temp_dir}/vod.mp4"
 
 
113
 
114
- msg "Extracting audio and resampling..."
115
 
116
- ffmpeg -i "${temp_dir}/vod.mp4" \
117
  -hide_banner \
 
118
  -loglevel error \
119
  -ar 16000 \
120
  -ac 1 \
121
- -c:a \
122
- pcm_s16le -y "vod-resampled.wav"
 
123
 
124
- msg "Transcribing to subtitle file..."
125
- msg "Whisper specified at: ${WHISPER_EXECUTABLE}"
126
 
127
- $WHISPER_EXECUTABLE \
128
  -m "${MODEL_PATH}" \
129
  -l "${WHISPER_LANG}" \
130
- -f "vod-resampled.wav" \
131
- -t 8 \
132
  -osrt \
133
- --translate
134
 
135
- msg "Embedding subtitle track..."
136
 
137
- ffmpeg -i "${temp_dir}/vod.mp4" \
138
  -hide_banner \
139
  -loglevel error \
140
- -i "vod-resampled.wav.srt" \
141
  -c copy \
142
  -c:s mov_text \
143
- -y res.mp4
144
 
145
- cleanup
146
 
147
- msg "Done! Your finished file is ready: res.mp4"
 
1
  #!/usr/bin/env bash
2
+ # shellcheck disable=2086
 
 
 
 
 
 
 
 
 
 
 
3
 
4
  # MIT License
5
 
6
  # Copyright (c) 2022 Daniils Petrovs
7
+ # Copyright (c) 2023 Jennifer Capasso
8
 
9
  # Permission is hereby granted, free of charge, to any person obtaining a copy
10
  # of this software and associated documentation files (the "Software"), to deal
 
24
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
  # SOFTWARE.
26
 
27
+ # Small shell script to more easily automatically download and transcribe live stream VODs.
28
+ # This uses YT-DLP, ffmpeg and the CPP version of Whisper: https://github.com/ggerganov/whisper.cpp
29
+ # Use `./examples/yt-wsp.sh help` to print help info.
30
+ #
31
+ # Sample usage:
32
+ #
33
+ # git clone https://github.com/ggerganov/whisper.cpp
34
+ # cd whisper.cpp
35
+ # make
36
+ # ./examples/yt-wsp.sh https://www.youtube.com/watch?v=1234567890
37
+ #
38
+
39
  set -Eeuo pipefail
40
 
41
+ # get script file location
42
+ SCRIPT_PATH="$(realpath -e ${BASH_SOURCE[0]})";
43
+ SCRIPT_DIR="${SCRIPT_PATH%/*}"
44
+
45
+ ################################################################################
46
+ # Documentation on downloading models can be found in the whisper.cpp repo:
47
+ # https://github.com/ggerganov/whisper.cpp/#usage
48
+ #
49
+ # note: unless a multilingual model is specified, WHISPER_LANG will be ignored
50
+ # and the video will be transcribed as if the audio were in the English language
51
+ ################################################################################
52
+ MODEL_PATH="${MODEL_PATH:-${SCRIPT_DIR}/../models/ggml-base.en.bin}"
53
+
54
+ ################################################################################
55
+ # Where to find the whisper.cpp executable. default to the examples directory
56
+ # which holds this script in source control
57
+ ################################################################################
58
+ WHISPER_EXECUTABLE="${WHISPER_EXECUTABLE:-${SCRIPT_DIR}/../main}";
59
+
60
+ # Set to desired language to be translated into english
61
+ WHISPER_LANG="${WHISPER_LANG:-en}";
62
+
63
+ # Default to 4 threads (this was most performant on my 2020 M1 MBP)
64
+ WHISPER_THREAD_COUNT="${WHISPER_THREAD_COUNT:-4}";
65
 
66
  msg() {
67
  echo >&2 -e "${1-}"
68
  }
69
 
70
+ ################################################################################
71
+ # create a temporary directory to work in
72
+ # set the temp_dir and temp_filename variables
73
+ ################################################################################
74
+ temp_dir="$(mktemp -d ${SCRIPT_DIR}/tmp.XXXXXX)";
75
+ temp_filename="${temp_dir}/yt-dlp-filename";
76
+
77
+ ################################################################################
78
+ # for now we only take one argument
79
+ # TODO: a for loop
80
+ ################################################################################
81
+ source_url="${1}"
82
+
83
+
84
+ title_name="";
85
+
86
+
87
  cleanup() {
88
+ local -r clean_me="${1}";
89
+
90
+ if [ -d "${clean_me}" ]; then
91
+ msg "Cleaning up...";
92
+ rm -rf "${clean_me}";
93
+ else
94
+ msg "'${clean_me}' does not appear to be a directory!";
95
+ exit 1;
96
+ fi;
97
  }
98
 
99
  print_help() {
100
+ echo "################################################################################"
101
  echo "Usage: ./examples/yt-wsp.sh <video_url>"
102
+ echo "# See configurable env variables in the script; there are many!"
103
+ echo "# This script will produce an MP4 muxed file in the working directory; it will"
104
+ echo "# be named for the title and id of the video."
105
+ echo "# passing in https://youtu.be/VYJtb2YXae8 produces a file named";
106
+ echo "# 'Why_we_all_need_subtitles_now-VYJtb2YXae8-res.mp4'"
107
+ echo "# Requirements: ffmpeg yt-dlp whisper.cpp"
108
+ echo "################################################################################"
109
  }
110
 
111
  check_requirements() {
112
  if ! command -v ffmpeg &>/dev/null; then
113
+ echo "ffmpeg is required: https://ffmpeg.org";
114
  exit 1
115
+ fi;
116
 
117
  if ! command -v yt-dlp &>/dev/null; then
118
+ echo "yt-dlp is required: https://github.com/yt-dlp/yt-dlp";
119
+ exit 1;
120
+ fi;
121
+
122
+ if ! command -v "${WHISPER_EXECUTABLE}" &>/dev/null; then
123
+ echo "The C++ implementation of Whisper is required: https://github.com/ggerganov/whisper.cpp"
124
+ echo "Sample usage:";
125
+ echo "";
126
+ echo " git clone https://github.com/ggerganov/whisper.cpp";
127
+ echo " cd whisper.cpp";
128
+ echo " make";
129
+ echo " ./examples/yt-wsp.sh https://www.youtube.com/watch?v=1234567890";
130
+ echo "";
131
+ exit 1;
132
+ fi;
133
+
 
 
134
  }
135
 
136
+ if [[ "${#}" -lt 1 ]]; then
137
+ print_help;
138
+ exit 1;
139
  fi
140
 
141
+ if [[ "${1##-*}" == "help" ]]; then
142
+ print_help;
143
+ exit 0;
144
  fi
145
 
146
+ check_requirements;
 
147
 
148
+ msg "Downloading VOD...";
149
 
150
+ ################################################################################
151
+ # Download the video, put the dynamic output filename into a variable.
152
+ # Optionally add --cookies-from-browser BROWSER[+KEYRING][:PROFILE][::CONTAINER]
153
+ # for videos only available to logged-in users.
154
+ ################################################################################
155
  yt-dlp \
156
  -f "bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best" \
157
+ -o "${temp_dir}/%(title)s-%(id)s.vod.mp4" \
158
+ --print-to-file "%(filename)s" "${temp_filename}" \
159
+ --no-simulate \
160
+ --no-write-auto-subs \
161
+ --restrict-filenames \
162
  --embed-thumbnail \
163
  --embed-chapters \
164
  --xattrs \
165
+ "${source_url}";
166
+
167
+ title_name="$(xargs basename -s .vod.mp4 < ${temp_filename})";
168
 
169
+ msg "Extracting audio and resampling...";
170
 
171
+ ffmpeg -i "${temp_dir}/${title_name}.vod.mp4" \
172
  -hide_banner \
173
+ -vn \
174
  -loglevel error \
175
  -ar 16000 \
176
  -ac 1 \
177
+ -c:a pcm_s16le \
178
+ -y \
179
+ "${temp_dir}/${title_name}.vod-resampled.wav";
180
 
181
+ msg "Transcribing to subtitle file...";
182
+ msg "Whisper specified at: '${WHISPER_EXECUTABLE}'";
183
 
184
+ "${WHISPER_EXECUTABLE}" \
185
  -m "${MODEL_PATH}" \
186
  -l "${WHISPER_LANG}" \
187
+ -f "${temp_dir}/${title_name}.vod-resampled.wav" \
188
+ -t "${WHISPER_THREAD_COUNT}" \
189
  -osrt \
190
+ --translate;
191
 
192
+ msg "Embedding subtitle track...";
193
 
194
+ ffmpeg -i "${temp_dir}/${title_name}.vod.mp4" \
195
  -hide_banner \
196
  -loglevel error \
197
+ -i "${temp_dir}/${title_name}.vod-resampled.wav.srt" \
198
  -c copy \
199
  -c:s mov_text \
200
+ -y "${title_name}-res.mp4";
201
 
202
+ cleanup "${temp_dir}";
203
 
204
+ msg "Done! Your finished file is ready: ${title_name}-res.mp4";