如何使用 ffmpeg 减小视频的大小?

xra*_*alf 562 compression ffmpeg video

如何ffmpeg通过降低质量来减小视频的大小(自然而然地尽可能减少,因为我需要它在没有太多可用空间的移动设备上运行)?

我忘了说当视频可以使用字幕(*.srt 或*.sub)时,我也想转换它们以适应转换后的视频文件的参数。

Vic*_*ani 803

这个答案是在 2009 年写的。 自 2013 年以来,一种比 H.264 更好的视频格式被广泛使用,即 H.265(更好的是它在相同质量下压缩得更多,或者在相同大小下提供更高质量)。要使用它,请用 libx265 替换 libx264 编解码器,并通过增加 CRF 值进一步推动压缩杆——例如添加 4 或 6,因为 H.265 的合理范围可能是 24 到 30。请注意较低的CRF 值对应于更高的比特率,从而产生更高质量的视频。

 ffmpeg -i input.mp4 -vcodec libx265 -crf 28 output.mp4
Run Code Online (Sandbox Code Playgroud)

要查看使用较旧的 H.264 格式应用此技术,请参阅此答案,为方便起见,引用如下:

通过将目标大小(以位为单位)除以视频长度(以秒为单位)来计算所需的比特率。例如,对于1?GB的目标大小(千兆字节,这是8个千兆比特)和视频(2 2 H 5 46?分40?S)的10?000秒,使用的800?000位的比特率/秒(800?kbit/s):

ffmpeg -i input.mp4 -b 800k output.mp4
Run Code Online (Sandbox Code Playgroud)

可能值得考虑的其他选项是设置Constant Rate Factor,这会降低平均比特率,但保持更好的质量。在 18 到 24 之间改变 CRF - 越低,比特率越高。

