Created
June 25, 2021 15:22
-
-
Save sixem/4447157b8ecbf5fecd9e7a78a06b6ad2 to your computer and use it in GitHub Desktop.
Downloads a YouTube video with all the subtitles packed into a .mkv file
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# ======================================================================== # | |
# Downloads a YouTube video with all the subtitles packed into a .mkv file # | |
# ======================================================================== # | |
# Usage: ./ytdl-subs.sh "YOUTUBE_URL" "OUTPUT_NAME_WITHOUT_EXTENSION" | |
UUID=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1) | |
youtube-dl --all-subs --write-sub --sub-format srt "$1" --format bestvideo+bestaudio -o "$UUID" | |
declare -a SUBS=() | |
declare -a LANGS=() | |
TARGET="" | |
METADATA="" | |
MAPPED="" | |
function join_by | |
{ | |
local d=${1-} | |
local f=${2-} | |
if shift 2; then | |
printf %s "$f" "${@/#/$d}" | |
fi | |
} | |
for NAME in $(find . -name "$UUID*\.mp4" -o -name "$UUID*\.webm" -o -name "$UUID*\.mkv"); do | |
BASENAME=$(basename "$NAME") | |
if [ ! -f "${BASENAME%.*}.mkv" ]; then | |
ffmpeg -i "$BASENAME" -c:v copy -c:a copy "${BASENAME%.*}.mkv" | |
TARGET="${BASENAME%.*}.mkv" | |
else | |
TARGET="$BASENAME" | |
fi | |
if [[ ! "$BASENAME" == *"\.mkv" ]]; then | |
rm "$BASENAME" | |
fi | |
done | |
for NAME in $(find . -name "$UUID*\.vtt" -o -name "$UUID*\.srt"); do | |
BASENAME=$(basename "$NAME") | |
if [[ ! "$BASENAME" == *"\.srt" ]]; then | |
if [ ! -f "${BASENAME%.*}.srt" ]; then | |
ffmpeg -i "$BASENAME" "${BASENAME%.*}.srt" | |
fi | |
rm "$BASENAME" | |
fi | |
done | |
for NAME in $(find . -name "$UUID*\.srt"); do | |
BASENAME=$(basename "$NAME") | |
[[ "$BASENAME" =~ \.([A-Za-z]+)\.srt ]] | |
LANGS=("${LANGS[@]}" "${BASH_REMATCH[1]}") | |
SUBS=("${SUBS[@]}" "$BASENAME") | |
done | |
for INDEX in "${!LANGS[@]}"; do | |
LANG=$(printf '%s\n' "${LANGS[$INDEX]}" | awk '{ print toupper($0) }') | |
METADATA="${METADATA}-metadata:s:s:$INDEX language=$LANG " | |
MAPPED="${MAPPED}-map $((INDEX + 1)) " | |
done | |
ffmpeg -i "$TARGET" -f srt \ | |
-i $(join_by ' -i ' "${SUBS[@]}") \ | |
-map 0:v -map 0:a $MAPPED \ | |
-c:v copy -c:a copy \ | |
$METADATA \ | |
-c:s copy "$2.mkv" | |
rm "$TARGET" | |
for NAME in $(find . -name "$UUID*\.vtt" -o -name "$UUID*\.srt"); do | |
rm $(basename "$NAME") | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment