我是Ryushane,爱好是撸猫的神必男子。

(诶剪视频也算信号处理吧)

点进来这个文章的同学我想多少是剪过视频,或者正需要视频压制工具的。

那么无论你之前用的是格式工厂 / 小丸工具箱 / Media Encoder / Compressor / HandBrake或者其他压制软件,都有必要看一下这期视频。

因为我要讲的是ffmpeg全称Fast Forward mpeg。上面提到的这些压制软件都是基于ffmpeg开发的,可以说是ffmpeg就是上面这些软件的生母。虽说一母生九子,九子各不同。但是这些儿子的内核(DNA)都是从母亲那里的。用命令行调用ffmpeg去进行一些简单的图像处理会比使用上述软件更加快捷。而如果你对命令行不是很熟悉呢,那么这期视频也能帮你理解你所使用的压制软件里的参数是什么含义,以及懂得如何去压制体积和清晰度更符合你的要求的视频。

言归正传,先看图标(x)。先看官网的介绍:

A complete, cross-platform solution to record, convert and stream audio and video.

一个面向录制 / 转换 / 推流音视频的完整的,跨平台的解决方案,听上去好像很牛比的样子,没错它就是很牛比。

在官网上给的例子是下面这一句,只需要这一行命令,就能把视频从mp4转化为avi。

FFmpeg

Stop,Wait a minute. 你可以打开你的终端,找一段mp4的视频,敲下这一句命令试试。网上的安装教程有很多,Windows用户去官网下载压缩包,然后把解压出来的文件夹目录添加到环境变量就OK了。macOS的用户也推荐直接使用brew install ffmpeg方便地安装。至于Linux的用户,想必就不需要我教了。

没错,使用命令行进行格式转换就是这么简单。那么常用到的剪辑 / 压制 / 裁剪如何实现呢。其实很简单,在终端敲入ffmpeg -h我们就可以得到ffmpeg的使用帮助。最常用的命令如下。

-ss    00:00:10    设置开始时间
-to    77:77:77    设置结束时间
-t     11:45:14    设置持续时间

-b:v   20M/20000K  指定视频平均码率(bit per seconds, bps)
-b:a   320k        指定音频平均码率(bit per seconds, bps)
-c:v   copy / x264 指定视频编码
-c:a   copy / x264 指定音频编码

crop=width:height:x:y,width:height表示裁剪尺寸,x:y表示裁剪区域左上角坐标,默认为中心裁剪

这些基本就能覆盖大部分转码需求了,并且参数都是可以自定义的,而且视频中给出的20Mbps码率正是现在B站所能支持的最高码率。那么编码中的copy参数是什么意思呢,其实就是输出跟输入的视频保持同一种编码格式,那这有什么用呢?其实很简单,比如OBS录制的mkv视频,是无法直接导入FCPX的,我们可以把它转换成mp4格式,使用-c:v copy -c:a copy参数可以编码格式转换,整个过程几乎瞬间完成。因为MKV与MP4都只是封装格式,编码方式不变的情况下,就相当于把鸡蛋从冰箱拿出来装到碗里。跟把鸡蛋从冰箱里拿出来打碎了,蒸成鸡蛋糕再盛到碗里的工作量完全不是一个量级。

你以为ffmpeg只能处理视频吗,当然不是。既然都能处理视频了,音频和图片当然不在话下。截取音频的参数跟视频完全一样,只不过把输出改成你想要的音频格式就可以了,这里我们用.mp3格式的文件作为输入,截取我们想要的一段音乐。

ffmpeg -i Enemy.mp3 --ss 00:00:32 -to 00:00:56 Enemy_cut.mp3

当然截取一段视频文件保留音频也是一个道理,只要输入改成你想截取的视频文件就OK了。

ffmpeg -i input.mp4 -ss **START_TIME** -t **STOP_TIME** -acodec copy -vcodec copy output.mp4

同样FFmpeg还有许多其他用法,比如前两天我需要把我录制的讲座的PPT截取出来整理一下给导师看,但是实际上截出来的图片是带有腾讯会议的边框的,为此我就得把这五十多张截图,都进行裁剪。但是人工截取实在是太费时间了,作为一个电子信息工程的硕士打工仔,我想到了用FFmpeg帮我完成这个dirty work。

首先是截取屏幕特定区域,这个很简单,设置好要裁减的大小就可以了,因为我需要的是中心裁剪,所以不设置左上角坐标。然后就是利用一些Shell知识让计算机去遍历文件夹里面每一张jpg对它执行裁剪操作就可以了。

for i in ./*.jpg; do ffmpeg -i $i ${i%.*}_crop.jpg; done
Get-ChildItem -Filter *.jpg -Recurse | Foreach-Object { ffmpeg -i $_*.FullName -vf "crop=1433:1079" "$_.jpg*" }

好了这就是关于FFmpeg的压制教程。

Reference

FFmpeg

FFmpeg 常见用法 - SegmentFault 思否

NVIDIA FFmpeg 转码指南 - NVIDIA 开发者博客

视频与图片互转工具:ffmpeg使用说明 | 闫金钢的Blog (yanjingang.com)

Linux shell中提取文件名和路径 - 鲁娜的博客 | Luna's Blog (dulunar.github.io)

Last modification:June 24, 2022
恰饭环节