如何强制 youtube-dl 将 Opus 编码的音频保存为 *.opus 文件

如何强制 youtube-dl 将 Opus 编码的音频保存为 *.opus 文件

我只想下载音频和视频流这个视频。(警告:前方有母亲的侮辱)我总是被这样的错误所禁止:

[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

为什么会发生这种情况?

因为 youtube-dl 下载了 Opus 音频或 VP9 视频后,它都会保存为 *.webm。

对此,我的第一个解决方法是将它们下载到其他目录,但对我来说这不是很有效。

那么我如何强制将 Opus 音频写为 *.opus 而不是 *.webm

补充说明:为什么我喜欢在 YouTube 上下载 VP9/Opus 格式,然后在 ffmpeg 上合并?VP9/Opus 比 H264/AAC 更好。

答案1

如果您希望同时保留音频文件和视频文件,请使用 -k 作为参数之一。例如:youtube-dl -k youtube.com/watch/somevideo如果您希望将音频文件保存为 .opus,请使用youtube-dl --audio-format opus youtube.com/watch/somevideo

一些额外的注意事项:
如果您想获得最佳音频,您可以使用它,youtube-dl --audio-quality 0 youtube.com/watch/somevid如果您想要获得最佳音频质量并youtube-dl -x youtube.com/watch/somevid 直接提取音频。如果您想了解有关所有这些内容的更多信息,只需使用youtube-dl -h它,它会为您提供帮助消息,您阅读的越多,它们就越不令人困惑。

答案2

--audio-format opus总是转换为 opus,无论下载文件的格式如何。所以,这通常不是你想要的。我编写了一个 python 脚本来解决这个问题。它是假设你只需要音频而编写的。它运行youtube-dl -if bestaudio <url>,然后如果任何下载的文件是 .webm,它会假定它是 opus 并使用 ffmpeg 将无损容器转换为 .opus。(用于-i下载整个播放列表。播放列表中经常会有一些由于某种原因无法下载。)

#!/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, '.')

编辑:我现在明白了,我误解了你的问题。避免 youtube-dl 运行之间发生文件名冲突的最佳方法是更改​​输出文件名模板。--output未指定 if 的默认为。您应该对音频采集和视频采集%(title)s-%(id)s.%(ext)s执行。有关更多信息,请参阅。您甚至可以完全删除 etc. 并只说etc. 以使脚本的 ffmpeg 阶段更容易找到源文件。--output %(title)s-%(id)s-audio.%(ext)s--output %(title)s-%(id)s-video.%(ext)sOUTPUT TEMPLATEman youtube-dl%(title)--output audio.webm

相关内容