Having grown up on the internet long before the average connection speed made music streaming services viable, streaming has always struck me as wasteful. And I know that doesn't make much sense—it's not like there's a limited amount of bandwidth to go around! But if I'm going to listen to the same audio file five times, why not just download it once and listen to it forever? Particularly if I want to listen to it while airborne and avoid the horrors of plane wifi. Or if I want to remove NSFW graphics that seem to frequently accompany mixes I enjoy.
youtube-dl
to the rescue
Luckily, at least as far as YouTube audio is concerned, there is plenty of free
software available to help with this! I like to fetch and process music from
YouTube using youtube-dl and
ffmpeg. Both are packaged and available in Debian if you
like to apt install
things:
Saving audio files from YouTube
Well, let's suppose you want to download some eurobeat. youtube-dl
can
help. The -x
flag tells youtube-dl
to skip downloading video and to only
fetch audio.
$ youtube-dl -x https://www.youtube.com/watch?v=8B4guKLlbVU
[youtube] 8B4guKLlbVU: Downloading webpage
[youtube] 8B4guKLlbVU: Downloading video info webpage
[youtube] 8B4guKLlbVU: Extracting video information
[youtube] 8B4guKLlbVU: Downloading js player vflGUPF-i
[download] Destination: SUPER EUROBEAT MIX-8B4guKLlbVU.webm
[download] 100% of 60.68MiB in 20:57
Deleting original file SUPER EUROBEAT MIX-8B4guKLlbVU.webm (pass -k to keep)
YouTube sometimes throttles connections to approximate real-time buffer rates,
so the download could take a while. If you need to interrupt the download for
some reason, you can use SIGINT
(Ctrl+C
) to stop it. If you run
youtube-dl
again, it's smart enough to resume the download where you left
off.
Once the download is complete, there's not much more to do. It will be saved with the appropriate file extension so you can determine what audio codec it uses. You might want to rename the file:
$ mv SUPER\ EUROBEAT\ MIX-8B4guKLlbVU.ogg super_eurobeat_mix.ogg
Now we can enjoy many plays of our super_eurobeat_mix.ogg
file!
🚗🎶
Re-encoding audio to another format
Suppose that I have a really old MP3 player I'd like to put this file on, and
it doesn't support the OGG Vorbis format. That's not a problem; we can use
ffmpeg
to re-encode the audio.
The -i
flag to ffmpeg
specifies an input file. -acodec mp3
says that we
want to use the mp3 codec to re-encode our audio. The last positional argument,
super_eurobeat_mix.mp3
, is the name of the file we want to output.
$ ffmpeg -i super_eurobeat_mix.ogg -acodec mp3 super_eurobeat_mix.mp3
ffmpeg version 3.4.2-1+b1 Copyright (c) 2000-2018 the FFmpeg developers
built with gcc 7 (Debian 7.3.0-4)
configuration: --prefix=/usr --extra-version=1+b1 --toolchain=hardened
--libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu
--enable-gpl --disable-stripping --enable-avresample --enable-avisynth
--enable-gnutls --enable-ladspa --enable-libass --enable-libbluray
--enable-libbs2b --enable-libcaca --enable-libcdio --enable-libflite
--enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme
--enable-libgsm --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg
--enable-libopenmpt --enable-libopus --enable-libpulse --enable-librubberband
--enable-librsvg --enable-libshine --enable-libsnappy --enable-libsoxr
--enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame
--enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp
--enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq
--enable-libzvbi --enable-omx --enable-openal --enable-opengl --enable-sdl2
--enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint
--enable-frei0r --enable-libopencv --enable-libx264 --enable-shared
libavutil 55. 78.100 / 55. 78.100
libavcodec 57.107.100 / 57.107.100
libavformat 57. 83.100 / 57. 83.100
libavdevice 57. 10.100 / 57. 10.100
libavfilter 6.107.100 / 6.107.100
libavresample 3. 7. 0 / 3. 7. 0
libswscale 4. 8.100 / 4. 8.100
libswresample 2. 9.100 / 2. 9.100
libpostproc 54. 7.100 / 54. 7.100
Input #0, ogg, from 'super_eurobeat_mix.ogg':
Duration: 01:06:35.57, start: 0.000000, bitrate: 124 kb/s
Stream #0:0(eng): Audio: vorbis, 44100 Hz, stereo, fltp, 128 kb/s
Metadata:
LANGUAGE : eng
ENCODER : Lavf57.83.100
Stream mapping:
Stream #0:0 -> #0:0 (vorbis (native) -> mp3 (libmp3lame))
Press [q] to stop, [?] for help
Output #0, mp3, to 'super_eurobeat_mix.mp3':
Metadata:
TSSE : Lavf57.83.100
Stream #0:0(eng): Audio: mp3 (libmp3lame), 44100 Hz, stereo, fltp
Metadata:
LANGUAGE : eng
encoder : Lavc57.107.100 libmp3lame
size= 62432kB time=01:06:35.58 bitrate= 128.0kbits/s speed=22.4x
video:0kB audio:62431kB subtitle:0kB other streams:0kB global headers:0kB
muxing overhead: 0.000396%
Voila! We now have a super_eurobeat_mix.mp3
file we can copy to our janky old
MP3 player.
Extracting audio from an existing video file
Sometimes I accidentally forget to pass the -x
flag to youtube-dl
,
and get a video file instead of an audio track. Oops.
But that's okay! Extracting the audio track from the video file with ffmpeg
is just a couple of commands away.
First, we should determine the encoding of the audio track. The combined video
file is a .webm file, but we can peek inside using ffmpeg
.
$ ffmpeg -i SUPER\ EUROBEAT\ MIX-8B4guKLlbVU.webm
ffmpeg version 3.4.2-1+b1 Copyright (c) 2000-2018 the FFmpeg developers
built with gcc 7 (Debian 7.3.0-4)
configuration: --prefix=/usr --extra-version=1+b1 --toolchain=hardened
--libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu
--enable-gpl --disable-stripping --enable-avresample --enable-avisynth
--enable-gnutls --enable-ladspa --enable-libass --enable-libbluray
--enable-libbs2b --enable-libcaca --enable-libcdio --enable-libflite
--enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme
--enable-libgsm --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg
--enable-libopenmpt --enable-libopus --enable-libpulse --enable-librubberband
--enable-librsvg --enable-libshine --enable-libsnappy --enable-libsoxr
--enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame
--enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp
--enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq
--enable-libzvbi --enable-omx --enable-openal --enable-opengl --enable-sdl2
--enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint
--enable-frei0r --enable-libopencv --enable-libx264 --enable-shared
libavutil 55. 78.100 / 55. 78.100
libavcodec 57.107.100 / 57.107.100
libavformat 57. 83.100 / 57. 83.100
libavdevice 57. 10.100 / 57. 10.100
libavfilter 6.107.100 / 6.107.100
libavresample 3. 7. 0 / 3. 7. 0
libswscale 4. 8.100 / 4. 8.100
libswresample 2. 9.100 / 2. 9.100
libpostproc 54. 7.100 / 54. 7.100
Input #0, matroska,webm, from 'SUPER EUROBEAT MIX-8B4guKLlbVU.webm':
Metadata:
ENCODER : Lavf57.83.100
Duration: 01:06:35.57, start: 0.000000, bitrate: 490 kb/s
Stream #0:0(eng): Video: vp9 (Profile 0), yuv420p(tv,
bt709/unknown/unknown), 1920x1080, SAR 1:1 DAR 16:9, 29.97 fps, 29.97 tbr, 1k
tbn, 1k tbc (default)
Metadata:
DURATION : 01:06:35.558000000
Stream #0:1(eng): Audio: vorbis, 44100 Hz, stereo, fltp (default)
Metadata:
DURATION : 01:06:35.572000000
At least one output file must be specified
The important line is here:
Stream #0:1(eng): Audio: vorbis, 44100 Hz, stereo, fltp (default)
The audio uses the "vorbis" codec. Hence, we should probably use the .ogg extension for our output file, to ensure we specify a compatible audio container format. If it were mp3-encoded, we'd use .mp3, and so on.
Let's extract the audio track from our video file. We need a couple new flags
for ffmpeg
. The first is -vn
, which tells ffmpeg
to not include a video
track. The second is -acodec copy
, which says we want to copy the existing
audio track, rather than re-encode it.
$ ffmpeg -i SUPER\ EUROBEAT\ MIX-8B4guKLlbVU.webm -vn -acodec copy super_eurobeat_mix.ogg
ffmpeg version 3.4.2-1+b1 Copyright (c) 2000-2018 the FFmpeg developers
built with gcc 7 (Debian 7.3.0-4)
configuration: --prefix=/usr --extra-version=1+b1 --toolchain=hardened
--libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu
--enable-gpl --disable-stripping --enable-avresample --enable-avisynth
--enable-gnutls --enable-ladspa --enable-libass --enable-libbluray
--enable-libbs2b --enable-libcaca --enable-libcdio --enable-libflite
--enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme
--enable-libgsm --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg
--enable-libopenmpt --enable-libopus --enable-libpulse --enable-librubberband
--enable-librsvg --enable-libshine --enable-libsnappy --enable-libsoxr
--enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame
--enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp
--enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq
--enable-libzvbi --enable-omx --enable-openal --enable-opengl --enable-sdl2
--enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint
--enable-frei0r --enable-libopencv --enable-libx264 --enable-shared
libavutil 55. 78.100 / 55. 78.100
libavcodec 57.107.100 / 57.107.100
libavformat 57. 83.100 / 57. 83.100
libavdevice 57. 10.100 / 57. 10.100
libavfilter 6.107.100 / 6.107.100
libavresample 3. 7. 0 / 3. 7. 0
libswscale 4. 8.100 / 4. 8.100
libswresample 2. 9.100 / 2. 9.100
libpostproc 54. 7.100 / 54. 7.100
Input #0, matroska,webm, from 'SUPER EUROBEAT MIX-8B4guKLlbVU.webm':
Metadata:
ENCODER : Lavf57.83.100
Duration: 01:06:35.57, start: 0.000000, bitrate: 490 kb/s
Stream #0:0(eng): Video: vp9 (Profile 0), yuv420p(tv,
bt709/unknown/unknown), 1920x1080, SAR 1:1 DAR 16:9, 29.97 fps, 29.97 tbr, 1k
tbn, 1k tbc (default)
Metadata:
DURATION : 01:06:35.558000000
Stream #0:1(eng): Audio: vorbis, 44100 Hz, stereo, fltp (default)
Metadata:
DURATION : 01:06:35.572000000
Output #0, ogg, to 'super_eurobeat_mix.ogg':
Metadata:
encoder : Lavf57.83.100
Stream #0:0(eng): Audio: vorbis, 44100 Hz, stereo, fltp (default)
Metadata:
DURATION : 01:06:35.572000000
encoder : Lavf57.83.100
Stream mapping:
Stream #0:1 -> #0:0 (copy)
Press [q] to stop, [?] for help
size= 60863kB time=01:06:35.54 bitrate= 124.8kbits/s speed=1.03e+03x
video:0kB audio:60330kB subtitle:0kB other streams:0kB global headers:4kB
muxing overhead: 0.884396%
We've successfully extracted super_eurobeat_mix.ogg
from our video file! Go
us!
Happy listening, and drive safely while you eurobeat. 🎵