ffmpeg -i input.mp4 -vcodec libx264 -crf 20 output.mp4
Run Code Online (Sandbox Code Playgroud)

  • 第二个命令,使用 `-crf 24` 拍摄了我拥有的 255.3MB 视频并将其减少到 72.7MB,而没有明显降低质量。点个赞吧! (78认同)
  • 使用`ffmpeg -i input.avi -vcodec libx264 -crf 24 output.avi`。它将 100mb 的视频减少到 9mb。视频质量几乎没有变化。谢谢! (25认同)
  • 可能需要注意的是,您现在可以使用 `libx265` 来进一步缩小尺寸。 (24认同)
  • 令人印象深刻地将 ~2G 的视频减少到 14MB,看起来仍然不错,这是第一个搜索结果,正是我要找的结果,谢谢! (19认同)
  • 答案很好,但我想指出另一个细节:某些设备(例如旧平板电脑、树莓派 1)可能不仅内存不足,而且处理能力也很低。在这种情况下,您可能希望通过“-profile:v 基线”限制配置文件来限制解压的复杂性(如 https://superuser.com/questions/371460/command-encoding-h264-baseline- profile-level-1-with-ffmpeg-and-libx264)。此外`-pix_fmt yuv420p` 有利于兼容性,`-movflags +faststart` 允许提前启动。 (13认同)
  • 如果您打算在 html5 视频上使用 libx265,请不要使用它,请参阅 https://gist.github.com/Vestride/278e13915894821e1d6f#support (6认同)
  • 第一种方法,即实现给定的_恒定比特率_,是**不鼓励的**,因为由于其刚性(比特率绝不能超过阈值),它会导致质量大大降低。为了控制输出的大小(而不是质量),推荐的方法是使用两次传递来实现给定的_平均比特率_,如本答案<https://unix.stackexchange.com/a/289322>所述。这是更好的,因为第一遍允许编解码器根据需要分配比特使用,即它可以在简单帧上节省比特,并有更多可用比特用于要求更高的帧。 (2认同)
  • 提醒所有支持此答案的人也要支持引用此答案的答案。必须赞成OP。 (2认同)
  • 这是一篇关于 CRF(恒定速率因子)及其含义的写得非常好且内容丰富的文章:https://slhck.info/video/2017/02/24/crf-guide.html#:~:text=The %20Constant%20Rate%20Factor%20(CRF,expense%20of%20higher%20file%20sizes. (2认同)
  • 使用 libx265 后无法在 Chrome 或 QuickTime Player 中打开视频。libx264 生成的文件大 15%,但兼容性更好。 (2认同)
  • 这个答案可能还应该提到,并非所有设备都支持 H.265 硬件解码(或编码!),并且编码过程通常比 H.264 慢得多。 (2认同)
  • 对于 @arka-prava-basu 和 @shimon-s ,添加 `-tag:v hvc1` 使结果与 Quicktime 兼容,而不改变文件大小! (2认同)

geo*_*sey 134

您提到想要减小文件大小以在移动设备上容纳更多视频,这也是我的用例。这里的所有答案都是为了降低压缩质量,但没有人提到减少视频帧大小。由于要编码的像素较少,因此速度要快得多,取决于您的来源和分辨率的降低量,速度最高可达数倍。此外,文件大小可以显着减小。

缺点是您也会损失大量质量,因为较少的像素意味着较少的图像细节。但是当转换为小型设备时,这可能是可以接受的。

有关更多信息,请参阅有关缩放的 ffmpeg 文档。

ffmpeg -i input.mkv -vf "scale=iw/2:ih/2" -c:v libx265 -crf 28 half_the_frame_size.mkv
ffmpeg -i input.mkv -vf "scale=iw/3:ih/3" -c:v libx265 -crf 28 a_third_the_frame_size.mkv
ffmpeg -i input.mkv -vf "scale=iw/4:ih/4" -c:v libx265 -crf 28 a_fourth_the_frame_size.mkv
Run Code Online (Sandbox Code Playgroud)

请注意,更改分辨率始终需要重新编码,因此其他答案的所有来龙去脉也适用于此。

  • 这个答案被低估了。它显着降低了编码的大小和速度。谢谢! (9认同)
  • ...并且显着降低视频质量,即使使用 /2 也是如此。 (5认同)

小智 88

我测试了这个问题的大多数其他建议答案。测试数据结论如下。这些是我测试过的建议答案:

(BR) 修改比特率,使用:

ffmpeg -i $infile -b $bitrate $newoutfile 
Run Code Online (Sandbox Code Playgroud)

(CR) 使用以下方法改变恒定速率因子:

ffmpeg -i $infile -vcodec libx264 -crf 23 $outfile
Run Code Online (Sandbox Code Playgroud)

(SZ) 使用以下方法更改视频屏幕大小(例如,更改为其像素大小的一半):

ffmpeg -i $infile -vf "scale=iw/2:ih/2" $outfile
Run Code Online (Sandbox Code Playgroud)

(BL) 将 H.264 配置文件更改为“基线”,使用:

ffmpeg -i $infile -profile:v baseline $outfile
Run Code Online (Sandbox Code Playgroud)

(DF) 使用默认的 ffmpeg 处理,使用:

ffmpeg -i $infile $outfile
Run Code Online (Sandbox Code Playgroud)

数据

  • "size" - 转换后视频相对于原始视频的像素大小百分比。
  • “比特率” - 原始和转换视频的比特率。
  • “定义” - 视频的像素大小。
  • “转换” - 以秒为单位转换视频的时间。

我使用建议的方法计算了 (BL) 的目标比特率。

=== 文件 A - Node 如何帮助推进 Angular-Fnbixa7Ts6M.mkv ===

            original    BR         CR         SZ         BL         DF
            --------    ---        --         --         --         --
size        64152 kb    214%       76%        40%        83%        76%
bitrate     411 kb/s    883        313        165        342        313
definition  1920x1080   1920x1080  1920x1080  960x540    1920x1080  1920x1080
convert     --          648        509        225        427        510
Run Code Online (Sandbox Code Playgroud)

=== 文件 B - 使用 GraphQL 和 Angular _ 作者 - Lee Costello-OGyFxqt5INw.mkv ===

            original    BR         CR         SZ         BL         DF
            --------    ---        --         --         --         --
size        410301 kb   33%        109%       28%        143%       109%
bitrate     2687 kb/s   880        2920       764        3843       2920
definition  3840x2160   3840x2160  3840x2160  1920x1080  3840x2160  3840x2160   
convert     --           2307       3188       1116       2646       3278
Run Code Online (Sandbox Code Playgroud)

结论

  • (SZ) 方法绝对是最快的方法。它快了 2 到 4 倍。这对于高清视频来说可能是一个很大的问题,因为所有其他方法的转换时间都比视频的实际长度要长!例如,(CR) 方法需要 53 分钟才能转换 21 分钟的视频。

  • 如果视频的清晰度大于将显示它的屏幕的清晰度,则 (SZ) 方法绝对是最好的方法。例如,如果您的手机只能显示 1080p 图片,那么向其发送 3840x2160 视频只是浪费。最好将其大小减半至 1080p。

  • 一些建议的答案实际上增加了某些视频的大小。例如,(BR) 方法使 1080p 样本的大小增加了一倍多。然而,它确实使 2160p 尺寸缩小了三分之一。对于高清样本,(CR)、(BL)和(DF)方法都增加了视频的大小。

正确(或最佳)答案

最好先将分辨率降低到目标显示器支持的最大值。

如果您想进一步减小文件大小,这将取决于个人选择。您可以减少信息内容或增加压缩。

  • 如果这不是您关心的问题,您可以进一步降低分辨率。

  • 如果视频不包含快速动作场景,您可能需要降低帧速率。

  • 如果您有一个强大的处理器并且空间是唯一的问题,您可以提高压缩率。

  • 比特率是多种因素的组合。所以只是告诉 ffmpeg 降低比特率可能不会给你想要的结果。

  • 另一种降低信息含量的方法是降低颜色深度。尚未讨论如何做到这一点。

  • **(3)** BR 字面上应用恒定比特率,因此结果比特率显然是您要求的(大约)。如果您要求两倍于输入,那么输出是两倍就不足为奇了![另外,请注意,不鼓励编码为恒定比特率,您应该进行 2 次平均比特率编码,请参阅其他答案。] **(4)** CR 提供了一个有趣的数据点,但仍然仅限于一个任意的CRF 的值。同样的缺点是,如果您选择的目标质量高于输入的质量,那么您将获得更大的输出。 (2认同)
  • 最后要注意的是,现在没有充分的理由不喜欢更好和更新的 H.265 格式(甚至 AV1,如果你足够耐心)而不是 H.264。 (2认同)

Ski*_*rou 63

请注意,在没有选项的情况下运行时似乎ffmpeg 已经执行了一些优化,因此在尝试使用您不理解的设置或决定明确丢失信息之前,请尝试默认转换:

ffmpeg -i input.mp4 output.mp4
Run Code Online (Sandbox Code Playgroud)

在我的例子中,它降低了视频和音频的比特率(您可以通过运行来检查和比较输入和输出文件ffprobe),将 700?Mb 的视频转换为 60?Mb 的看起来质量相似的视频。

  • 虽然这可能有效,但值得注意的是,它是不可持续的。将来,FFMPEG 默认值可能会更改并产生不同的结果。也许,默认设置会让更改变得更好,但在我看来,这是有风险的,因为您依赖开发人员来优化您的文件 - 他们是否创建较小的文件,而不担心质量,或者他们是否试图在两者之间找到平衡? (4认同)
  • 就我而言,该命令极大地降低了视频比特率(没有明显的质量下降),但稍微增加了音频比特率(这显然不好)。要保留原始音轨,请运行“ffmpeg -i input.mp4 -acodec copy output.mp4” (4认同)
  • 用这个从 4Gb 到 2Gb,谢谢!! (3认同)
  • (从 10Mo 到 1.2Mb,ffmpeg 自动将我在 [VP8](https://fr.wikipedia.org/wiki/VP8) 中的视频转换为 [VP9](https://fr.wikipedia.org/wiki/副总裁9)) (3认同)
  • @pjtnt11 很高兴知道它并不“总是”高效,感谢您的报告。 (3认同)
  • 这将我的视频大小从 10.8MB 增加到 14MB (2认同)
  • 迄今为止最简单的答案。在 18 秒 4K 视频上使用它,结果是大小减少了 30%,而质量没有任何明显下降。 (2认同)
  • 对于@JustCarty 的观点,最好知道这些默认值是什么。 (2认同)
  • ffmpeg 版本 4.2.7-0ubuntu0.1 具有默认值`选项:cabac=1 ref=3 deblock=1:0:0 analysis=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mix_ref=1 me_range =16 chroma_me=1 网格=1 8x8dct=1 cqm=0 死区=21,11 fast_pskip=1 chroma_qp_offset=-2 线程=12 Lookahead_threads=2 sliced_threads=0 nr=0 抽取=1 交错=0 Bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 权重b=1 open_gop=0 权重p=2 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=crf mbtree=1 crf=23.0 qcomp= 0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00` (2认同)

Tom*_*lly 57

除非您正在寻找特定的比特率,否则我建议您使用该-crf选项。

这最常用于本文x264所述的编码。

短期:恒定速率因子23(CRF)将制作DVD画质电影(700MB〜 - 1GB),降低CRF值会更高品质(大文件)。

链接文章中的一个示例:

ffmpeg -i input.mp4 -c:v libx265 -crf 28 output.mp4
Run Code Online (Sandbox Code Playgroud)

  • 这似乎不适用于网络视频/html5 视频。 (2认同)
  • 其他人已经提到 libx265 对浏览器的支持有限。请参阅https://gist.github.com/Vestride/278e13915894821e1d6f#support (2认同)

Jak*_*ger 11

我将 40 分钟的高清视频演示从 505MB 压缩到 183MB
这就像从 100MB → 36MB。
原始视频是高清的,输出几乎为零,显着差异。
这是一个视频文件,“我想保留,但高清过分了。”
这是我出于以下原因使用的命令:

ffmpeg -n -loglevel error -i inputfile.mp4 -vcodec libx264 -crf 28 -preset faster -tune film outputfilename.mp4

  • -n避免覆盖输出文件(测试然后批处理更安全)
  • -loglevel error : 显示错误并隐藏进度的行和行
  • -i inputfile.mp4 : 输入文件名
  • -vcodec libx264:从上面最佳答案刷卡
  • -crf 28:轻微明显的区别单通压缩(“0 =无损耗的,23 =缺省情况下,51 =最差;主观理智的范围是17- 28REF文档
  • -preset faster:看起来比“中等”参考文档的默认编码时间快 2 倍
  • -tune film: 指定输入是 HQ 视频(其他选项包括“卡通”、“静止图像”..)参考文档
  • outputfilename.mp4 : 输出文件名

对于视频文件的目录:

for i in *.{avi,flv,m4v,mov,wmv,mp4,MP4,TS,mkv}; do ffmpeg -n -loglevel error -i "$i" -vcodec libx264 -crf 28 -preset faster -tune film "cc${i}"; done

问题:

  • 在命令中没有所有扩展名的情况下收集“所有视频文件”的更简洁的方法
  • 一种更简洁的方式来输出没有“cc”前缀的文件名,并且能够在删除之前确认视频
  • .webm文件不适用于该命令。不得不换"cc${i}""${i%.*}.mp4"

Handbrake 是一种带有 UI 的开源替代方案


小智 7

如果您的目标是特定的文件大小(或比特率)而不是特定的质量,则需要使用两遍平均比特率编码(或简称“2 遍 ABR”)以使视频适合此大小不会大幅降低质量。

简而言之,对于相同的比特率,它比单程比特率编码获得更好的质量(如本答案所示),因为第一遍允许编解码器根据需要分配位使用量,它可以在简单的帧上节省位并有更多可用于购买要求更高的镜框。相比之下,在单程模式下,编解码器无法提前知道即将发生的事情,但仍必须强制执行受限制的比特率。

请参阅此博客文章(或此存档文章)以获得启发性的解释,以及ffmpeg 关于 H.264 的 wiki以获得更综合的操作方法。

典型的命令行:

ffmpeg -i <INPUT> -c:v libx264 -preset medium -b:v <BITRATE> -pass 1 -an -f <OUTPUT_CONTAINER> -y /dev/null && \
ffmpeg -i <INPUT> -c:v libx264 -preset medium -b:v <BITRATE> -pass 2 <AUDIO_OPTIONS> <OUTPUT>.<OUTPUT_CONTAINER>
Run Code Online (Sandbox Code Playgroud)

你必须选择一些东西。

  • 设置目标比特率,例如 1M(1?Mbit/s) 或500k(500?kbit/s)。有关如何计算相关比特率的信息,请参阅此答案
  • 如今(2020 年),您可能会libx264用较新的libx265编解码器替换视频编解码器,这样可以在相同大小的情况下提供更高的质量。有关如何使 2-pass 选项适应该编解码器的信息,请参阅ffmpeg 的 wiki
  • 为音频编码设置您想要的任何选项。例如,要使用128?kbit/s的Opus编解码器重新编码,请编写-c:a libopus -b:a 128k(在 2020 年,我会推荐 Opus 而不是任何其他有损音频编解码器,例如 AAC)。但是,除非您知道自己在做什么,否则最好的选择可能是根本不重新编码音频,编写-c:a copy. 这样,您甚至不必费心,您的音频也不会质量下降。无论如何,重新编码音频通常不会节省太多(野外的许多音频流的比特率已经约为 128kbit/s 或更低),并且当有视频流时,音频流的大小通常可以忽略不计。有关音频重新编码的更多指南,请参见此处
  • 选择您喜欢的容器格式。最相关的 (2020) 是webmmkvmp4