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


200

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

我忘了写一件事。当视频可以使用字幕(* .srt或* .sub)时,我也希望将其转换为适合转换后的视频文件的参数。


4
我没有使用过它,但是ffmpeg手册页显示了一个-fs限制输出大小的选项,是否可以ffmpeg -i in.avi -fs 100M out.avi正常工作?
凯文(Kevin)

1
我不会将您重定向到手册页:man ffmpeg | wc -l --> 5254

3
.avi不是主要问题。avi只是一个容器。主要问题是您使用的是哪种编解码器。很多(大多数?).avivid使用较旧的编解码器(例如XviD),但与后代的编解码器相比,它们的质量更高,但质量相同。通过使用H.264视频压缩标准(例如,编解码器x264)和aac音频压缩进行紧密编码。您使用的容器和编解码器取决于您和您的电话... .mp4容器已被广泛接受。(但您的电话可以处理它:看到此链接
Peter.O 2012年

@Kevin这需要更多参数进行转换。
xralf 2012年

@hesse是什么意思?
xralf 2012年

Answers:


277

看到这个答案。为方便起见,在下面引用:

通过将1 GB除以以秒为单位的视频长度来计算所需的比特率。因此,对于长度为16:40(1000秒)的视频,请使用1000000字节/秒的比特率:

ffmpeg -i input.mp4 -b 1000000 output.mp4

可能值得考虑的其他选项是设置“恒定速率因子”,它降低了平均比特率,但保留了更好的质量。CRF在18到24之间变化-比特率越低,比特率越高。

ffmpeg -i input.mp4 -vcodec libx265 -crf 20 output.mp4

根据需要更改编解码器-如果libx265不可用,则libx264可用,但代价是文件大小稍大。


大小为338 MB的视频减少为大小130 MB。质量迅速下降。这个过程有什么解释吗?原始作者没有解释他的指导方针。
xralf 2012年

13
第二个命令,使用-crf 24拍摄了我拥有的255.3MB视频,并将其减少到72.7MB,而没有明显降低质量。有一个赞!
帕特里克·罗伯茨

2
令人印象深刻的是,将〜2G的视频减少到14MB,看起来仍然不错,这是第一个搜索结果,而这正是我想要的,谢谢!
sinisterstuf

5
可能需要注意的是,您现在可以使用它libx265来进一步减小尺寸。
ZN13

6
二手的ffmpeg -i input.avi -vcodec libx264 -crf 24 output.avi。它将100mb的视频减少到9mb。。视频质量的变化很小。谢谢!
alpha_989 '18

32

除非您要寻找特定的比特率,否则我建议您-crf选择该选项。这是最常用的 x264编码:http : //slhck.info/articles/crf

简而言之:CRF为23将产生“ DVD”质量的电影(〜700MB-1GB),而较低的CRF值将具有较高的质量(较大的文件)。


3
请提供完整命令的示例,而不是链接到外部网站(有一天可能会中断:)
Jake Berger '18

1
@Vicky Chijwani在上面的示例中提供了代码。这更适合发表评论,但这是我在此站点上的第一个活动。该链接对crf选项有更多说明,但并不需要使代码起作用。
汤姆·凯利

27

您提到要减少文件大小以适合移动设备上的更多视频,这也是我的用例。这里所有的答案都是为了降低压缩质量,但是没有人提到减小视频帧的大小。根据我的经验,它要快很多,比重新压缩要快3到5倍。查看ffmpeg的文档缩放以获得更多信息。

ffmpeg -i input.mkv -vf "scale=iw/2:ih/2" half_the_frame_size.mkv
ffmpeg -i input.mkv -vf "scale=iw/3:ih/3" a_third_the_frame_size.mkv
ffmpeg -i input.mkv -vf "scale=iw/4:ih/4" a_fourth_the_frame_size.mkv

20

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

(BR)使用以下方法修改比特率:

ffmpeg -i $infile -b $bitrate $newoutfile 

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

ffmpeg -i $infile -vcodec libx264 -crf 23 $outfile

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

ffmpeg -i $infile -vf "scale=iw/2:ih/2" $outfile

(BL)使用以下命令将H.264配置文件更改为“基准”:

ffmpeg -i $infile -profile:v baseline $outfile

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

ffmpeg -i $infile $outfile

数据

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

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

===文件A-节点如何帮助推进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

===文件B-将GraphQL与角度一起使用_作者-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

结论

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

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

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

正确(或最佳)答案

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

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

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

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

  • 如果您拥有强大的处理器,而只有空间是唯一的问题,则可以提高压缩率。

  • 比特率是多种因素的组合。因此,仅告诉ffmpeg降低比特率可能不会给您想要的结果。

  • 降低信息含量的另一种方法是降低色彩深度。如何进行此操作尚未讨论。


12

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

ffmpeg -i input.mp4 output.mp4

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


1
从4Gb到2Gb,谢谢!
Sam Hosseini

1
(从10Mo到1.2Mb,ffmpeg将我的视频从VP8自动转换为VP9
sodimel

这使我的视频大小从10.8MB增加到
14MB

3

我有一个最初为自己准备的菜谱,目的是将旧相机生成的Motion JPEG视频(它们是非常大的视频,因为每帧都是整个JPEG图像)转换为h264。这是对其他类型视频(课程等)的改编。

不是用ffmpeg,而是mplayer和mencoder。首先,我们必须使用mplayer对音频进行解复用:

mplayer -vo null -ao pcm:fast:file=<audio_pcm.wav> <video>
  • -vo null-ao null参数告诉MPlayer不提取视频。

在接下来的步骤中,我们将使用Mencoder进行3遍压缩。在第一遍中,我们将选择合适的“恒定质量模式”压缩(crf参数)作为起点:

mencoder <video> -ovc x264 \ 
         -x264encopts ratetol=100:preset=veryslow:crf=<value>:pass=1 \
         -nosound -o video1.h264
  • 如果您对视频的最终质量有偏执,可以将slow_firstpass参数添加到-x264encopts。Mencoder手册说,此选项禁用一些参数,“这些参数“显着提高了编码速度,而对最终通过的质量几乎没有影响”。因此,仅在最后一步使用它。

  • 您应该为crf尝试多个值-尝试从25开始,然后不断增加,直到您注意到所生成视频的伪像为止(更高的值会压缩更多)。请记住,后续的编码传递将提高您为crf选择的质量。

  • 为替代veryslow预置是较慢的中等等等。参见mencoder的手册的完整列表。

  • ratetol控制比特率变化-我不确定在这里是否做正确的事,但是我将其设置为最大值,以便让编码人员完全自由地为每个场景选择正确的比特率。

第一次通过后,您会注意到最后一行为您提供了在后续步骤中使用的平均比特率:

(...)
x264 [info]: kb/s:526.43

将第一遍建议的crf参数更改为后续遍所需的bitrate

mencoder <video> -ovc x264 \
       -x264encopts slow_firstpass:ratetol=100:preset=veryslow:bitrate=526:pass=3 \
       -nosound -o video2.h264

此第二遍编码将读取在第一遍(divx2pass.logdivx2pass.log.mbtree)生成的统计信息,以优化压缩。

  • 请注意,您将使用相同的视频输入,而不是首遍生成的视频-首遍的输出视频仅用于检查初始质量。

  • 另请注意,pass=3not pass=2)将生成一个新的统计文件,因此您可以根据需要多次重复最后一步。我通常会做pass=3两次,始终注意结果的比特率。

同时,您也可以使用lame或压缩音频oggenc

oggenc -q<n> <audio_pcm.wav>

最后,我们将重新混合音频和视频

mencoder -audiofile <audio>.ogg video2.h264 -oac copy -ovc copy \
         -of lavf -lavfopts format=mp4 -o <video>.mp4
  • -of lavf -lavfopts format=mp4生成mp4使用lavopts muxers文件格式。

3

我将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 docs
  • -preset faster:比“中型” 参考文档的默认编码时间快2倍
  • -tune film:指定输入为HQ视频(其他选项包括“卡通”,“静止图像”。)ref docs
  • 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的开源替代方案


有用。但是要花很多时间 是否有任何改进可以减少执行时间
Nirali


1

我写了一个bash脚本来减小视频大小并自动尝试不同的crf值。

基本上你会

  • 选择一系列crf值
  • 运行脚本
  • 检查生成的视频的大小,然后选择所需的视频

当您有想要达到的大小限制并且不知道什么crf值可以使用时,这确实很方便。

我希望这会对某人有所帮助。我与同事共享,每个人都发现它很有帮助。

#!/bin/bash

# bigger values of crf will lead to a bigger compression (smaller video size)
#for i in 1 2 3 4 5
for i in {25..28}
do
# you can remove the option -y if you want to be asked if to overwrite a file with the same name (leave the -y only if you understand what you are doing, otherwise you might rewrite an important file)
   ffmpeg -y -i NAMEOFTHEVIDEOTOCOMPRESS.mp4 -c:v libx264 -crf $i -preset veryfast -profile:v baseline -level 3.0 -strict -2 out_$i.mp4
   printf "\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>Done compression at crf=$i \n\n"
done
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.