youtube-dl - Download videos from YouTube (and more sites)

mail

What if the best quality audio and video tracks are in distinct YouTube streams ?

Situation

[youtube] bAdqazixuRY: Downloading webpage
[youtube] bAdqazixuRY: Downloading video info webpage
[info] Available formats for bAdqazixuRY:
format code	extension	resolution	note
249		webm		audio only	DASH audio   56k , opus @ 50k, 1.50MiB
250		webm		audio only	DASH audio   75k , opus @ 70k, 2.00MiB
140		m4a		audio only	DASH audio  130k , m4a_dash container, mp4a.40.2@128k, 3.94MiB
171		webm		audio only	DASH audio  142k , vorbis@128k, 3.70MiB					I'd like this audio track...
251		webm		audio only	DASH audio  150k , opus @160k, 3.99MiB
394		mp4		256x144		144p   87k , av01.0.05M.08, 25fps, video only, 2.34MiB
278		webm		256x144		144p   98k , webm container, vp9, 25fps, video only, 2.72MiB
160		mp4		256x144		144p  118k , avc1.4d400c, 25fps, video only, 2.32MiB
395		mp4		426x240		240p  196k , av01.0.05M.08, 25fps, video only, 4.77MiB
242		webm		426x240		240p  221k , vp9, 25fps, video only, 5.36MiB
133		mp4		426x240		240p  252k , avc1.4d4015, 25fps, video only, 4.31MiB
396		mp4		640x360		360p  342k , av01.0.05M.08, 25fps, video only, 8.50MiB
243		webm		640x360		360p  412k , vp9, 25fps, video only, 9.89MiB
397		mp4		854x480		480p  634k , av01.0.05M.08, 25fps, video only, 14.94MiB
134		mp4		640x360		360p  637k , avc1.4d401e, 25fps, video only, 10.41MiB
244		webm		854x480		480p  762k , vp9, 25fps, video only, 17.17MiB
135		mp4		854x480		480p 1190k , avc1.4d401e, 25fps, video only, 20.50MiB
247		webm		1280x720	720p 1520k , vp9, 25fps, video only, 34.49MiB
136		mp4		1280x720	720p 2368k , avc1.4d401f, 25fps, video only, 38.07MiB
248		webm		1920x1080	1080p 2665k , vp9, 25fps, video only, 59.33MiB
137		mp4		1920x1080	1080p 4406k , avc1.640028, 25fps, video only, 66.79MiB			... and this video track
271		webm		2560x1440	1440p 8791k , vp9, 25fps, video only, 137.79MiB
313		webm		3840x2160	2160p 17743k , vp9, 25fps, video only, 355.77MiB
18		mp4		640x360		medium	582k , avc1.42001E, mp4a.40.2@ 96k (44100Hz), 17.72MiB (best)	Only (audio + video) track available, but such a poor quality 

Details

The idea would be to :
  1. download both tracks : 1 "audio only" + 1 "video only"
  2. merge both with avconv or ffmpeg
  3. BONUS : the original YouTube video has a final "sponsors + links" screen at the very end. Would that be possible to remove it ? Of course, you just have to get the "final cut" time.
Have a look at the script below :

Solution

#!/usr/bin/env bash

youtubeUrl='https://www.youtube.com/watch?v=bAdqazixuRY'
startTime='0:0'
stopTime='4:04'
outputFile='./output.mp4'

trackFilePrefix='track_'
soundTrackId='171'
videoTrackId='137'

for trackId in "$videoTrackId" "$soundTrackId"; do
	youtube-dl --no-overwrites -f "$trackId" "$youtubeUrl" -o "$trackFilePrefix$trackId"
done

ffmpeg -i "$trackFilePrefix$soundTrackId" -i "$trackFilePrefix$videoTrackId" -map 0:0 -map 1:0 -ss "$startTime" -t "$stopTime" -c copy "$outputFile"
mail

How to download an album / playlist from YouTube with the best possible audio quality (no format conversion) ?

For an optimal (bug-free ) experience, make sure youtube-dl is up-to-date.
After experiencing the youtube-dl is very slow issue, I've switched to yt-dlp : in the CLI, simply replace youtube-dl with yt-dlp and enjoy !

Up-to date procedure

  1. get the code of the audio format you'd like to get :
    yt-dlp -F youtubePlaylistUrl
  2. then catch them all with a single command :
  3. automatically create a directory with the album name + rename files with track numbers and clean track names :
    yt-dlp -f 251 -o "%(playlist)s/%(playlist_index)s - %(title)s.%(ext)s" 'https://music.youtube.com/playlist?list=OLAK5uy_nWNDw-Jx1u5A2_7ygFAKeiEcVe1mGMk7k'
  4. wait, then enjoy !

