随手可用的FFmpeg

Posted happydeer

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了随手可用的FFmpeg相关的知识,希望对你有一定的参考价值。

若干年前,写过一篇“技术宅学会几招FFmpeg”。至今仍觉得这篇小文挺实用,时不时会翻出来,对照着使用场景把FFmpeg命令行一抄,直接运行或者简单修改一下参数,就能完成任务,非常方便!有时候,又觉得时过境迁,这篇小文覆盖的使用场景太单薄,亟需补充一下。毕竟自己也换了新的工作环境,碰到了一些新需求。于是,便有了本文。

我们仍然按照使用场景来归类,分为视频/图像、音频、其他工具等。我会视情况,持续更新本文的内容——记得收藏本文的链接哦!

一.视频/图像

Case 100】从最基础的场景开始,在视频文件的指定时间点抽取一帧图像,目标文件格式通过扩展名来控制,可以是.png、.jpg、.webp等:

ffmpeg -ss 5 -i D:\\input.mp4 -frames:v 1 D:\\snapshot.png

如果需要的是缩略图,或者出于节省存储空间考虑,那就要对图像进行缩放。可以通过scale过滤器来指定你想要的图像宽和高,也可以宽或高只指定一个,另一个用“-1”代替,以保持图像的原始宽高比(确保图像内容不被扭曲):

ffmpeg -ss 5 -i D:\\input.mp4 -frames:v 1 -vf scale=120:-1 D:\\snapshot.jpg

注:-vf表示简单过滤器。所谓“简单”,是指过滤器只能有一个输入和一个输出。

Case 101】挑战一下,另一种“既要…又要…”的缩略图:既要限定宽和高(比如120x80),又需要保持图像的原始宽高比,图像内容之外的区域用黑色填充:

ffmpeg -ss 5 -i D:\\input.mp4 -frames:v 1 -vf "scale='min(120/iw, 80/ih)'*iw:'min(120/iw, 80/ih)'*ih, pad=120:80:(ow-iw)/2:(oh-ih)/2:black" D:\\snapshot.webp

解释一下:我们使用了两个过滤器。先使用scale过滤器,iw和ih分别表示源图像的宽和高,相对于目标图像尺寸120x80,分别计算宽和高的缩放比例,选择两者中较小的比例对原始图像进行缩放。然后使用pad过滤器来填充:前两个参数指定目标图像的宽和高(把它想象成一块黑色画布),紧接着的两个参数用来指定实际图像在“画布”上渲染的起始点(左上角)坐标x:y,最后一个参数是填充色。ow和oh分别指代输出图像的宽和高,本例中其实就是120和80。

Case 102】怎样从视频文件里按照一定的间隔(比如10fps)抽取一系列的缩略图呢?

ffmpeg -i D:\\input.mp4 -r 10 -vf "scale='min(120/iw, 80/ih)'*iw:'min(120/iw, 80/ih)'*ih, pad=120:80:(ow-iw)/2:(oh-ih)/2:black" -y D:\\Thumbnails\\Pic-%05d.jpeg

Case 103】有些手机的前置摄像头拍的视频是左右颠倒的,需要做一次水平翻转:

ffmpeg -i D:\\input.mp4 -vf hflip D:\\flipped.mp4

“买一送一”,送一条垂直翻转:ffmpeg -i D:\\input.mp4 -vf vflip D:\\flipped.mp4

那么,如何同时做水平和垂直翻转呢?-vf后面可以跟多个过滤器,使用逗号分开即可,注意要加一对引号:

ffmpeg -i D:\\input.mp4 -vf "hflip, vflip" D:\\flipped2.mp4

还有以前学过的一招,一起汇总在这儿:旋转90度(弧度值为正数表示顺时针,负数表示逆时针),记得要将输出图像的宽和高对调一下:

ffmpeg -i D:\\input.mp4 -vf "rotate=a='90*PI/180':ow=ih:oh=iw" D:\\rotate90.mp4

当然,上述针对视频文件的处理,对图像文件同样也是适用的。

Case 104】随着智能手机的普及以及UGC短视频内容的风行,现在随处可见竖版视频。如果在某些场景下你偏偏要用横版视频,怎么从竖版视频里抠出一块来呢?该crop过滤器上场啦!举个例子,居中截取与源视频等宽、宽高比是16:9的那一块区域:

