Ffmpeg

https://github.com/FFmpeg/FFmpeg

https://github.com/FFmpeg/FFmpeg

https://git.ffmpeg.org/ffmpeg.git

FFmpeg 是一套用于处理多媒体内容(例如音频、视频、字幕和相关元数据)的库和工具集合。

官网(文档):https://ffmpeg.org/

下载:https://github.com/BtbN/FFmpeg-Builds/releases

官网教程:https://ffmpeg.org/ffmpeg.html

YouTube教程(一个较为完整的):https://www.youtube.com/watch?v=MMOTscnkEec&list=PLnMTZUNDARlFhhGzMH3YUrWg4lxWNjCdU

基础使用

-i输入文件

ffmpeg -i test.avi test.mp4

这条简单命令转化视频格式。ffmpeg会自动根据拓展名转换视频格式

什么是视频文件的格式?

mp4是视频的一种封装格式/容器格式,里面包含了

image-20251218191614514

而其中的音频、视频流又可以采用不同的编码格式

编码解决的是如何将每一顿的画面存储成二进制的数据保存在硬盘上或者通过网络传输。显然不同的编码对于视频的质量和压缩率有很大的影响

对于 mp4 文件 自前使用最广泛的视频编码是H264

它有很多不同的名字但实际上说的都是同一个东西

image-20251218192846655

可以看到FFmpeg也默认帮我们选择了-H264编码

image-20251218193103215

当然我们可以通过-c:v(videoencoder)去手动指定一个视频编码器

ffmpeg -i test.avi -c:v libx264 test.mp4

这里的libx264 其实就是FFmpeg默认提供的一个用纯软件实现的H264编码器

如果你使用的是 Nvidia 显卡的话,还可以用 h264_nvenc 进行硬件加速

ffmpeg -i test.avi -c:v h264_nvenc test.mp4

可以看到第二种明显快了不少:

image-20251218193414292

H264并不是唯一的编码格式,我们还可以选择宣称有更高压缩率的H265、VP9等等。但考虑到硬件支持度、编码效率当然还有使用许可的限制,自前应用最广泛的视频编码依然还是 H264

除了视频文件之外,我们还可以用 FFmpeg 来转换音频,甚至可以用它来转换图片

ffmpeg -i sound.wav sound.mp3

或者更常见的用法用它来提取视频中的缩略图等等

bash
ffmpeg -i test.mp4 -vf "fps=1/10,scale=-2:720" thumbnail-%03d.jpg

另外在转换视频的时候,我们可以设置一些其它的参数来压缩宿视频文件的大小

比如对于 H264 编码器,我们可以指定一个预设(preset)

ffmpeg -i test.avi -c:v libx264 -p presetxxx output.mp4

它可以是下面这些取值

image-20251218193951505

从上到小文件编码速度越来越慢,文件大小越来越小。这个参数允许你在编码速度文件大小之间做一些取舍。

第二个非常重要的参数是 -crf (constant rate factor)。它是用来控制图像质量的,取值范围是0-51。这个值越大代表图像质量越差

0(无损)-51(最差质量)实际使用中我们最常用到的范围是19-28

这里的crf允许我们在视频文件大小图像质量之间做一些权衡

我们来讲一下FFmpeg 中另一个重要的功能一一过滤器(filter)

过滤器可以对视频图像进行变换,比如修改它的尺寸、裁剪、旅转、添加滤镜等等

并且我们可以去指定一系列的过滤器:

image-20251218194457657

前一个过滤器的输出会直接作为下一个过滤器的输入。

这里我们用参数-vf(videofilter)来指定一个过滤器

如果要修改视频的尺寸我们可以用 scale,后面我们输入缩放之后的长度和宽度,中间以冒号分隔

bash
ffmpeg -i test.avi -c:v libx264 -vf "scale=1024:576" output.mp4

我们也可以将其中任意一个参数设置成-1,让FFmpeg根据另一个参数帮自动我们推算

比如想要将视频转换成720p,那么可以简写为-1:720

如果要旋转视频, 我们可以用到另一个过滤器transpose,后面的数字代表旋转方向,我们可以在文档中看到这里的2代表将视频90度逆时针旋转

bash
ffmpeg -i test.avi -c:v libx264 -vf "transpose=2" output.mp4 

当然不同的过滤器可以相互组合,比如可以先缩放再旋转,我们只需要将它们以逗号分隔即可

bash
ffmpeg -i test.avi -c:v libx264 -vf "transpose=2,scale=1024:576" output.mp4 

如果我们想要裁剪视频中的某一块区域,可以用到另一个过滤器 crop。这里的四个数字分别代表区域的宽和高

image-20251218195238510

bash
-vf "crop=400:400:100:100"

另外它们也可以是一个表达式

