使用相同格式减小视频大小以及减小帧大小

75

这个问题可能非常基础

有没有一种方法可以减小损失压缩格式(WMV,MPEG)的帧大小/率,以获得相同格式的更小、更低质量的视频。

是否有任何开源或专有的API可以做到这一点?

6个回答

95

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>

将输入视频文件转换为大小为640 x 480,比特率为512千位/秒的视频,使用MPEG 1视频编解码器并仅复制原始音频流。当然,您可以插入任何需要的值,并调整大小和比特率以实现您所寻找的质量/大小权衡。还有许多其他选项在文档中描述。
运行ffmpeg -formatsffmpeg -codecs以获取所有可用格式和编解码器的列表。如果您不必针对最终输出选择特定的编解码器,则可以使用先进的编解码器(如H.264)实现更好的压缩比和最小的质量损失。

8
“-b”需要改为“-b:v”,以表示视频比特率。 - Mr AH
4
@MrAH,谢谢您的更新。看起来自我发布这条信息以来,接口已经发生了变化。过去,视频比特率使用“-b”,音频比特率使用“-ab”,但现在变成了“-b:[流规范]”。请让我知道如果您需要更多帮助。 - Jason B
3
该命令略微不完整,缺少您还需要输入输出文件的名称:ffmpeg -i <inputfilename> -s 640x480 -b 512k -vcodec mpeg1video -acodec copy <outputfilename> - desmond13
@JasonB 嘿,伙计,这很棒。你知道如何使用NodeJS实现吗? - Chanaka De Silva
MPEG1是一种过时的编解码器,与x264或VP9相比不是一个好的推荐选择。通常情况下,通过质量目标获得更好的结果,而不是绝对比特率。例如,x264默认的“-crf 23”在各种分辨率和内容类型下都非常合理。 - Peter Cordes
显示剩余2条评论

41
如果您想保持相同的屏幕大小,可以考虑使用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音频。) - Peter Cordes
“-b:v 1M” 覆盖了 “-crf”。不要同时使用两者,只需使用 CRF。 - Peter Cordes

30

使用 H.264 编解码器时,您可以选择不同的预设而不是固定比特率,具体请参见https://trac.ffmpeg.org/wiki/x264EncodingGuide。我还发现KeyJ博客上的视频编码器比较存档版本)很有趣,它将 H.264 与 Theora 等进行了比较。

以下是我尝试的各种选项的比较。录制的视频最初大小为 673M,使用 RecordMyScreen 在 iPad 上拍摄。它的持续时间约为 20 分钟,分辨率为 1024x768(其中一半是空白的,因此我将其裁剪为 768x768)。为了减小文件大小,我将分辨率降低到了 480x480。没有音频。

将1024x768作为基础(并应用裁剪、缩放和一个过滤器),得到的结果如下:

  • 没有特殊选项:95M(编码时间:1m19s)。
  • 只添加-b 512k,大小降至77M(编码时间:1m17s)。
  • 仅使用-preset veryslow(没有-b),大小变为70M(编码时间:6m14s)。
  • 同时使用-b 512k-preset veryslow,大小为77M(比仅使用-b 512k小100K)。
  • 使用-preset veryslow -crf 28,我得到了一个39M的文件,花费了5m47s(对我来说没有视觉质量差异)。

N=1,因此请带着一份谨慎的心态进行测试,并进行自己的测试。


没有任何速率选项时,x264的默认值是-crf 23。但是,对于编码一次流多次使用,您应该使用类似-preset veryslow的东西。不出所料,这在屏幕捕获方面表现非常好。通常情况下,除非您的目标是非常低的比特率,否则您不需要缩小比例;将细节分散到更多像素上有助于编解码器保持更好的细节。锐利边缘周围的伪影往往是固定数量的像素,因此更高的分辨率会使伪影变小。(即使每像素的位数较少意味着更多的量化,其中一些是模糊而不是伪影。) - Peter Cordes

4

有一个名为Handbrake的应用程序适用于Mac和Windows系统。虽然它不是命令行工具,但可以快速打开文件、选择输出文件格式和大致输出大小,并保留视频的大部分优点。这是ffmpeg最好的图形化界面之一...... 对于那些喜欢使用命令行的用户,它也支持命令行输入。 https://handbrake.fr/downloads.php


它支持命令行 https://handbrake.fr/docs/en/latest/cli/cli-options.html - kiranr

4

最近我也有这个需要,所以我创建了一个名为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

希望这能帮到某人!


3
ffmpeg -i <input.mp4> -b:v 2048k -s 1000x600 -fs 2048k -vcodec mpeg4 -acodec copy <output.mp4>
  • -i 输入文件

  • -b:v 输出视频的视频比特率(以千字节为单位)(需要尝试)

  • -s 输出视频的尺寸

  • -fs 输出视频的文件大小(以千字节为单位)

  • -vcodec 视频编码器(使用 ffmpeg -codecs 列出所有可用的编码器)

  • -acodec 输出视频的音频编码器(仅复制音频流,不要更改)

1
-fs 选项可以让 FFmpeg 在达到指定文件大小后停止编码。它并不是用于速率计算的“目标”文件大小。如果你正确使用了 -b:v 选项,那么生成的文件大小就会是正确的;如果你使用不当,那么生成的文件可能会更小或被截断。 - Peter Cordes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接