FFMPEG 从 MP3 转换为 FLAC - 为什么文件这么大?

FFMPEG 从 MP3 转换为 FLAC - 为什么文件这么大?

因此,由于各种原因,我将 MP3 转换为 FLAC,方法如下:

ffmpeg -i x.mp3 -map 0 -map -0:v -compression_level 5 x.flac

x.mp3 为 21MB,生成的 x.flac 为 102MB

我可能错误地假设,FFMPEG 正在从 MP3 创建 PCM 流,然后对该流进行编码、压缩和容器化到 FLAC 文件中。

输入文件比特率为320kb/s,输出文件比特率为1558kb/s。

有人能解释一下为什么 FLAC 中的压缩算法不能更好地处理 MP3 解码后输入的 PCM(或其他格式)吗?还是我的命令行错了?

我进行的另一项测试如下:

文件 input.flac 为 24MB

ffmpeg -i input.flac output.mp3

文件 output.mp3 为 3.5MB

ffmpeg -I output.mp3 output2.flac

文件 output2.flac 为 41MB

谢谢

答案1

首先,我怀疑你误解了不同编解码器的用途。FLAC 的作用不是让音频“听起来”更好(尽管它可能听起来更好一点),而是用于存档音频。使用 FLAC,你可以反复解码和重新编码文件而不会损失任何质量。对于 mp3,如果你解码并重新编码几十次,最终结果将无法识别。将 mp3 编码为 FLAC 是没有意义的,因为它只会占用更多空间,而且听起来与 mp3 一模一样。

但要回答为什么:完整的答案非常复杂,需要了解信息理论。但我会尝试总结一下。

简短的回答:MP3 是有损的,而 flac 是无损的,这意味着 mp3 可以选择在数据中删除或插入信息,从而使压缩更有效率。FLAC 做不到这一点。

长答案:让我们使用英语作为压缩算法。遵循以下说明:

“将 1000000 个零写入文本文件”。

如果这样做,最终文件将约为 1Mb。但是使用英语,我能够将其描述(压缩)为一个简短的句子,如果写入文件则仅占用 32 个字节。让我们稍微改变一下这个句子。

“向文本文件中写入 500000 个零,然后写入一个 1,然后再写入 499999 个零”。

现在这个句子长得多(82 字节),并且生成的文件几乎完全相同,除了中间的一个值。中间的一个随机值使我们的句子(压缩数据)大了两倍多。您会看到,某事物越可预测,压缩效果就越好。数据的“可压缩性”取决于其“信息熵”或随机性。熵越高,压缩效果越差。压缩的极限是已知的,可以使用信息论来计算。

MP3 是有损的。这意味着它可以查看第二句话,并决定永远不会注意到文件中间的额外“1”,并将其更改为零,从而降低其熵,从而提高压缩率。但是现在 1 永远消失了,永远无法恢复。这个过程称为“量化”,这是 mp3 可以实现其压缩比的几个原因之一

但 mp3 也有相反的做法。由于 mp3 将数据转换为频域,并进行了心理声学优化,因此它在解码时实际上会增加 PCM 数据的熵。如果您随后将 PCM 用 FLAC 编码,FLAC 将保留增加的熵。

Flac 使用完全不同的压缩技术来确保熵被保留下来,而不会被量化。这意味着 flac 需要更多空间来编码文件。FLAC 不量化这一事实是其存在的首要原因,也是其主要特征。

答案2

默认情况下,最新版本的ffmpegmp3 解码为浮点格式;flac 编码线性 PCM。为了将浮点编码为 flac,ffmpeg 必须首先将浮点格式转换为整数格式。它选择有符号 32 位(这会导致文件不必要地大)。有两种方法可以获取 16 位输出:

a)使用输出16位的解码器:

ffmpeg -c:a mp3 -i x.mp3 x.flac

b) 明确转换为 16 位(也可以通过过滤器完成aformat):

ffmpeg -i x.mp3 -sample_fmt s16 x.flac

注意:这不会提高 mp3 音轨的质量 - 在您有机会重新翻录丢失的音轨之前,仅使用 mp3 更有意义。


ffmpeg 的 flac 编码器支持样本格式s16s32。有两个 mp3 解码器 - 一个输出浮点格式,另一个输出 16 位整数格式:

$ ffmpeg -h encoder=flac
    Supported sample formats: s16 s32

$ ffmpeg -codecs | grep -Fi mp3
 DEA.L. mp3    MP3 (MPEG audio layer 3) (decoders: mp3float mp3 ) (encoders: libmp3lame )

$ ffmpeg -h decoder=mp3float
    Supported sample formats: fltp flt

$ ffmpeg -h decoder=mp3
    Supported sample formats: s16p s16

相关内容