比如我们将宽高设为1/3的原始视频宽度和高度

bash
-vf "crop=iw/3:ih/3"

除了之前讲到的这三种过滤器之外,我们还可以在文档中找到其它上百种的过滤器

接下来我们来讲一下FFmpeg对视频的剪切与合并。

如果要剪切出视频的某个片段,我们会用到两个参数:

第一个-ss 指定了片段的起始位置,第二个-t 表示片段的时长

这里我们可以用 时:分:秒(hh:mm:ss)的格式

ffmpeg -i test.avi -c:v libx264 -ss 00:00:03 -t 00:00:05 output.mp4

也可以直接填写秒数,需要注意的是-ss需要放在-i参数的后面,这样才能做到分毫不差的剪切。

ffmpeg -i test.avi -c:v libx264 -ss 00:00:03 -t 5 output.mp4

如果将 -ss 放在 -i 参数之前

我们虽然可以快速定位片段的起点,但由于使用的是关键帧定位,所以剪切的起始位置可能会稍有偏差,这种方式比较适用于较长的视频,因为定位的速度很快

另外我们可以用-to 来替代-t指定一个片段的终止位置

js
ffmpeg -i test.avi -c:v libx264 -ss 00:00:03 -t 00:00:08 output.mp4

这两个参数都可以用于指定片段的时间范围,只不过表示方式不同而已

如果要合并视频的话,我们需要先将所有的文件列举在一个文本文中

image-20251218200126396

然后通过-f concat指定接下来输入的文件是一个视频列表,后面的-i传入了这个列表文件,再后面的-c copy代表我们不希望重新编码而是直接拷贝原始视频的数据(因为我们输入的视频格式都是完全一样的,重新编码自然会浪费很多时间)

js
ffmpeg -f concat -i mylist.txt -c copy

和视频过滤器一样,我们同样可以用过滤器对音频进行处理,不过这次我们用的是-af(audiofilter)参数

FFmpeg对音频的支持同样是相当齐全的。

比如我们可以用volume调节音量的大小、用loudnorm来统一视频的音量。添加高通、低通滤波器、甚至均衡器等等

有时候我们还希望册删除视频中的音频轨,比如创建一个无声的视频,那么可以用到-an参数

类似的 FFmpeg 还提供-vn /-sn /-dn

image-20251218200826683

小技巧:

首先第一个一一创建视频的缩略图。

js
ffmpeg -i test.mp4 -vf "fps=1/10,scale=-2:720" thumbnail-%03d.jpg

这里用到了两个过滤器。第一个fps指定了输出文件的顿率。1/10代表每十秒输出一顿画面。而后面的 scale指定了输出图像的大小

最后是图像的文件名,由thumbnail加上编号组成

这个命令会在当前的目录下输出若干张长视频的缩略图

image-20251218201452992

第二个技巧,给视频添加水印

我们需要先准备一张图片,然后将原始视频和水印图片同时输入给 FFmpeg

image-20251218201732795

后面的过滤器overlay用于将水印叠加在原始视频的上面,再后面这两个参数指定了水印在图像中的位置

js
ffmpeg -i test.mp4 -i water.png -filter_complex "overlay=100:100" output.mp4
image-20251218203834339

第三个技巧一一gif动图的转换

由于 gif 自身编码格式的限制,不太适合较大或考较长的视频,我们需要先剪接出一个片段

然后用过滤器缩放视频并且降低视频的顿率

最后的这部分存粹是因为 gif 自身 256 色的限制,因此需要单独创建一个调色板

js
ffmpeg -i test.mp4 -ss 0 -t 3 -filter_complex [0:v]fps=15,scale=-1:256,split[a][b];[a]palettegen[p];[b][p]paletteuse output.gif

运行命含可以帮我们生成高画质的igif动图

output

(3 秒片段 → 15fps → 缩放到高 256 → split → palettegen → paletteuse → 输出 GIF)

最后一个技巧一一利用 FFmpeg 来进行屏幕录像

它虽然效率上不如OBS,ShadowPlay这些工具,但是由于不需要额外安装软件,配合上过滤器可以轻易实现各种效果

bash
ffmpeg -hide_banner -loglevel error -stats ^
-f gdigrab -framerate 60 -offset_x 0 -offset_y 0 -video_size 1920x1080 -draw_mouse 1 ^
-i desktop ^
-c:v libx264 -r 60 -preset ultrafast -pix_fmt yuv420p -y screen_record.mp4

这条命令默认会一直录,直到你手动结束 ffmpeg 进程。

你想录固定时长可以加 -t(单位秒,或 hh:mm:ss):

ffmpeg ... -t 00:05:00 -y screen_record.mp4

这就是录 5 分钟自动停止。

清晰度挺高的!

评论

评论加载中……