使用 ffmpeg 时,编解码器参数被文件扩展名覆盖

使用 ffmpeg 时,编解码器参数被文件扩展名覆盖

我正在使用 ffmpeg 转码一些视频文件,在本文中我们将使用 test.mkv。test.mkv 在索引 2 处有一个 AAC 7.1 音轨。我想保留该音轨,但也添加 AAC 立体声版本。

ffmpeg -y -i test.mkv \
    -map 0 \
    -map 0:2 -codec:2 copy \
    -map 0:2 -codec:3 libfdk_aac -ac 2 \
    out.mkv

但是,我注意到立体声音轨被转换为 vorbis。这很奇怪,因为我-map 0:2 -codec:3 libfdk_aac -ac 2在命令中指定了。所以我做了一些测试,尝试提取音轨:

ffmpeg -y -i test.mkv \
    -map 0:2 -codec:2 libfdk_aac \ 
    test.aac

#-> important parts of the output

[aac @ 0x55761a165c40] Assuming an incorrectly encoded 7.1 channel layout instead of a spec compliant 7.1(wide) layout, use -strict 1 to decode according to the specification instead.
Stream #0:2 -> #0:0 (aac (native) -> aac (native))
Stream #0:0(eng): Audio: aac (LC), 48000 Hz, 7.1, fltp, 469 kb/s (default)

这很奇怪,因为我指定 libfdk_aac 作为编码器(因为它比 aac 好得多),但它却显示[aac @ ...在输出中。因此,当我提取 aac 音轨时,它使用 aac,而当我将其转码到媒体文件中时,它使用 vorbis。全部不是 libfdk_aac。它似乎只是忽略了编解码器参数并自行决定将其转换为什么。

我使用 libfdk_aac 安装了 ffmpeg指南直接作为编辑出现在问题中。

我的目标是将所选的音轨转码为 aac。不是 vorbis,也不使用 aac 编码器;而是使用 libfdk_aac 编码器。


编辑:好的,我能够确定问题,尽管我还不知道如何修复它。请参阅以下示例:

#test.mkv contains opus audio track at index 1

ffmpeg -y -i test.mkv -map 0:1 -codec:1 aac output.flac
#output.flac's codec is flac and not aac

ffmpeg -y -i test.mkv -map 0:1 -codec:1 copy output.flac
#output.flac's codec is flac and not opus

ffmpeg -y -i test.mkv -map 0:1 -codec:1 aac output.mkv
#output.mkv's codec is vorbis and not aac

那么我们从这些结果中学到什么?ffmpeg 将编解码器设置为适合输出文件容器的任何内容。因此,当输出文件为 .flac 时,它会将编解码器设置为 flac,尽管我已将其设置为 aac。显然,当输出容器为 .mkv 时,ffmpeg 已决定 vorbis 是音频流的编解码器。基本上,ffmpeg 会监听输出文件的扩展名,而不是我使用 -codec 参数所说的内容。

这应该反过来;当没有为流提供编解码器时,使其适合输出容器,但如果为流提供了编解码器,则在该编解码器中对其进行转码,从而忽略输出文件的文件扩展名。

在这个问题的第一个例子中,我在文件内部创建了一个额外的立体声音轨,我将该立体声音轨的编解码器设置为 libfdk_aac,但输出容器是 .mkv,因此 ffmpeg 将其转码为 vorbis。

然而,既然我们知道了问题所在,那么该如何解决它呢?


编辑2:

好的,我知道问题是什么了。如果我的文件在索引 1 处只有一个音轨,则-map 0:1 -codec:a:0 aac无法工作。即使映射和编解码器都针对同一个流,编解码器部分也不会应用于之前映射一个参数的流。结论:引用流的方式必须在任何地方都相同。

相关内容