ffmpeg -i D:\\input.mp4 -vf "crop=in_w:(in_w*9/16):0:(in_h-in_w*9/16)/2" D:\\cutout.mp4

二.音频

【Case 200】实验室的Matlab算法能接受的数据格式可能仅限于.wav,而客户提供的素材可能是任意一种压缩格式,需要做一次转换:

ffmpeg -i D:\\input.m4a D:\\output.wav

好简单吧,通过输出文件的扩展名.wav就能控制数据格式。当然,如果想要生成.mp3或.ogg压缩格式,如法炮制,把输出文件名改成output.mp3或output.ogg即可。如果拿到的素材是视频文件,只想提取其中的音频,用法也是类似的(-vn表示丢弃视频数据,这个参数是可选的):

ffmpeg -i D:\\input.mp4 -vn D:\\output.wav

【Case 201】常见的音频采样频率有11025Hz、22050Hz、24000Hz、44100Hz(CD音质)、48000Hz、96000Hz等。如何进行改变呢?

ffmpeg -i D:\\input.m4a -ar 48000 D:\\output.wav

【Case 202】假如客户给的素材是5.1声道的,而我们只能处理单声道或双声道,怎么办?

ffmpeg -i D:\\input.m4a -ac 1 D:\\output.wav

【Case 203】常见的采样精度/位深有8位、16位、24位、32位等,即单个声道每个采样点用多少Bits来表示。如果要改变位深,则需使用-acodec来指定编码器(如果想查询当前有哪些可用的编码器,参见Case 300),可选值为:pcm_u8、pcm_s16le、pcm_s24le、pcm_s32le等,其中“u”表示无符号数,“s”表示有符号数,“le”表示little-endian(即低字节在前的多字节数据格式):

ffmpeg -i D:\\input.m4a –acodec pcm_s24le D:\\output.wav

注:-acodec与-c:a是等价的。

【Case 204】如何改变音量呢?使用-af音频过滤器,volume=1表示正常音量,=0.5表示变为一半,=2表示变为2倍。volume的取值也可以带上dB单位,正数表示音量增加xxdB,负数表示音量减小xxdB:

ffmpeg -i D:\\input.m4a -af volume=2 D:\\output.wav

ffmpeg -i D:\\input.m4a -af volume=-2dB D:\\output.wav

【Case 205】如果目标文件是一种压缩格式,我们可能还想使用-ab来指定它的码率/bitrate(CBR-恒定码率),以控制音质(码率越高、音质越好):

ffmpeg -i D:\\input.m4a -ab 128k D:\\output.mp3

注:-ab与-b:a是等价的。

或者也可以用-aq(取决于特定的编码器,VBR-可变码率,取值越小,码率越高):

ffmpeg -i D:\\input.m4a -aq 2 D:\\output2.mp3

【Case 206】如何将多个音频文件首尾相连合成为一个?假设有四个源文件,分别是input1.m4a、input2.wav、input3.mp3、input4.mp4(格式不限),然后要使用-filter_complex复杂过滤器,“concat”之前的[0:0]表示第一个输入源的0号输出(注意:索引都是从0开始的,对于有多路输出的源文件,0号输出是视频流,1号输出是音频流),[1:0]表示第二个输入源的0号输出,以此类推;“concat”之后的n=4表示总共有4路流参与合成,v=0表示丢弃视频数据,a=1表示为合成一路音频流:

ffmpeg -i D:\\input1.m4a -i D:\\input2.wav -i D:\\input3.mp3 -i D:\\input3.mp4 -filter_complex "[0:0][1:0][2:0][3:1]concat=n=4:v=0:a=1" –ab 128k –y D:\\concat.mp3

脑补这样一张图:

【Case 207】继续讨论多文件混合的场景,如果我们要的不是首尾相连,而是混音呢?那就要用到amerge这个复杂过滤器了:

ffmpeg -i D:\\input1.m4a -i D:\\input2.wav -filter_complex "[0:0][1:0]amerge=inputs=2" –ab 128k D:\\merge.mp3

需要注意的是,合成的文件时长以较短的那个为准——这个有点让人无法接受!有个“笨”办法,就是使用-stream_loop让较短的那个输入文件循环输出,像这样:

