You may not always have a fast Internet connection for your devices, or any connection at all. On one hand, this is OK, since device storage is now relatively large and cheap. On the other hand, many online content providers do not provide an easy way to download their content.
A Command Line Interface (CLI) tool called youtube-dl can help you.
Most likely, youtube-dl is available in your GNU/Linux distribution's repository. However, you are likely better off downloading it directly from its developers to make sure that you stay up-to-date with the latest version. The online services that the tool interacts with frequently change, and having the latest version of the application will ensure that you have the best experience.
Note: If you are not familiar with the GNU/Linux command line interface, review the Conventions page before proceeding.
Installation
You can install youtube-dl with the following command (you will need to make sure that you have the wget
command installed first, which you can verify by running the command -v wget
command):
# wget 'https://yt-dl.org/downloads/latest/youtube-dl' -O '/usr/local/bin/youtube-dl'
This will download the application from https://yt-dl.org/downloads/latest/youtube-dl
and save it as youtube-dl
in your /usr/local/bin
directory.
Now, verify the application file's hash, and compare it to the value posted here:
sha256sum '/usr/local/bin/youtube-dl'
Download and import the developer's public keys into your GNU/Linux system's GPG keyring. For example:
$ wget 'https://phihag.de/keys/A4826A18.asc' &&
gpg --import A4826A18.asc
$ wget 'https://dstftw.github.io/keys/18A9236D.asc' &&
gpg --import 18A9236D.asc
Now, check the signature:
gpg --verify '/usr/local/bin/youtube-dl.sig' '/usr/local/bin/youtube-dl'
The output should say that there is a Good signature from one of the keys that were listed on the page above and that you imported into your keyring.
Next, run the following command to set the appropriate permissions on the application:
# chmod 755 '/usr/local/bin/youtube-dl'
Configuration
By default, the youtube-dl
command will save its output to the directory that you issue the command from. You can change this by creating a youtube-dl configuration file and specifying a new download directory/output file format:
$ mkdir -p "${HOME}/.config/youtube-dl" &&
{
echo '# Save media to Downloads directory in your home directory'
echo '-o "${HOME}/Downloads/%(title)s.%(ext)s"'
} > "${HOME}/.config/youtube-dl/config"
The above command will create the youtube-dl
directory in ${HOME}/.config
(if this directory does not exist on your system, the -p
option will make sure that it is created), create a config
file in that directory, and add lines to the config
file to have the youtube-dl
command download media to your home directory's Downloads
directory. Files will be saved with the media content's title and extension as the filename.
Usage
youtube-dl should work with a vast amount of sites. Also, the command is highly configurable through myriad options. You can customize your commands to alter output filenames with filename templates and specify which video/audio format to obtain.
To see if multiple formats are available for a given piece of media, you can use youtube-dl
's -F
(--list-formats
) option. For example:
$ youtube-dl -F \
'https://betamax.video/videos/watch/0a6feebf-a2d6-4965-9942-34bf63d92054'
[PeerTube] 0a6feebf-a2d6-4965-9942-34bf63d92054: Downloading JSON metadata
[info] Available formats for 0a6feebf-a2d6-4965-9942-34bf63d92054:
format code extension resolution note
480p mp4 480p 80.12MiB
1080p mp4 1080p 190.49MiB (best)
However, it is simplest to let the youtube-dl
command select the best format of a given piece of content for you. You can use the following special names to select the case formats:
best
Selects the best quality format represented by a single file with both video and audiobestvideo
Selects the best quality video-only format (may not be available)bestaudio
Selects the best quality audio-only format (may not be available)
Then, if you just want the best quality format file available that has both video and audio in a single file, you can use a command like this (the -f
option is short for --format
):
youtube-dl -f 'best' 'https://betamax.video/videos/watch/0a6feebf-a2d6-4965-9942-34bf63d92054'
Some media providers keep the best quality video and audio in separate video-only and audio-only files, respectively. There is a way to utilize youtube-dl to create a combined best quality file from these disparate files.
First, make sure that you have ffmpeg
installed. This program is likely available in the repository of your GNU/Linux distribution (if not, you may need to add/enable an additional repository to obtain it).
For example, here is how you can install ffmpeg
on Debian:
# apt install ffmpeg
Then, you can obtain the best video-only file, the best audio-only file, and merge them into a single file with both video and audio like so:
youtube-dl -f 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best' ex_url...
You can find more examples regarding comparable commands in youtube-dl's documentation.
If you encounter a media provider that only has video file formats available, and you only want the video's audio, you can use youtube-dl to download the video, extract the audio, and provide an audio-only file. This will require ffmpeg
, as well.
To obtain just the audio from a file with both video and audio, you can use youtube-dl
's -x
(--extract-audio
) option:
youtube-dl -f 'best' -x ex_url...
Functions
Instead of continually entering these commands, it might be helpful to create bash functions that you can easily call up on the command line and pass content URLs as arguments. For example, here are two bash functions that will grab either the best
or bestaudio
formats for media content.
# Download Video Content
yv() {
youtube-dl -f 'best' "${1}"
}
# Download Audio Content
ya() {
youtube-dl -f 'bestaudio' "${1}"
}
You will need to add these functions to your shell's configuration file to make them persistently available. For example, you can add them to your user's .bashrc
file like so:
$ {
echo -e '\n# Download Video Content'
echo 'yv() {'
echo ' youtube-dl -f '\''best'\'' "${1}"'
echo -e '}\n'
echo '# Download Audio Content'
echo 'ya() {'
echo ' youtube-dl -f '\''bestaudio'\'' "${1}"'
echo '}'
} >> "${HOME}/.bashrc"
Either stop and restart your terminal, or run source "${HOME}/.bashrc"
to see the changes reflected in your shell.
Now, you can use the functions to download content on the command line, e.g., yv 'https://diode.zone/videos/watch/cfab9b7c-89d7-463f-8256-72629ed96791'
.
Multiple Downloads
Running youtube-dl
commands or the functions above are fine for single downloads, but if you ever need to download many files in a short period of time, it can become tedious. The following is a bash script you can use to improve this process.
#!/usr/bin/env bash
# Author: siliconsoul.org
# Purpose: Download audio/video content
# Program
# Obtain script name and save to variable
script_name="${0##/*/}"
# Remove suffix from script name and save to variable
sn_no_suffix="${script_name%.*}"
# Create temporary directory for script error log
# and save to variable
error_dir="$(mktemp -d "/tmp/${sn_no_suffix}.XXXXXXXX")"
# Create file in temporary directory and
# save error log location to variable
error_log="$(touch "${error_dir}/${sn_no_suffix}.log" &&
echo "${error_dir}/${sn_no_suffix}.log")"
# Prompt for audio or video download, save to variable
read -p 'Audio (a) or Video (v)? ' -r choice
# Check for invalid input, reprompt if necessary
while [[ "${choice}" != 'a' && "${choice}" != 'v' ]]; do
echo -e '\nInvalid choice. Try again.\n'
read -p 'Audio (a) or Video (v)? ' -r choice
done
# Set value of output mode variable, based on user input
if [[ "${choice}" == 'a' ]]; then
output_mode='Audio'
elif [[ "${choice}" == 'v' ]]; then
output_mode='Video'
fi
# Give option to enter URL, change the mode, or quit
while read -p \
'Enter unquoted URL (c to change mode, d to debug, or q to quit): ' \
-r user_input; do
# Break loop if user selects 'q'
if [[ "${user_input}" == 'q' ]]; then
break
# Else, if user chooses to view the debug log
elif [[ "${user_input}" == 'd' ]]; then
# Open the debug log
xdg-open "${error_log}"
# Output current mode
echo -e "\\nCurrent mode: ${output_mode}"
# Else, if user chooses to change the mode
elif [[ "${user_input}" == 'c' ]]; then
# Prompt for audio or video download, save to variable
echo ''
read -p 'Audio (a) or Video (v)? ' -r choice
# Check for invalid input, reprompt if necessary
while [[ "${choice}" != 'a' && "${choice}" != 'v' ]]; do
echo -e '\nInvalid choice. Try again.\n'
read -p 'Audio (a) or Video (v)? ' -r choice
done
# Set value of output mode variable, based on user input
if [[ "${choice}" == 'a' ]]; then
output_mode='Audio'
elif [[ "${choice}" == 'v' ]]; then
output_mode='Video'
fi
# Output current mode
echo -e "\\nCurrent mode: ${output_mode}"
else
# Check for invalid URL input, reprompt if necessary; output current mode
while ! [[ "${user_input}" =~ ^htt(p|ps)://.* ]]; do
echo ''
read -p 'Please enter a valid unquoted URL: ' -r user_input
done
# Output current mode
echo -e "\\nCurrent mode: ${output_mode}"
# If choice is audio
if [[ "${choice}" == 'a' ]]; then
# If ffmpeg is installed
if command -v ffmpeg > '/dev/null'; then
youtube-dl -f 'bestaudio[ext=m4a]' \
-q "${user_input}" 2> "${error_log}" &
# Else, if ffmpeg is not installed
else
youtube-dl -f 'bestaudio' -q "${user_input}" 2> "${error_log}" &
fi
# If choice is video
elif [[ "${choice}" == 'v' ]]; then
# If ffmpeg is installed
if command -v ffmpeg > '/dev/null'; then
youtube-dl -f \
'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best' \
-q "${user_input}" 2> "${error_log}" &
# Else, if ffmpeg is not installed
else
youtube-dl -f 'best' -q "${user_input}" 2> "${error_log}" &
fi
fi
fi
done
# Exit script with successful exit status
exit 0
In short, the script gives you the opportunity to continually add URLs for content that you would like to download.
After the script starts, you choose which mode you want to run it in (i.e., Audio or Video mode). On each iteration of the program's main loop, you are asked to enter a new URL. From here, you also have the option to either change the script's mode (c
), debug the script (d
), or quit (q
).
If you have ffmpeg
installed on your system, the script selects the best video-only and audio-only files available, and merges them into a single file with both video and audio. If you do not have ffmpeg
installed, the script selects the best single file with both video and audio, or with audio-only, depending on your mode selection.
youtube-dl
's output has been suppressed, to prevent the script from being disrupted. So, if you ever try to download content and you do not get the expected result, check your system's /tmp
directory for a subdirectory that begins with the name of the script. This subdirectory will contain a file that also begins with the name of the script and ends with .log
. youtube-dl
's error output is redirected to this file.
Documentation
For more information on youtube-dl
, check out its man page by running man 1 youtube-dl
or visit its project repository.