Last active
August 20, 2021 13:41
-
-
Save skybldev/35203a1bc5b483e8f63a3fbbc89437d6 to your computer and use it in GitHub Desktop.
A script I use to quickly download YouTube videos into my music folder as .ogg files.
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
#!/usr/bin/env bash | |
# ytdl-ogg - quickly download a youtube video from a URL and save to an ogg, | |
# with an optional custom filename. | |
# | |
# USAGE: | |
# ytdl-ogg <URL> <output filename> | |
# | |
# If a custom filename is given, it will save to that name under OUTDIR. | |
# Otherwise, it will save to youtube-dl's default format under OUTDIR. | |
# | |
# TODO: | |
# - Make this code not look like garbage | |
# The directory to output files by default, later sorting, as an example. | |
OUTDIR="$HOME/Music/auto" | |
UNCDIR="$OUTDIR/unconverted" | |
if ! [ -d $UNCDIR ]; then mkdir -p $UNCDIR; fi | |
ytdl_output="$UNCDIR/%(title)s-%(id)s.%(ext)s" | |
# Download the video's audio. | |
youtube-dl \ | |
"$1" \ | |
-f bestaudio \ | |
--no-playlist \ | |
-o "$ytdl_output" | |
# Use the same parameters but only get the filename. | |
filename=$(youtube-dl \ | |
"$1" \ | |
-f bestaudio \ | |
-o "$ytdl_output" \ | |
--get-filename | |
) | |
if [ "${filename#*.}" = "webm" ]; then | |
# If the container is .webm, that means that the format is opus. For some | |
# reason, ffprobe doesn't detect stream bitrate from an opus stream, but | |
# can still get it from the format. | |
# Take audio from downloaded file and save it to a .opus file. | |
ffmpeg \ | |
-v error \ | |
-i "$filename" \ | |
-c:a copy \ | |
"${filename%%.*}.opus" | |
# Strip the extension from the filename and add ".opus" to it. | |
filename="${filename%%.*}.opus" | |
# Find bitrate from the "format" section. | |
bitrate=$(ffprobe \ | |
-v error \ | |
-select_streams a:0 \ | |
-show_entries format=bit_rate \ | |
-of compact=p=0:nk=1 \ | |
"$filename" | |
) | |
else | |
# If it isn't .webm, then it's .m4a with a DASH stream. ffprobe can determine | |
# the bitrate from the stream, so we tell it to do so here. | |
bitrate=$(ffprobe \ | |
-v error \ | |
-select_streams a:0 \ | |
-show_entries stream=bit_rate \ | |
-of compact=p=0:nk=1 \ | |
"$filename" | |
) | |
fi | |
# Determine sample rate from stream section. | |
samplerate=$(ffprobe \ | |
-v error \ | |
-select_streams a:0 \ | |
-show_entries stream=sample_rate \ | |
-of compact=p=0:nk=1 \ | |
"$filename" | |
) | |
echo "Bitrate: $bitrate" | |
echo "Sample Rate: $samplerate" | |
if [ "$2" ]; then | |
# If an output filename is provided, use that. | |
if [ "$(basename "$2")" = "$2" ]; then | |
# If the basename matches the original string, it's a filename, not a path. | |
# Save the file to the name under OUTDIR. | |
output_filename="$OUTDIR/$2" | |
else | |
# If the basename doesn't match the original string, it's under a path. | |
# Save the file to that full custom path instead. | |
output_filename="$2" | |
fi | |
else | |
# Otherwise, save to youtube-dl's format under OUTDIR. | |
file_basename=$(basename "$filename") | |
file_basename_noextension=${filename_basename%%.*} | |
output_filename="$OUTDIR/$file_basename_noextension.ogg" | |
fi | |
echo "Saving to: $output_filename" | |
# Finally, convert the file to .ogg with minimal loss. | |
ffmpeg \ | |
-v error \ | |
-i "$filename" \ | |
-c:a libvorbis \ | |
-ab $bitrate \ | |
-ar $samplerate \ | |
"$output_filename"; | |
echo "Done." |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment