减小相同格式的视频大小并减小帧大小
Posted
技术标签:
【中文标题】减小相同格式的视频大小并减小帧大小【英文标题】:Reducing video size with same format and reducing frame size 【发布时间】:2011-05-28 06:29:53 【问题描述】:这个问题可能很基础
有没有办法减少有损压缩(WMV、MPEG)格式的帧大小/速率,以获得具有相同格式的更小、更小尺寸的视频。
是否有任何开源或专有 api 用于此?
【问题讨论】:
【参考方案1】:ffmpeg 提供此功能。您需要做的就是运行类似
ffmpeg -i <inputfilename> -s 640x480 -b 512k -vcodec mpeg1video -acodec copy <outputfilename>
对于较新版本的 ffmpeg,您需要将 -b
更改为 -b:v
:
ffmpeg -i <inputfilename> -s 640x480 -b:v 512k -vcodec mpeg1video -acodec copy <outputfilename>
使用 MPEG 1 视频编解码器将输入视频文件转换为大小为 640 x 480 和比特率为 512 千比特/秒的视频,并仅复制原始音频流。当然,您可以插入您需要的任何值,并使用大小和比特率来实现您正在寻找的质量/大小权衡。 documentation
中还描述了许多其他选项运行 ffmpeg -formats
或 ffmpeg -codecs
以获取所有可用格式和编解码器的列表。如果您不必为最终输出指定特定的编解码器,则可以使用 H.264 等最先进的编解码器以最小的质量损失实现更好的压缩比。
【讨论】:
-b 需要为 -b:v 用于 vid 比特率 @MrAH,感谢您的更新。自从我发布此内容以来,界面似乎发生了变化。以前视频码率是-b
,音频码率是-ab
,现在改成-b:[stream specifier]
。
命令有点不完整。缺少您还需要输入输出文件的名称:ffmpeg -i <inputfilename> -s 640x480 -b 512k -vcodec mpeg1video -acodec copy <outputfilename>
@JasonB 嘿,伙计,这太棒了。你知道如何使用 NodeJS 做到这一点吗?
@JasonB 我有一个 9MB 的视频,当我使用你的代码时,它的大小增加到 16mb 请帮助【参考方案2】:
如果要保持相同的屏幕尺寸,可以考虑使用 crf 因子:https://trac.ffmpeg.org/wiki/Encode/H.264
这是对我有用的命令:(在 mac 上,您需要添加 -strict -2
才能使用 aac 音频编解码器。
ffmpeg -i input.mp4 -c:v libx264 -crf 24 -b:v 1M -c:a aac output.mp4
【讨论】:
好建议,除了不要使用 FFmpeg 的内置 AAC 编码器:这听起来像废话。如果你想要 AAC,至少使用 libfdk-aac,或者现在更喜欢 Opus 音频(完全免费/开源/不受专利保护,并且可以与最好的 AAC 编码器竞争。比最差的 AAC 编码器好得多,比如 FFmpeg 的-c:a aac
)。使用-c:a libopus -b:a 64k
或类似的东西。 (但请注意,MP4 容器不能保存 Opus 音频。)
-b:v 1M
覆盖 -crf
。不要同时使用两者。只需使用 CRF。【参考方案3】:
除了选择固定比特率,使用 H.264 编解码器,您还可以选择不同的预设,如 https://trac.ffmpeg.org/wiki/x264EncodingGuide 所述。我还发现Video encoder comparison at KeyJ's blog (archived version) 很有趣,它将 H.264 与 Theora 等进行了比较。
以下是我尝试过的各种选项的比较。录制的视频最初大小为 673M,在 iPad 上使用RecordMyScreen 拍摄。它的持续时间约为 20 分钟,分辨率为 1024x768(视频的一半是空白的,所以我将其裁剪为 768x768)。为了减小尺寸,我将分辨率降低到 480x480。没有音频。
结果,以相同的 1024x768 作为基础(并应用裁剪、缩放和a filter):
无特殊选项时:95M(编码时间:1m19s)。 仅添加-b 512k
,大小降至77M(编码时间:1m17s)。
只有-preset veryslow
(没有-b
),变成了70M(编码时间:6m14s)
同时使用-b 512k
和-preset veryslow
,大小变为77M(比-b 512k
小100K)。
使用 -preset veryslow -crf 28
,我得到一个 39M 的文件,耗时 5 分 47 秒(对我来说没有视觉质量差异)。
N=1,因此对结果持保留态度并执行您自己的测试。
【讨论】:
没有任何速率选项,x264 默认为-crf 23
。但是,是的,对于 encode-once stream-many,你应该使用类似-preset veryslow
的东西。毫不奇怪,这在屏幕捕获上 非常 做得很好。通常你不需要缩小比例,除非你的目标是非常低比特率;将细节分散在更多像素上往往有助于编解码器更好地保持细节。锐利边缘周围的伪影往往是固定数量的像素,因此更高的 rez 会使伪影更小。 (尽管每像素更少的比特意味着更多的量化,但其中一些是模糊而不是伪影。)【参考方案4】:
有一个适用于 Mac 和 Windows 的应用程序调用 Handbrake,我知道这不是命令行的东西,而是用于快速打开文件 - 选择输出文件格式和粗略的输出大小,同时保留大部分关于视频的好东西这很好,它只是 ffmpeg 最好的图形视图...... 它确实支持那些顽固的文本用户的命令行输入.. https://handbrake.fr/downloads.php
【讨论】:
支持命令行handbrake.fr/docs/en/latest/cli/cli-options.html【参考方案5】:我发现自己最近也想这样做,所以我创建了一个名为 Shrinkwrap 的工具,它使用 FFmpeg 对视频进行转码,同时尽可能多地保留原始元数据(包括文件修改时间戳)。
您可以将其作为 docker 容器运行:
docker run -v /path/to/your/videos:/vids bennetimo/shrinkwrap \
--input-extension mp4 --ffmpeg-opts crf=22,preset=fast /vids
地点:
/path/to/your/videos/ 是您想要播放视频的位置 转换 --input-extension 是你要处理的视频类型,这里是.mp4 --ffmpeg-opts 是您要用于自定义转码的任意 FFmpeg 选项然后它会递归查找所有匹配扩展名的视频文件,并将它们全部转码为具有-tc
后缀的同名文件。
有关 GoPro 等的更多配置选项、预设,请参阅readme。
希望这对某人有所帮助!
【讨论】:
【参考方案6】:ffmpeg -i <input.mp4> -b:v 2048k -s 1000x600 -fs 2048k -vcodec mpeg4 -acodec copy <output.mp4>
-i 输入文件
-b:v 输出视频的视频比特率,以千字节为单位(你必须尝试)
-s 输出视频的尺寸
-fs FILESIZE 以千字节为单位的输出视频
-vcodec 视频编解码器(使用ffmpeg -codecs
列出所有可用的编解码器)
【讨论】:
-fs
使 FFmpeg 在达到该文件大小后停止编码。它不是用于速率计算的 target 文件大小。如果-b:v
正确,则文件的大小无论如何都会正确,如果错误,文件会变小或被截断。以上是关于减小相同格式的视频大小并减小帧大小的主要内容,如果未能解决你的问题,请参考以下文章
如何在android中以编程方式上传到服务器之前减小视频的大小[关闭]
MediaMuxer 视频文件大小减小(重新压缩,降低分辨率)