ffmpeg 输出文件小于输入文件

ffmpeg output file smaller than input file

我正在使用 ffmpeg 在 Python 脚本中将视频旋转 90 或 180 度。它很好用。但是,我很好奇为什么输出文件的字节数会比输入文件少。

以下是我使用的命令:

180度:

ffmpeg -i ./input.mp4 -preset veryslow -vf "transpose=2,transpose=2,format=yuv420p" -metadata:s:v rotate=0 -codec:v libx264 -codec:a copy ./output.mp4

90度:

ffmpeg -i ./input.mp4 -vf "transpose=2" ./output.mp4

例如,GoPro Hero 3 MP4 文件最初为 2.0 GB。生成的输出文件为 480.9 MB。另一个 GoPro 文件是 2.0,其生成的文件是 671.5 MB。这可能是因为 GoPro 文件是 2.0 但包含空 space,有点像某些 NTFS 文件系统如何制作最小的 4k 文件,即使其中的字节较少?

如果这不是 GoPro Hero 3,我如何将文件旋转 90 或 180 度但确保输出文件大小相同?或者,是否会丢失数据?数据丢失是否与格式有关?

请注意,视频的质量似乎没有损坏,这很好。所以,我有兴趣了解更多关于为什么会发生这种情况,然后我可以阅读与此相关的 ffmpeg 文档部分。

谢谢!

从一开始就忽略比特率

ffmpeg 将输入完全解码为未压缩的原始视频和音频(stream copying – more about that below). The input format or bitrate does not matter: it does this for all formats. The encoder then works from these raw, decoded frames. See diagram.

时除外

H.264 与 H.264

您的输入和输出均为 H.264。 H.264 等格式由编码器创建。任何人都可以制作编码器。然而,并非所有编码器都是平等的。给定相同的输入,一个 H.264 编码器的输出可能与另一个 H.264 编码器的输出具有相同的质量,但比特率可能小几倍。

GoPro H.264 编码器专为在硬件有限的平台上工作而设计。这意味着为了速度和质量牺牲了比特率(文件大小)。 x264 是终极的 H.264 编码器:没有什么能比得上它的质量比特率。

旋转而不重新编码

您可以 stream copy(重新混合)并同时旋转。旋转由 metadata/sidedata:

处理
ffmpeg -i input.mp4 -metadata:s:v rotate=90 -c copy output.mp4

缺点是您的 player/device 可能会忽略旋转,因此您可能不得不 physically rotate with filters 这需要重新编码,因此无法使用流复制。

我曾经遇到过同样的旋转问题...

我通过 "resetting" 旋转来修复它...

ffmpeg ...... -metadata:s:v rotate="0" ......