How to force youtube-dl to save Opus-encoded audio as *.opus files

10,675

Solution 1

If you are looking to keep both the audio file and the video file use -k as one of your arguments. Ex. : youtube-dl -k youtube.com/watch/somevideo if you want to save your audio file as .opus use youtube-dl --audio-format opus youtube.com/watch/somevideo

Some extra notes:
If you want to have the audio be the best you can get it use youtube-dl --audio-quality 0 youtube.com/watch/somevid if you want to have the best quality of audio and youtube-dl -x youtube.com/watch/somevid to extract the audio directly. If you want more info on all of this stuff just use youtube-dl -h it will give you the help message and the more you read the less confusing they get.

Solution 2

--audio-format opus always converts to opus, regardless the format of the downloaded file. So, that's typically not what you want. I wrote a python script to solve this problem. It was written assuming you only want the audio. It runs youtube-dl -if bestaudio <url>, then if any of the downloaded files are .webm, it assumes it's opus and uses ffmpeg to do a lossless container conversion to .opus. (The -i is for downloading whole playlists. There are often a few in the playlist that fail to download for whatever reason.)

#!/usr/bin/env python

# Youtube actually hosts audio-only opus tracks, but you can only get them
# in the webm container, which many music players, including quodlibet, don't
# know what to do with. This script downloads the track, then converts it with
# zero loss to the opus container using ffmpeg's `-acodec copy` feature.

from sys import *
from subprocess import call
from os.path import splitext
from os import remove, walk, listdir
from tempfile import TemporaryDirectory
from shutil import move

url = argv[1]

with TemporaryDirectory(prefix='yta-') as tempdir:
    call(['env', '-C', tempdir, 'youtube-dl', '-if', 'bestaudio', url])

    for tempdir, dirs, files in walk(tempdir):
        for fn in files:
            path = tempdir+'/'+fn
            name, ext = splitext(path)
            if ext == '.webm':
                if call([
                    'ffmpeg', '-hide_banner',
                    '-i', path,
                    '-acodec', 'copy',
                    name+'.opus'
                ]) == 0:
                    remove(path)

    for node in listdir(tempdir):
        move(tempdir+'/'+node, '.')

EDIT: I can see now, I misunderstood your question. The best way to avoid filename collisions between runs of youtube-dl is to change the output filename template. The default if --output is not specified is %(title)s-%(id)s.%(ext)s. What you should do is do --output %(title)s-%(id)s-audio.%(ext)s for the audio acquisition and --output %(title)s-%(id)s-video.%(ext)s for the video acquisition. See OUTPUT TEMPLATE in man youtube-dl for more. You can even nuke the %(title) etc. entirely and just say --output audio.webm etc. to make it easier for the ffmpeg stage of your script to find the source files.

Share:
10,675

Related videos on Youtube

CV01HatsuneASD
Author by

CV01HatsuneASD

In case you're wondering why Miku is messing around Stack Exchange, excuse me! For those I'm not Miku Hatsune, you big dummies! I only use her name as my Internet alias! Shitpost-grade user bio aside: I'm Daniel Nicolas. I'm 17 years old and I'm a computer programming student at the Arellano University – Elisa Esguerra Campus here in the Philippines. I like to play video games, listen to music, especially pop, EDM, vaporwave, and Vocaloid. I enjoy most of my free time watching YouTube videos, reading Reddit posts (not to mention being actively participating in discussions)

Updated on September 18, 2022

Comments

  • CV01HatsuneASD
    CV01HatsuneASD almost 2 years

    I just want to download both audio and video streams of this video. (WARNING: Maternal Insults ahead) I always barred by errors like this:

    [youtube] hcQlNng606I: Downloading webpage
    [youtube] hcQlNng606I: Downloading video info webpage
    [youtube] hcQlNng606I: Extracting video information
    [youtube] hcQlNng606I: Downloading MPD manifest
    [download] YO MAMA! Star Wars Jokes-hcQlNng606I.webm has already been downloaded
    [download] 100% of 4.78MiB
    

    Why this happens?

    Because after youtube-dl downloaded either the Opus audio or the VP9 video, it will be both saved as *.webm.

    My first workaround for this is to download them on other directory and it is not (for me) very efficient.

    So how do I force it to write Opus audio as *.opus instead of *.webm

    Additional notes: Why do I like to download VP9/Opus formats on YouTube and combine it later on ffmpeg? VP9/Opus are better than H264/AAC.

  • Simón
    Simón over 3 years
    Would you explain why did you chose to use those command-line arguments for youtube-dl and ffmpeg? What do each of them mean?
  • enigmaticPhysicist
    enigmaticPhysicist over 3 years
    -f bestaudio is for downloading the best quality, audio only. I already said why I included -i. As for ffmpeg, the banner in the output of each conversion is too noisy, so I added --hide_banner. -i specifies the input file. -acodec copy says do lossless conversions only, failing if this is impossible. The final option is the output file. See man ffmpeg and man youtube-dl for more.