"old" procedure

This script is here for "historical" reasons. This is old code I've not updated for a while (one-liners above do the job). Not sure it still works
#!/bin/bash

playlist='https://www.youtube.com/playlist?list=PL4A181D94881BD304'
audioformatString='vorbis@128k'
youtubeBaseUrl='https://www.youtube.com/watch?v='

getVideosIdFromPlaylist() {
	playlist="$1"
#	youtube-dl --get-id --max-downloads 3 "$playlist"	for dev/debug only
	youtube-dl --get-id "$playlist"
	}

getFormatCodeOfVideoHavingBestAudioQuality() {
	youtubeVideoId="$1"
	youtube-dl -F "$youtubeBaseUrl$youtubeVideoId" | awk -v needle='audio only.*'"$audioformatString" '$0 ~ needle { print $1 }'
	}

downloadYoutubeTrack() {
	formatCode="$1"
	youtubeVideoId="$2"
	youtube-dl -f "$formatCode" -o "%(playlist)s/%(playlist_index)s - %(track_number)s - %(title)s.%(ext)s" "$youtubeBaseUrl$youtubeVideoId"
	}

for youtubeVideoId in $(getVideosIdFromPlaylist "$playlist"); do
	formatCodeOfVideoHavingBestAudioQuality=$(getFormatCodeOfVideoHavingBestAudioQuality "$youtubeVideoId")
	downloadYoutubeTrack "$formatCodeOfVideoHavingBestAudioQuality" "$youtubeVideoId"
done

As a big fat one-liner :

playlist='https://www.youtube.com/watch?v=RKmw9oS__MM&list=RDRKmw9oS__MM'; audioformatString='opus @160k'; youtubeBaseUrl='https://www.youtube.com/watch?v='; echo 'Retrieving the list of videos IDs, this may take some time...'; for youtubeVideoId in $(youtube-dl --get-id "$playlist"); do formatCode=$(youtube-dl -F "$youtubeBaseUrl$youtubeVideoId" | awk -v needle='audio only.*'"$audioformatString" '$0 ~ needle { print $1 }'); youtube-dl -f "$formatCode" -o "%(playlist)s/%(playlist_index)s - %(track_number)s - %(title)s.%(ext)s" "$youtubeBaseUrl$youtubeVideoId"; done
Alternate method :

1. download all streams marked as 'best quality' (mostly HD videos) :

playlist='https://www.youtube.com/watch?v=Rl-VzB3PhTo&list=RDd27mV60APRo'; audioformatString='(best)'; youtubeBaseUrl='https://www.youtube.com/watch?v='; for youtubeVideoId in $(youtube-dl --get-id "$playlist"); do formatCode=$(youtube-dl -F "$youtubeBaseUrl$youtubeVideoId" | awk -v needle="$audioformatString" '$0 ~ needle { print $1 }'); youtube-dl -f "$formatCode" -o "%(playlist)s/%(playlist_index)s - %(track_number)s - %(title)s.%(ext)s" "$youtubeBaseUrl$youtubeVideoId"; done

2. extract audio from all those videos
mail

How to download a track / playlist from YouTube and convert it to MP3 ?

This method works fine, BUT :
  • I can't be sure it picks the audio track having the best quality
  • it re-encodes the audio, meaning :
    • degrading again the audio quality
    • useless CPU usage + delay
    • generating artificial "high bitrate" MP3 files (i.e. more MB, same/lower quality)
Consider downloading without format conversion.

If anything below fails saying :

ERROR: ffprobe or avprobe not found. Please install one.
you'll have to install either ffmpeg or avconv (source) :
apt install libav-tools

Single track

youtube-dl --extract-audio --audio-format mp3 --audio-quality 0 https://www.youtube.com/watch?v=DOtoIBrBAYE

Playlist

youtube-dl --extract-audio --audio-format mp3 -o "%(title)s.%(ext)s" https://www.youtube.com/playlist?list=PLE0F4727AA947BBB9
Will output files named after : youtubeVideoTitle.mp3
youtube-dl --extract-audio --audio-format mp3 -o "%(playlist_index)s - %(title)s.%(ext)s" https://www.youtube.com/playlist?list=PL2E1BB7AF0B48892D
Will output files named after : trackNumber - youtubeVideoTitle.mp3
mail