ffmpeg -stream_loop 2 -i D:\\input1.m4a -i D:\\input2.wav -filter_complex "[0:0][1:0]amerge" –ab 128k -y D:\\merge.mp3

很别扭呀!还是来看看更为强大的amix过滤器吧,它可以通过duration来指定目标文件的时长以哪个为准(可选值为longest、shortest、first),还可以通过weights指定各路流的混音权重(缺省均为1/N):

ffmpeg -i D:\\input1.m4a -i D:\\input2.wav -i D:\\input3.mp3 -filter_complex "[0:0][1:0][2:0]amix=inputs=3:duration=longest:weights='0.1 0.1 0.8'" –ab 128k D:\\mix.mp3

【Case 208】继续深入探讨:在混音时,可以为各个音效文件指定在时间线上的开始时间吗?答案是肯定的。我们这次把最长的主音频文件作为第一个输入源,然后通过adelay过滤器将第二个音效文件延迟5秒开始,将第三个音效文件延迟至第30秒开始(delays参数值,不带单位时默认为毫秒,小写s表示秒,大写S表示采样点数量;可以为各个声道分别指定延迟时间,或者通过all=1为所有声道指定相同的延时):

ffmpeg -i D:\\input1.m4a -i D:\\input2.wav -i D:\\input3.mp3 -filter_complex "[1:a]adelay=delays=5s:all=1[a1]; [2:a]adelay=delays=30s:all=1[a2]; [0:a][a1][a2] amix=inputs=3:duration=first:weights='0.6 0.2 0.2'" –ab 128k -y D:\\mix.mp3

值得注意的是,这次我们换了一种标注方法:[1:a]表示第二个输入源的音频输出,经过adelay处理之后把输出流标记为[a1];[2:a]表示第三个输入源的音频输出,经过adelay处理之后把输出流标记为[a2];然后第一个输入源的音频输出流[0:a]与[a1]和[a2]一起喂给amix过滤器进行混音。目标文件的时长以第一个输入源为准。各路流的混音比例分别是60%、20%、20%(加起来等于100%)。

三.其他工具

【Case 300】查看FFmpeg自带的编解码器、文件容器格式:

ffmpeg –codecs

ffmpeg –decoders

ffmpeg –encoders

ffmpeg –formats

【Case 301】有时候需要录屏,但又懒得去安装一款第三方录屏软件。可以这样:

ffmpeg -f gdigrab -i desktop D:\\screenshots.mp4

注:按下“Q”键或者 Ctrl+C 即可停止录屏。

【Case 302】基于上述录屏命令,在视频右下角加上文字水印:

ffmpeg -f gdigrab -i desktop -vf drawtext="fontsize=80:fontcolor=white:text='TEST':x=(w-text_w-10):y=(h-text_h-10)" -y D:\\screenshots.mp4

【Case 303】基于上述录屏命令,改成在视频右上角加上图片水印:

ffmpeg -f gdigrab -i desktop -i D:\\logo.png -filter_complex "[0:0][1:0]overlay=x=main_w-overlay_w-10:y=0" -y D:\\screenshots.mp4

【Case 304】通过笔记本电脑的内置摄像头采集一段视频。摄像头的名字未必总是“Integrated Camera”,可能因不同机型而不同,可以在Windows系统的“设备管理器 | 照相机”下查看(或者执行ffmpeg -list_devices true -f dshow -i dummy):

ffmpeg -f dshow -i video="Integrated Camera" D:\\capture.mp4

注:按下“Q”键或者 Ctrl+C 即可停止采集。

官网资料:

http://ffmpeg.org/ffmpeg.html#Audio-Options

 http://ffmpeg.org/ffmpeg.html#Video-Options

http://ffmpeg.org/ffmpeg-filters.html

以上是关于随手可用的FFmpeg的主要内容,如果未能解决你的问题,请参考以下文章

随手可用的FFmpeg(更新于2022/11/24)

随手可用的FFmpeg(更新于2022/8/23)

FFMPEG:两个单声道到一个立体声文件,其持续时间是这两个单声道文件中最长的

FFMPEG:生成输入文件时间最长的7.1声道音频文件

OGG与AAC音质比较起来哪个更好?

HDMI和光纤哪种音质好