How to download a single song / video from YouTube ?

  1. List the available formats :

    youtube-dl -F https://www.youtube.com/watch?v=5pBjopDymts

    [youtube] Setting language
    [youtube] 5pBjopDymts: Downloading webpage
    [youtube] 5pBjopDymts: Downloading video info webpage
    [youtube] 5pBjopDymts: Extracting video information
    [info] Available formats for 5pBjopDymts:
    format code	extension	resolution	note
    171		webm		audio only	DASH audio , audio@ 48k (worst)
    140		m4a		audio only	DASH audio , audio@128k
    160		mp4		144p		DASH video , video only
    
    247		webm		720p		DASH video , video only
    136		mp4		720p		DASH video , video only	This is really VIDEO ONLY: no sound !
    248		webm		1080p		DASH video , video only
    
    264		mp4		1440p		DASH video , video only
    249		unknown_videounknown
    
    313		unknown_videounknown
    17		3gp		176x144
    36		3gp		320x240
    43		webm		640x360
    18		mp4		640x360		This is the version I'd like to download
    22		mp4		1280x720	(best)
  2. Pick the version you like :

    youtube-dl -f 18 https://www.youtube.com/watch?v=5pBjopDymts

    [youtube] Setting language
    [youtube] 5pBjopDymts: Downloading webpage
    [youtube] 5pBjopDymts: Downloading video info webpage
    [youtube] 5pBjopDymts: Extracting video information
    [download] Destination: It's Gonna Be OKAY - ThePianoGuys-5pBjopDymts.mp4
    [download] 100% of 20.70MiB in 00:59
mail

youtube-dl

Usage

youtube-dl can be installed via the youtube-dl Debian package (read my notes about youtube-dl setup).

youtube-dl is not limited to YouTube and can download videos (and music !) from MANY other sites I've not tried yet myself

Setup :

Stuff below is obsolete since I moved to yt-dlp, see up-to-date instructions.
There are several ways to install youtube-dl :
  • from the Debian packages, but the stable version is way behind the SID version (2014.08.05-1+deb8u1 vs 2017.03.26-1 as of today). So you'd better install it from the Debian backports.
  • using one of the suggested methods (with some warnings / points of attention) :
    • The pip method (including variants with/without sudo / pip / pip3) installs youtube-dl fine, but I get errors when trying to use it :
      1. sudo -H pip3 install --upgrade youtube-dl
        [sudo] password for kevin:
        Collecting youtube-dl
        	Downloading https://files.pythonhosted.org/packages/05/d4/64dfe51be0fae772e86be3c83d82ec22d59aa8521d88
        34e10355bf60f9f5/youtube_dl-2020.1.24-py2.py3-none-any.whl (1.8MB)
        		100% |████████████████████████████████| 1.8MB 747kB/s
        Installing collected packages: youtube-dl
        Successfully installed youtube-dl-2020.1.24
      2. youtube-dl -F https://www.youtube.com/watch?v=JozAmXo2bDE
        Traceback (most recent call last):
        	File "/usr/local/bin/youtube-dl", line 6, in <module>
        		from youtube_dl import main
        ImportError: cannot import name 'main' from 'youtube_dl' (unknown location)
      3. sudo -H pip3 uninstall youtube-dl
      4. sudo -H pip install --upgrade youtube-dl
        Collecting youtube-dl
        	Using cached https://files.pythonhosted.org/packages/05/d4/64dfe51be0fae772e86be3c83d82ec22d59aa8521d8834e10355bf60f9f5/youtube_dl-2020.1.24-py2.py3-none-any.whl
        Installing collected packages: youtube-dl
        Successfully installed youtube-dl-2020.1.24
      5. youtube-dl -F https://www.youtube.com/watch?v=JozAmXo2bDE
        Traceback (most recent call last):
        	File "/usr/local/bin/youtube-dl", line 6, in <module>
        		from youtube_dl import main
        ImportError: No module named youtube_dl
    • Finally, the cURL methods looks best .

Flags

Flag Usage
-a file --batch-file file download URL's listed in file
you can even combine options : youtube-dl -f 22 -a list
--audio-format format With -x only : specify the audio format, with format in :
best (default), aac, flac, m4a, mp3, opus, vorbis, wav
--audio-quality quality Specify ffmpeg / avconv audio quality with :
  • a value between 0 (better) and 9 (worse) for VBR (default 5)
  • or a specific bitrate like 128K
If omitted, the quality of converted MP3's will default to 64kb/s.
-f formatCode
--format formatCode
download the video having the formatCode format
-F --list-formats list all available formats
-U --update (explicit )
If youtube-dl was installed without the distribution packages (i.e. without apt, yum, ...), it can be updated with (source) :
  • sudo youtube-dl -U
  • sudo -H pip install --upgrade youtube-dl
-o template
--output template
Rename downloaded / converted files according to template
-x --extract-audio Convert video files to audio-only files (requires ffmpeg , avconv or others)

Example

Download + convert to MP3 :