写点什么

FFmpeg 从入门到精通 - 云享读书会总结

作者:DS小龙哥
  • 2023-05-05
    重庆
  • 本文字数:27860 字

    阅读完需:约 91 分钟

前言

FFmpeg 是一款开源软件,用于生成处理多媒体数据的各类库和程序。FFmpeg 可以转码、处理视频和图片(调整视频、图片大小,去噪等)、打包、传输及播放视频。作为最受欢迎的视频和图像处理软件,它被来自各行各业的不同公司所广泛使用。


FFmpeg 被称作是音视频领域的瑞士军刀,是音视频及相关领域是无人不晓,无人不知的项目, 只要了解多媒体音视频处理的人,都会感叹这个项目的强大。


FFmpeg 项目由 Fabrice Bellard 在 2000 年创立,到目前为止,经历了 21 年的演化。FFmpeg 社区和其他多媒体项目互动频繁,这也是它成功的原因之一。在创立之初,有很多开发者同时活跃在 Mplayer 项目,到目前为止,FFmpeg 项目的开发者仍然与 VLC、MPV、dav1d、x264 等多媒体开源项目有着广泛的重叠。2004 年以后,FFmpeg 社区基本由 Michael Niedermayer 领导。


在这近 22 年的风风雨雨中,FFmpeg 一路走来也是经历过不少挫折,在 2011 年 FFmpeg 就因为核心成员意见不一导致分裂,差点最终导致整个项目消亡殆尽。最终的结果就是,项目创始人法布里斯贝拉选择了离开 FFmpeg,但是随后他与其他一起出走的开发者创建另一知名开源编解码库项目 Libav。 FFmpeg 和 Libav ,就像南慕容和北乔峰一样,是当下所有主流播放器必备的编解码库,并且这些编解码库全部开源可免费使用无需额外付费。不过,虽然说是免费使用,但 FFmpeg 是基于 LGPL/GPL 开源的,这意味着如果某软件使用了 FFmpeg 的代码,那么这个软件涉及这些代码的部分,也必须开源,并且需要在使用其项目源代码和编解码库时注明来源。目前,FFmpeg 不仅被大量免费软件使用,同时使用的,还有很多大型公司,例如:YouTube、iTunes、腾讯旗下产品、字节跳动旗下产品等。


当前文章内容来至 华为云 · 云享读书会 第13期 《FFmpeg从入门到精通》读书会直播视频的资料整理,《FFmpeg从入门到精通》的作者是一位典型的音视频技术爱好者,前后就职于广电巨头和音视频互联网公司,具有丰富的音视频直播和点播相关经验,对 WebRTC、FFmpeg 和 Electron 有非常深入的了解。


接下来会陆续按照几个章节由浅入深地介绍 FFmpeg 处理音视频的常用方法, 对音视频技术感兴趣的小伙伴能从中学到很多干货。


当前文章能学习的知识点:


(1)了解多媒体处理工具 FFmpeg 工具集


(2)了解音频文件的封装格式、编码格式


(3)了解视频文件的封装格式、编码格式


(4)掌握 FFmpeg 查看音视频媒体信息的方法


(5)掌握 FFmpeg 处理音视频文件的常用方法

一、多媒体处理工具 FFmpeg 工具集

(1)FFmpeg 的发展

FFmpeg 是一个多媒体开源项目,项目地址:https://github.com/FFmpeg/FFmpeg


FFmpeg 最早是由法国天才程序员法布里斯·贝拉在 2000 年时开发的,后来一直快速发展至今,当前最新的版本是 5.0。


目前,FFmpeg 已经被很多开源项目所采用,比如 ijkplayer、VLC、MPlayer、Blender、Google Chrome 等。

(2)FFmpeg 的组成

FFmpeg 工程内部根据功能划分了不同的模块,包括 AVFormat、AVCodec、AVFilter、AVDevice、AVUtil、swresample、swscale。


(3)FFmpeg 的模块介绍

【1】AVFormat 是 FFmpeg 的封装模块,其中实现了目前多媒体领域中的绝大多数媒体封装格式,包括封装和解封装,比如 MP4、FLV、MKV、TS 等文件封装格式,RTMP、RTSP、HLS 等网络协议封装格式。另外,也支持自定义封装格式。


【2】AVCodec 是 FFmpeg 的编解码模块,其中实现了目前多媒体领域中的绝大多数媒体编解码格式,包括编码和解码两大部分,比如 MPEG4、H264、H265 等视频格式,AAC、MP3 等音频格式。另外,也支持自定义编解码格式。


【3】AVFilter 是 FFmpeg 的滤镜模块,其中实现了目前通用的音频、视频、字幕等滤镜处理框架。


【4】AVDevice 是 FFmpeg 的设备管理模块,包括音频设备和视频设备。


【5】AVUtil 是 FFmpeg 的工具模块。


【6】swresample 是 FFmpeg 的音频转换模块,包括音频重采样、声道数调整等。


【7】swscale 是 FFmpeg 的视频图像转换模块,包括图像缩放、像素格式转换等。


FFmpeg 开发库:


(1)、libavutil是一个包含简化程序功能的库,其中包括随机数生成器,数据结构,数学例程,核心多媒体实用程序等。(2)、libavcodec是一个库,其中包含音频/视频编解码器的解码器和编码器。(3)、libavformat是一个包含用于多媒体容器格式的解复用器和复用器的库。(4)、libavdevice是一个包含输入和输出设备的库,用于从许多常见的多媒体输入/输出软件框架(包Video4Linux,Video4Linux2,VfW和ALSA)中获取和呈现。(5)、libavfilter是一个包含媒体过滤器的库。(6)、libswscale是一个执行高度优化的图像缩放和颜色空间/像素格式转换操作的库。(7)、libswresample是一个执行高度优化的音频重采样,重矩阵化和样本格式转换操作的库。
复制代码

(4)FFmpeg 的工具集


【1】ffmpeg 是 FFmpeg 工具集中的编解码工具。


【2】ffplay 是 FFmpeg 工具集中的播放器。


【3】ffprobe 是 FFmpeg 工具集中的多媒体分析工具。

(5)FFmpeg 编译安装(linux)

【1】下载地址


https://ffmpeg.org/download.html
复制代码


【2】配置 FFMPEG


[root@wbyq ffmpeg-3.0.2]#./configure --enable-shared --enable-static --prefix=$PWD/_install --enable-gpl --extra-cflags=-I/home/wbyq/pc_work/x264-snapshot-20160527-2245/_install/include --extra-ldflags=-L/home/wbyq/pc_work/x264-snapshot-20160527-2245/_install/lib --enable-ffserver --enable-ffmpeg --enable-libx264编译安装:[root@wbyq ffmpeg-3.0.2]# make[root@wbyq ffmpeg-3.0.2]# make install
FFMPEG最新版本4.2.2编译配置:截止编写文档时,FFMPEG最新版本是4.2.2。 编译配置方法如下:[root@wbyq ffmpeg-4.2.2]# ./configure --enable-static --enable-shared --prefix=$PWD/_install --extra-cflags=-I/home/wbyq/pc_work/x264-snapshot-20160527-2245/_install/include --extra-ldflags=-L/home/wbyq/pc_work/x264-snapshot-20160527-2245/_install/lib --enable-ffmpeg --enable-libx264 --enable-gpl[root@wbyq ffmpeg-4.2.2]#make[root@wbyq ffmpeg-4.2.2]#make install
复制代码

二、视频文件的封装格式

FFmpeg 支持很多封装格式,包括 MP4、FLV、MKV、TS 等视频封装格式、MP3、AAC 等音频封装格式以及 RTMP、RTSP、HLS 等网络协议封装格式。接下来,重点介绍 MP4 视频封装格式。

(1)MP4 封装格式

MP4 封装格式基本上可以认为是日常生活和工作中最常见的视频文件格式,主要是由于其广泛的适用性,不仅在 PC 端(windows、mac、linux)支持的非常好,而且在移动端(Android、iOS)也能流畅播放。

(2)MP4 格式标准

MP4 格式标准为 ISO-14496 Part 12 和 ISO-14496 Part 14,具体特征如下:


【1】MP4 文件由许多 Box 和 FullBox。


【2】FullBox 是 Box 的扩展,在 Header 中增加了 8 位 version 信息和 24 位的 flags 信息。


【3】每个 Box 由 Header 和 Data 两部分组成。


【4】Header 中包含了整个 Box 的长度大小(size)和类型(type)。


【5】Data 中包含了实际的数据,可以是纯数据,也可以是子 Box。当 Box 中的 Data 是一系列子 Box 时,这个 Box 又被称为 Container(容器)。


(3)MP4 ftyp Box

ftyp Box,一般位于文件开始位置,其中包含了 MP4 视频文件的类型、版本、兼容协议等信息。


(4)MP4 moov 容器

moov 容器中包含了 MP4 视频文件的媒体数据信息,内部又包含两个子容器:mvhd 和 trak,前者定义了文件头信息,后者定义了媒体文件中的 track 信息。


moov 容器一般默认会生成在 MP4 文件结尾,在线播放时需要加载完整个文件才能正常打开,为了能够快速打开视频,需要把 moov 容器放在 MP4 文件的前面。


(5)MP4 mdat Box

mdat Box,用来存放媒体文件的实际数据内容。


三、视频文件的编码格式

FFmpeg 支持很多视频编码格式,比如:MPEG4、H263、H264、H265、VP8、VP9 等。


接下来,重点介绍 H264 视频编码格式。

(1)H264 的码率控制

【1】VBR:Variable BitRate,动态码率模式,其码率可以随着图像的复杂程度的不同而变化,因此其编码效率比较高。


【2】CBR:Constant BitRate,恒定码率模式,由于码率恒定,有画面剧烈变化时,QP 参数会增大,图像质量会变差,当场景静止时,又浪费带宽。该模式的整体图像质量不稳定。


【3】ABR:Average BitRate,平均码率模式,是 VBR 的一种衍生形式,在指定的文件大小内,静态或者接近静态的画面部分使用相对较低的流量,复杂画面部分使用较高的流量,可以视为是 VBR 和 CBR 的一种折衷方案。

(2)H264 的 I 帧类型

【1】一个 GOP 序列的第一个图像叫做 IDR 图像(立即刷新图像),IDR 图像都是 I 帧图像,但 I 帧不一定都是 IDR 帧,只有 GOP 序列的第 1 个 I 帧是 IDR 帧。


【2】I 帧,又叫帧内参考帧 ,保留一帧完整的画面。


【3】解码时仅用 I 帧的数据就可重构出完整的图像。


【4】I 帧不需要参考其他画面而生成。


【5】I 帧是 P 帧和 B 帧的参考帧。


【6】I 帧不需要考虑运动矢量。


【7】I 帧所占数据的信息量最大。

(3)H264 的 B 帧类型

【1】B 帧,又叫双向参考帧,也就是 B 帧记录的是本帧与前后帧的差别,要解码 B 帧,不仅要取得之前的缓存画面,还要解码之后的画面,通过前后画面的与本帧数据的叠加取得最终的画面。


【2】B 帧的压缩率最高,但是解码时 CPU 使用率会比较高。


【3】B 帧是由前面的 I 或 P 帧和后面的 P 帧来进行预测的。


【4】B 帧传送的是它与前面的 I 或 P 帧和后面的 P 帧之间的预测误差及运动矢量。


【5】B 帧不是参考帧,不会造成解码错误的扩散。

(4)H264 的 P 帧类型

【1】P 帧,又叫前向参考帧,表示的是这一帧跟之前的一个关键帧(或 P 帧)的差别,解码时需要用之前缓存的画面叠加上本帧定义的差别,生成最终画面,P 帧没有完整画面数据,只有与前一帧的画面差异的数据。


【2】P 帧是 I 帧后面相隔 1~2 帧的编码帧。


【3】P 帧采用运动补偿的方法传送它与前面的 I 或 P 帧的差值及运动矢量(预测误差)。


【4】P 帧属于前向预测的帧间编码。它只参考前面最靠近它的 I 帧或 P 帧。


【5】P 帧可以是其后面 P 帧的参考帧,也可以是其前后的 B 帧的参考帧。


【6】P 帧是参考帧,可能会造成解码错误的扩散。


【7】P 帧的压缩比介于 I 帧和 B 帧之间。

(5)H264 帧参考关系

四、音频文件的封装格式和编码格式

(1)FFmpeg 的音频封装格式

MP3 是我们在日常生活中最常见的音频格式之一,也是一种音频封装格式。


日常生活中,我们经常可以看到 *.mp3 的音频文件,就像 mp4、flv 的视频封装格式一样。


MP3 封装格式


使用如下命令查看 ffmpeg 支持的封装格式列表: ffmpeg -formats | grep mp3



使用如下命令播放一个 mp3 音乐文件:


普通模式: ffplay 少年.mp3


波形图模式:ffplay -showmode 1 少年.mp3


频谱图模式:ffplay -showmode 2 少年.mp3



(2)FFmpeg 的音频编码格式

FFmpeg 支持很多编码格式,包括 MP3、AAC、AC3 等。


接下来,重点介绍 MP3 音频编码格式。


MP3 编码格式


MP3 也是一种音频编码格式。


和视频不同,视频编码格式,比如 H264,一般会封装 MP4 或者 FLV 这种封装格式中被使用。音频编码格 MP3,则是封装在同名的 MP3 的封装格式中。二者容易混淆,注意区分。


MP3 编码格式


使用如下命令查看ffmpeg支持的编码格式列表:



MP3 文件结构



MP3 文件结构


五、FFmpeg 查看媒体信息和处理音视频文件的常用方法

(1)FFmpeg 的工程化方案

音频文件和视频文件的转码处理一般称为多媒体处理,华为云也有相应的媒体处理服务——Media Processing Center,简称 MPC,是一种多媒体数据处理服务,基于华为云云计算服务构建,解决客户自建音视频处理能力不可避免的投入成本高昂、技术门槛高等问题,帮助客户专注于业务能力构建,快速交付上线。


【1】视频处理



【2】音频处理


(2)FFmpeg 视频转码

采用 FFmpeg 对音视频处理,主要是转码、视频参数、音频参数三部分内容。


传统的转码程序工作原理如下图所示:



【1】音视频转码示例:


1. 音频转码ffmpeg -i 少年.mp3 -acodec aac -ab 3000 -ac 1 -ar 8000 output.aac
2. 视频转码ffmpeg -i big_buck_bunny.mp4 -vcodec h263 -b:v 256000 -r 15 -s 352x288 -acodec copyoutput.ts
复制代码


【2】最简单的方式转码


ffmpeg -i 123.mp4 out.flv
复制代码


【3】任意格式转为 MP4


转码视频格式并设置音频采样率和输出视频尺寸: mpg-->mp4C:\FFMPEG\ffmpeg_x86_4.2.2\bin\ffmpeg.exe -i 1.mpg -y -qscale 0 -vcodec libx264 -acodec aac -ac 1 -ar 22050 -s 300*300  1_1.mp4  转码视频格式并设置音频采样率和输出视频尺寸(软解可以播放-硬解无法播放): wmv-->wmvC:\FFMPEG\ffmpeg_x86_4.2.2\bin\ffmpeg.exe -i 2.wmv -y -qscale 0 -vcodec libx264 -acodec aac -ac 1 -ar 48000 -s 300*300  2_1.wmv  转码视频格式并设置音频采样率和输出视频尺寸: wmv-->mp4C:\FFMPEG\ffmpeg_x86_4.2.2\bin\ffmpeg.exe -i 2.wmv -y -qscale 0 -vcodec libx264 -acodec aac -ac 1 -ar 48000 -s 300*300  2_1.mp4  转码视频格式并设置音频采样率: wmv-->mp4C:\FFMPEG\ffmpeg_x86_4.2.2\bin\ffmpeg.exe -i 2.wmv -y -qscale 0 -vcodec libx264 -acodec aac -ac 1 -ar 48000 2_1.mp4  转码视频格式并设置音频采样率: wmv-->mp4C:\FFMPEG\ffmpeg_x86_4.2.2\bin\ffmpeg.exe -i Video_2020-10-11_2.wmv -y -qscale 0 -vcodec libx264 -acodec aac -ac 1 -ar 22050 Video_2020-10-11_2_1.mp4  转码视频格式并设置音频采样率和输出视频尺寸、修改码率: mpg-->mp4C:\FFMPEG\ffmpeg_x86_4.2.2\bin\ffmpeg.exe -i 1.mpg -y -qscale 0 -vcodec libx264 -acodec aac -ac 1 -ar 22050 -b:v 400k -s 300*300  1_1.mp4
复制代码

(3)音视频合并

【1】视频拼接


这种方式需要保证所有的视频的格式、音频码率一样,不然无法正常合并。


C:\FFMPEG\ffmpeg_x86_4.2.2\bin\ffmpeg.exe  -f concat -safe 0 -i filelist.txt -c copy demo.mp4 filelist.txt文件内容---里面的视频路径使用相对路径:file 'd8381671f616468c9193defcd55eeb3b.mp4'file 'ad6beef4b9e14bcf8f4c07d802cae360.mp4'file '1d15bf4c221c4e429413568d5c2e58e4.mp4' 转码视频格式并设置音频采样率和输出视频尺寸、设置输出帧率: C:\FFMPEG\ffmpeg_x86_4.2.2\bin\ffmpeg.exe -i 1.mp4 -y -qscale 0 -vcodec libx264 -acodec aac -ac 1 -ar 22050 -s 300*300 -r 30 -aspect 1_1.mp4
复制代码


【2】不同分辨率的源视频合成一个视频,设置画面的中心位置


C:\FFMPEG\ffmpeg_x86_4.2.2\bin\ffmpeg.exe -i 1.mp4 -i 1.mpg -i 123.mp4 -f lavfi -i color=black -filter_complex "[0:v]format=pix_fmts=yuva420p,rotate=PI*0/180:c=none:ow=rotw(PI*0/180):oh=roth(PI*0/180),pad=1920:1080:(ow-iw)/2:(oh-ih)/2:black,setpts=PTS-STARTPTS+0/TB[va0];[1:v]format=pix_fmts=yuva420p,rotate=PI*0/180:c=none:ow=rotw(PI*0/180):oh=roth(PI*0/180),pad=1920:1080:(ow-iw)/2:(oh-ih)/2:black,setpts=PTS-STARTPTS+3/TB[va1];[2:v]format=pix_fmts=yuva420p,rotate=PI*0/180:c=none:ow=rotw(PI*0/180):oh=roth(PI*0/180),pad=1920:1080:(ow-iw)/2:(oh-ih)/2:black,setpts=PTS-STARTPTS+7/TB[va2];[3:v]scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2:black,trim=duration=12[over0];[over0][va0]overlay[over1];[over1][va1]overlay[over2];[over2][va2]overlay=format=yuv420[outv];[0:a][1:a][2:a] concat=n=3:v=0:a=1[outa]" -aspect 1920:1080 -vcodec libx264 -map "[outv]" -map "[outa]" -y out.mp4
复制代码


【3】音频混合合成


ffmpeg -i 1.mp3 -i 2.mp3 -filter_complex amix=inputs=2:duration=first:dropout_transition=2 -f mp3 remix.mp3    参数说明:-i 文件 1.mp3 和 2.mp3 为待合成的两个源文件;-filter_complex 过滤器参数;amix=inputs 配置输入的整体样本数;duration,first:长度取决于第一个文件,longest:长度取决于时间最长文件,shortest:长度取决于时间最短文件;dropout_transition:输入流结束时用于体积重新规范化的过渡时间;-f mp3 设置导出文件格式;
复制代码


【4】音频连接合成


ffmpeg -i "concat:headerNew.mp3|006.mp3" -acodec copy demo6.mp3    参数说明:concat 合并文件指令;
复制代码


【5】音频淡出效果


ffmpeg -i bgm3.mp3  -filter_complex afade=t=out:st=16:d=4 bgm31.mp3
参数说明:afade 淡入淡出指令;从 st 秒开始,经过 d 秒钟的淡出效果;
复制代码


【6】使用 FFmpeg concat 过滤器重新编码(有损)


语法有点复杂,但是其实不难。这个方法可以合并不同编码器的视频片段,也可以作为其他方法失效的后备措施。


ffmpeg -i input1.mp4 -i input2.webm -i input3.avi -filter_complex '[0:0] [0:1] [1:0] [1:1] [2:0] [2:1] concat=n=3:v=1:a=1 [v] [a]' -map '[v]' -map '[a]' <编码器选项> output.mkv
复制代码


上面的命令合并了三种不同格式的文件,FFmpeg concat 过滤器会重新编码它们。注意这是有损压缩。


[0:0] [0:1] [1:0] [1:1] [2:0] [2:1] 分别表示第一个输入文件的视频、音频、第二个输入文件的视频、音频、第三个输入文件的视频、音频。concat=n=3:v=1:a=1 表示有三个输入文件,输出一条视频流和一条音频流。[v] [a] 就是得到的视频流和音频流的名字,注意在 bash 等 shell 中需要用引号,防止通配符扩展。


【7】使用 amix 合并两种声音


ffmpeg -i g001_2.wav -i tx.wav -filter_complex amix=inputs=2:duration=longest:dropout_transition=2 tx_new.wav
复制代码

(4)视频倒放

//视频倒放,无音频C:\FFMPEG\ffmpeg_x86_4.2.2\bin\ffmpeg.exe -i 123.mp4 -filter_complex [0:v]reverse[v] -map [v] -preset superfast out.mp4//视频倒放,音频不变C:\FFMPEG\ffmpeg_x86_4.2.2\bin\ffmpeg.exe -i 123.mp4 -vf reverse out.mp4//音频倒放,视频不变C:\FFMPEG\ffmpeg_x86_4.2.2\bin\ffmpeg.exe -i 123.mp4 -map 0 -c:v copy -af "areverse" out.mp4//音视频同时倒放C:\FFMPEG\ffmpeg_x86_4.2.2\bin\ffmpeg.exe -i 123.mp4 -vf reverse -af areverse -preset superfast out.mp4
复制代码

(5)视频转 GIF

1. 最简单的方式ffmpeg -i 123.mp4 out.gif    2.将视频 MP4 转化为 GIFffmpeg -i OUTPUT_VIDEO.mp4 OUTPUT_VIDEO.gif
3.将视频中的一部分转换为GIF// 从视频中第二秒开始,截取时长为3秒的片段转化为 gifffmpeg -t 3 -ss 00:00:02 -i small.mp4 small-clip.gif

4.转化高质量 GIFffmpeg -i OUTPUT_VIDEO.mp4 -b 2048k OUTPUT_VIDEO.gif
5.将 GIF 转化为 MP4
ffmpeg -f gif -i animation.gif animation.mp4ffmpeg -f gif -i animation.gif animation.mpegffmpeg -f gif -i animation.gif animation.webm
6. 设置时间通常我们只需要转换视频的某一个时间片段,所以不能像上图中的命令那样直接转换,需要使用-ss(设置起始时间),-t(设置持续时间)。
ffmpeg -ss 起始时间 -t 持续时间 -i 输入文件 输出文件
比如:ffmpeg -ss 9 -t 5 -i 1.mp4 1.gif,将会从视频的9秒开始截取5秒片段转换为gif图片。-ss也可以设置为00:00:00.000的形式,为小时、分钟、秒、毫秒,例如00:00:09.000。
7. 设置循环次数
-loop 循环次数,比如设置-loop 1,生成的gif图片将只会播放一次,0为无限次(默认)。
ffmpeg -ss 起始时间 -t 持续时间 -i 输入文件 -loop 循环次数 输出文件
比如ffmpeg -ss 9 -t 5 -i 1.mp4 -loop 0 1.gif。
8. 设置缩放
如果是高分辨率视频,可能需要将画面缩放,不然gif图片就太大了,可以使用scale控制。比如scale=iw/2:-1:flags=lanczos(lanczos为缩放算法),将会设置gif图片的宽度为源视频一半,高度为比例缩放,也可以强制设置宽高像素。
ffmpeg -ss 起始时间 -t 持续时间 -i 输入文件 -loop 循环次数 -vf scale=宽:高:flags=lanczos 输出文件
例如ffmpeg -ss 9 -t 5 -i 1.mp4 -loop 0 -vf scale=iw/2:-1:flags=lanczos 1.gif。
9. 设置fps(每秒帧数)设置低一些的fps可以压缩gif的体积,使用fps=指定的fps数值,保持流畅即可。ffmpeg -ss 起始时间 -t 持续时间 -i 输入文件 -loop 循环次数 -vf "scale=宽:高:flags=lanczos,fps=数值" 输出文件
例如ffmpeg -ss 9 -t 5 -i 1.mp4 -loop 0 -vf "scale=iw/2:-1:flags=lanczos,fps=15" 1.gif
10. 裁剪画面
可能我们只需要将视频画面的一部分转成gif图片,可以使用crop,具体为crop=宽度:高度:宽度起始:高度起始,比如crop=200:200:0:0,将会从横向0像素,纵向0像素开始,从画面裁剪200x200的区域。
ffmpeg -ss 起始时间 -t 持续时间 -i 输入文件 -loop 循环次数 -vf "scale=宽:高:flags=lanczos,fps=数值,crop=宽度:高度:宽度起始:高度起始" 输出文件
例如: ffmpeg -ss 9 -t 5 -i 1.mp4 -loop 0 -vf "scale=iw/2:-1:flags=lanczos,fps=15,crop=iw/2:ih:0:0" 1.gif,将裁剪视频的左半边画面。
11. 提高gif画面质量
你可能发现通过上面的方法直接生成的gif图片质量不怎么好,可以使用split和palette过滤器进行改善。
ffmpeg -ss 起始时间 -t 持续时间 -i 输入文件 -loop 循环次数 -vf "scale=宽:高:flags=lanczos,fps=数值,crop=宽度:高度:宽度起始:高度起始,split[s1][s2];[s1]palettegen[p];[s2][p]paletteuse" 输出文件
如ffmpeg -ss 9 -t 5 -i 1.mp4 -loop 0 -vf "scale=iw/2:-1:flags=lanczos,fps=15,crop=iw/2:ih:0:0,split[s1][s2];[s1]palettegen[p];[s2][p]paletteuse" 1.gif。
上面的参数和过滤器可根据自己的需要自由选择及设置。
复制代码

(6)给视频添加图片水印

【1】添加图片水印


//添加图片水印C:/FFMPEG/ffmpeg_x86_4.2.2/bin/ffmpeg.exe -i D:/666.mp4 -vf "movie=image/123.png[wm];[in][wm]overlay=30:10[out]" D:/linux-share-dir/video_file/test/output.mp4 参数解析:1. D:/666.mp4 输入的视频2. image/123.png 要添加进去的图片水印3. D:/linux-share-dir/video_file/test/output.mp4 合成水印之后输出的视频
复制代码




【2】在视频左下角添加 GIF 动态水印


ffmpeg -y -i test2.mp4 -i gnore_loop 0 -i test.gif  -filter_complex overlay=0:H-h test_out2.mp4
复制代码


【3】水印显示时间变化


1. 设置水印显示时长ffmpeg -hide_banner -i big_buck_bunny.mp4 -i doggie2.png -filter_complex "overlay=enable=\'lte(t,5)\'" out.mp4 -y上面命令作用是:让水印只显示5秒,5秒后消失。
2. 设置水印显示时间段ffmpeg -hide_banner -i big_buck_bunny.mp4 -i doggie2.png -filter_complex "overlay=enable=\'between(t,5,10)\'" out.mp4 -y上面的命令作用是:让水印在视频的5~10秒时间段内显示
3. 设置两个水印轮番出现ffmpeg -i big_buck_bunny.mp4 -i doggie1.png -i doggie2.png -filter_complex "overlay=enable=\'lte(mod(t,10),4)\',overlay=enable=\'gt(mod(t,10),6)\'" out.mp4 -y上面的命令作用是:第一个水印显示4秒后消失,2秒后第二个水印显示4秒后消失。这里布置个作业?huaji 请让两个水印一个在左上角,一个在右上角
复制代码


【4】水印位置变化


设置水印随时间向右移动ffmpeg -i big_buck_bunny.mp4 -ignore_loop 0 -i doggie3.gif -lavfi "overlay=x=t*20" -shortest out.mp4 -y上面命令的作用是:让水印每秒向右移动20像素,直到消失。
设置水印每隔10秒钟从左移动右直至消失 ffmpeg -i big_buck_bunny.mp4 -ignore_loop 0 -i doggie3.gif -lavfi "overlay=enable=\'mod(t,10)\':x=\'100*mod(t,10)-w\'" -shortest out.mp4 -y
复制代码


【5】GIF 水印循环播放方式


第一种:设置gif的-ignore_loop为0,让gif保持循环播放即可,命令如下:ffmpeg -hide_banner -i big_buck_bunny.mp4 -ignore_loop 0 -i doggie3.gif -filter_complex  overlay -shortest out.mp4 -y但是这种方式,只适用于gif格式的图像,如果滤镜是一小段视频就无能为力了。
第二种:使用movie滤镜,同样是让gif循环播放,虽然这种方式复杂点,不过这种解决方案支持视频水印,命令如下:ffmpeg -hide_banner -i big_buck_bunny.mp4 -vf "movie=doggie3.gif:loop=0,setpts=N/FRAME_RATE/TB[out];[0:v][out]overlay=x=main_w-overlay_w:y=0" -shortest out.mp4 -y上面的命令有两个地方比较关键:
loop=0,setpts=N/FRAME_RATE/TB :设置水印gif无限循环-shortest :将输出文件的时长设置为第一个视频文件的时长,如果不设置,你会发现命令会一直执行根本不会停下来,因为gif图的循环是无限的这样gif图/短视频就会一直不停的播放了。

希望水印播放一次就不播放了,那就设置上面的eof_action为pass就可以了,如下:ffmpeg -hide_banner -i big_buck_bunny.mp4 -i doggie3.gif -filter_complex "overlay=x=0:y=0:eof_action=pass" out.mp4 -y
如果视频一开始就播放且只播放一次,假如水印比较短可能根本就没被注意就过去了,这时可以设置水印出现的延迟时间,使用-itsoffset选项,如下:ffmpeg -hide_banner -i big_buck_bunny.mp4 -itsoffset 3 -i doggie3.gif -filter_complex "overlay=x=0:y=0:eof_action=pass" out.mp4 -y这样,视频播放3秒后,水印才会出现。
复制代码


【6】水印旋转


如果想实现旋转的功能,需要使用ffmpeg过滤器的链式功能,即:先把作为水印的图片旋转,再覆盖到视频上。
1. 水印旋转一次ffmpeg -i buck.mp4 -i s1.jpg -lavfi "[1:v]format=rgba,rotate='PI/6:c=0x00000000:ow=hypot(iw,ih):oh=ow'[out];[0:v][out]overlay=10:10" out.mp4 -y
思路是:调整水印宽高,根据勾股定律计算图片对角长度(hypot),将这个值设置为水印的宽高,这样,图片无论如何旋转,都不会超过设定的宽高,也就不会出现图片部分丢失的情况了将图片显示的像素格式转换为rgba格式,如果做过前端的小伙伴会很熟悉的,最后的a表示透明度,如此一来,c=0x00000000的作用就是将图片旋转后的背景变为白色且完全透明,这样就不会遮挡视频了
2. 让旋转停不下,具体命令如下:ffmpeg -i buck.mp4 -loop 1 -i s1.jpg -lavfi "[1:v]format=rgba,rotate='PI/2*t:c=0x00000000:ow=hypot(iw,ih):oh=ow'[out];[0:v][out]overlay=10:10" -shortest out.mp4 -y这次水印图片前面添加了-loop 1,正常情况下水印图片默认在播放一次后就停下来,保留最后一帧,所以要让水印图片保持循环才行。
复制代码

(7)使用 ffprobe 获取媒体信息

【1】输出媒体信息


PS D:\> ffprobe -i .\jiyi.mp4ffprobe version 4.2.2 Copyright (c) 2007-2019 the FFmpeg developers  built with gcc 9.2.1 (GCC) 20200122  configuration: --disable-static --enable-shared --enable-gpl --enable-version3 --enable-sdl2 --enable-fontconfig --enable-gnutls --enable-iconv --enable-libass --enable-libdav1d --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libtheora --enable-libtwolame --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib --enable-gmp --enable-libvidstab --enable-libvorbis --enable-libvo-amrwbenc --enable-libmysofa --enable-libspeex --enable-libxvid --enable-libaom --enable-libmfx --enable-amf --enable-ffnvcodec --enable-cuvid --enable-d3d11va --enable-nvenc --enable-nvdec --enable-dxva2 --enable-avisynth --enable-libopenmpt  libavutil      56. 31.100 / 56. 31.100  libavcodec     58. 54.100 / 58. 54.100  libavformat    58. 29.100 / 58. 29.100  libavdevice    58.  8.100 / 58.  8.100  libavfilter     7. 57.100 /  7. 57.100  libswscale      5.  5.100 /  5.  5.100  libswresample   3.  5.100 /  3.  5.100  libpostproc    55.  5.100 / 55.  5.100Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '.\jiyi.mp4':  Metadata:    major_brand     : isom    minor_version   : 512    compatible_brands: isomiso2avc1mp41    encoder         : Lavf58.29.100  Duration: 00:00:54.15, start: 0.000000, bitrate: 574 kb/s    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709), 960x544, 518 kb/s, 29.97 fps, 29.97 tbr, 19200 tbn, 38400 tbc (default)    Metadata:      handler_name    : Core Media Video    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, mono, fltp, 47 kb/s (default)    Metadata:      handler_name    : Core Media AudioPS D:\>
复制代码


【2】输出媒体信息


PS D:\> ffprobe -v quiet -of json -i .\jiyi.mp4  -show_streams
{ "streams": [ { "index": 0, "codec_name": "h264", "codec_long_name": "H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10", "profile": "High", "codec_type": "video", "codec_time_base": "8123/486900", "codec_tag_string": "avc1", "codec_tag": "0x31637661", "width": 960, "height": 544, "coded_width": 960, "coded_height": 544, "has_b_frames": 1, "pix_fmt": "yuv420p", "level": 31, "color_range": "tv", "color_space": "bt709", "color_transfer": "bt709", "color_primaries": "bt709", "chroma_location": "left", "refs": 1, "is_avc": "true", "nal_length_size": "4", "r_frame_rate": "30000/1001", "avg_frame_rate": "243450/8123", "time_base": "1/19200", "start_pts": 0, "start_time": "0.000000", "duration_ts": 1039744, "duration": "54.153333", "bit_rate": "518796", "bits_per_raw_sample": "8", "nb_frames": "1623", "disposition": { "default": 1, "dub": 0, "original": 0, "comment": 0, "lyrics": 0, "karaoke": 0, "forced": 0, "hearing_impaired": 0, "visual_impaired": 0, "clean_effects": 0, "attached_pic": 0, "timed_thumbnails": 0 }, "tags": { "language": "und", "handler_name": "Core Media Video" } }, { "index": 1, "codec_name": "aac", "codec_long_name": "AAC (Advanced Audio Coding)", "profile": "LC", "codec_type": "audio", "codec_time_base": "1/44100", "codec_tag_string": "mp4a", "codec_tag": "0x6134706d", "sample_fmt": "fltp", "sample_rate": "44100", "channels": 1, "channel_layout": "mono", "bits_per_sample": 0, "r_frame_rate": "0/0", "avg_frame_rate": "0/0", "time_base": "1/44100", "start_pts": 0, "start_time": "0.000000", "duration_ts": 2387471, "duration": "54.137664", "bit_rate": "47025", "max_bit_rate": "47025", "nb_frames": "2332", "disposition": { "default": 1, "dub": 0, "original": 0, "comment": 0, "lyrics": 0, "karaoke": 0, "forced": 0, "hearing_impaired": 0, "visual_impaired": 0, "clean_effects": 0, "attached_pic": 0, "timed_thumbnails": 0 }, "tags": { "language": "und", "handler_name": "Core Media Audio" } } ]}
复制代码

(8)采集桌面屏幕、摄像头保存为视频

【1】 列出当前电脑上音频设备、摄像头设备列表


C:/FFMPEG/ffmpeg_x86_4.2.2/bin/ffmpeg.exe -list_devices true -f dshow -i dummy
复制代码


【2】录制桌面全屏图像+音频


C:/FFMPEG/ffmpeg_x86_4.2.2/bin/ffmpeg.exe -f gdigrab -i desktop -f dshow -i audio="@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{6E399CBA-5F7D-443F-9071-1657DE0F5483}" -vcodec libx264 -acodec libmp3lame -s 1280x720 -r 15 D:/linux-share-dir/video_file/6666.mp4 其中: audio= "" 这里填麦克风设备. 第一条指令就是查询电脑上音频设备。把名字复制过来即可。
复制代码


【3】录制摄像头+音频


示例1:C:/FFMPEG/ffmpeg_x86_4.2.2/bin/ffmpeg.exe -f dshow -i video="@device_pnp_\\?\usb#vid_5986&pid_2113&mi_00#6&3326332&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global" -f dshow -i audio="@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{6E399CBA-5F7D-443F-9071-1657DE0F5483}" -vcodec libx264 -acodec libmp3lame -s 1280x720 -r 15 D:/linux-share-dir/video_file/6666.mp4  其中:video="" 视频摄像头设备名称audio="" 视频音频设备名称  示例2:C:/FFMPEG/ffmpeg_x86_4.2.2/bin/ffmpeg.exe -f dshow -i video="@device_pnp_\\?\usb#vid_5986&pid_2113&mi_00#6&3326332&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global" -f dshow -i audio="@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{6E399CBA-5F7D-443F-9071-1657DE0F5483}" D:/linux-share-dir/video_file/test/202108161456.mp4
复制代码


【4】 采集桌面指定区域(无音频)


C:/FFMPEG/ffmpeg_x86_4.2.2/bin/ffmpeg.exe -f gdigrab -framerate 6 -offset_x 50 -offset_y 50 -video_size 400x400 -i desktop D:/linux-share-dir/video_file/test/202108161448.mp4
复制代码



【5】采集桌面指定区域+音频


//录制指定范围--采集图像+音频C:/FFMPEG/ffmpeg_x86_4.2.2/bin/ffmpeg.exe -f gdigrab -framerate 6 -offset_x 50 -offset_y 50 -video_size 400x400 -i desktop -f dshow -i audio="@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{6E399CBA-5F7D-443F-9071-1657DE0F5483}" D:/linux-share-dir/video_file/test/202108161514.mp4
复制代码


【6】案例


列出设备列表ffmpeg -list_devices true -f dshow -i dummy
全屏录像 ( dshow录屏, H264编码 )ffmpeg -f dshow -i video="screen-capture-recorder" -f dshow -i audio="virtual-audio-capturer" -vcodec libx264 -acodec libmp3lame -s 1280x720 -r 15 e:/temp/temp.mkv
全屏录像 ( gdigrab录屏, H264编码 )ffmpeg -f gdigrab -i desktop -f dshow -i audio="virtual-audio-capturer" -vcodec libx264 -acodec libmp3lame -s 1280x720 -r 15 e:/temp/temp.mkv
全屏录像 ( gdigrab录屏, vp9编码 )( 注 : dshow不支持vp9 )ffmpeg -f gdigrab -i desktop -f dshow -i audio="virtual-audio-capturer" -vcodec libvpx-vp9 -acodec libmp3lame -s 1280x720 -r 15 e:/temp/temp.mkv
区域录像 ( 起点:100,60 width:600 width:480 )ffmpeg -f gdigrab -i desktop -f dshow -i audio="virtual-audio-capturer" -vcodec libx264 -acodec libmp3lame -video_size 600x480 -offset_x 100 -offset_y 60 -r 15 e:/temp/temp.mkvC:/FFMPEG/ffmpeg_x86_4.2.2/bin/ffmpeg.exe -f dshow -i video="screen-capture-recorder" screen-capture.mp4



window (安装dshow)ffmpeg -rtbufsize 100M -f dshow -i video="screen-capture-recorder":audio="virtual-audio-capturer" -vcodec libx264 -preset veryfast -crf 22 -tune:v zerolatency -pix_fmt yuv420p -s '+size+r' -acodec libmp3lame -t ' + str(times) + ' ' + filename


列出当前电脑上音频设备、摄像头设备列表C:/FFMPEG/ffmpeg_x86_4.2.2/bin/ffmpeg.exe -list_devices true -f dshow -i dummy
//录制全屏C:/FFMPEG/ffmpeg_x86_4.2.2/bin/ffmpeg.exe -f gdigrab -i desktop -f dshow -i audio="@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{6E399CBA-5F7D-443F-9071-1657DE0F5483}" -vcodec libx264 -acodec libmp3lame -s 1280x720 -r 15 D:/linux-share-dir/video_file/6666.mp4 C:/FFMPEG/ffmpeg_x86_4.2.2/bin/ffmpeg.exe -f dshow -i video="screen-capture-recorder" screen-capture.mp4



window (安装dshow)ffmpeg -rtbufsize 100M -f dshow -i video="screen-capture-recorder":audio="virtual-audio-capturer" -vcodec libx264 -preset veryfast -crf 22 -tune:v zerolatency -pix_fmt yuv420p -s '+size+r' -acodec libmp3lame -t ' + str(times) + ' ' + filename


列出当前电脑上音频设备、摄像头设备列表C:/FFMPEG/ffmpeg_x86_4.2.2/bin/ffmpeg.exe -list_devices true -f dshow -i dummy
//录制全屏C:/FFMPEG/ffmpeg_x86_4.2.2/bin/ffmpeg.exe -f gdigrab -i desktop -f dshow -i audio="@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{6E399CBA-5F7D-443F-9071-1657DE0F5483}" -vcodec libx264 -acodec libmp3lame -s 1280x720 -r 15 D:/linux-share-dir/video_file/6666.mp4 这是OK的--录制全屏无音频C:/FFMPEG/ffmpeg_x86_4.2.2/bin/ffmpeg.exe -f gdigrab -framerate 10 -i desktop D:/linux-share-dir/video_file/test/666.mp4

这是OK的---但是捕获的位置有问题C:/FFMPEG/ffmpeg_x86_4.2.2/bin/ffmpeg.exe -f dshow -i video="screen-capture-recorder" -crf 22 -r 10 D:/linux-share-dir/video_file/test/666.mp4


C:/FFMPEG/ffmpeg_x86_4.2.2/bin/ffmpeg.exe -f gdigrab -i desktop -f dshow -i audio="@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{6E399CBA-5F7D-443F-9071-1657DE0F5483}" -vcodec libx264 -acodec aac -s 1280x720 -r 10 D:/linux-share-dir/video_file/6666.mp4 其中: audio= "" 这里填麦克风设备. 第一条指令就是查询电脑上音频设备。把名字复制过来即可。

C:/FFMPEG/ffmpeg_x86_4.2.2/bin/ffmpeg.exe -f gdigrab -i desktop -f dshow -i audio="麦克风阵列 (Conexant SmartAudio HD)" -vcodec libx264 -acodec aac -s 1280x720 -r 10 D:/linux-share-dir/video_file/test/6666.mp4

C:/FFMPEG/ffmpeg_x86_4.2.2/bin/ffmpeg.exe -f gdigrab -i desktop -f dshow -i audio="麦克风阵列 (Conexant SmartAudio HD)" -vcodec libx264 -acodec aac -video_size 100x100 -offset_x 500 -offset_y 500 -r 10 D:/linux-share-dir/video_file/6666.mp4 //采集摄像头 C:/FFMPEG/ffmpeg_x86_4.2.2/bin/ffmpeg.exe -f dshow -i video="Integrated Camera" -f dshow -i audio="virtual-audio-capturer" D:/linux-share-dir/video_file/test/202108161421.mp4

//采集摄像头和电脑音频. 这是OK的C:/FFMPEG/ffmpeg_x86_4.2.2/bin/ffmpeg.exe -f dshow -i video="Integrated Camera" -f dshow -i audio="@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{6E399CBA-5F7D-443F-9071-1657DE0F5483}" D:/linux-share-dir/video_file/test/202108161443.mp4


//录制指定范围--采集图像--这是OK的C:/FFMPEG/ffmpeg_x86_4.2.2/bin/ffmpeg.exe -f gdigrab -framerate 6 -offset_x 50 -offset_y 50 -video_size 400x400 -i desktop D:/linux-share-dir/video_file/test/202108161448.mp4

//采集摄像头和电脑音频. 这是OK的C:/FFMPEG/ffmpeg_x86_4.2.2/bin/ffmpeg.exe -f dshow -i video="@device_pnp_\\?\usb#vid_5986&pid_2113&mi_00#6&3326332&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global" -f dshow -i audio="@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{6E399CBA-5F7D-443F-9071-1657DE0F5483}" D:/linux-share-dir/video_file/test/202108161456.mp4

//录制指定范围--采集图像+音频C:/FFMPEG/ffmpeg_x86_4.2.2/bin/ffmpeg.exe -f gdigrab -framerate 6 -offset_x 50 -offset_y 50 -video_size 400x400 -i desktop -f dshow -i audio="@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{6E399CBA-5F7D-443F-9071-1657DE0F5483}" D:/linux-share-dir/video_file/test/202108161514.mp4

fmpeg.exe -f dshow -i video=\"@device:pnp:\\\\?\\usb#vid_5986&pid_2113&mi_00#6&3326332&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\\global\" -f dshow -i audio=\"麦克风阵列 (Conexant SmartAudio HD)\" C:/Users/11266/Videos/2021-8-16-16-35-44-426.mp4\n"
复制代码

(9)视频音频替换

【1】去掉视频原声再添加新的音频


(1)去掉视频原声:C:\FFMPEG\ffmpeg_x86_4.2.2\bin>ffmpeg.exe -i 123.mp4 -c:v copy -an out1.mp4 (2)合并音频到视频:C:\FFMPEG\ffmpeg_x86_4.2.2\bin>ffmpeg.exe -i out1.mp4 -i 花僮-笑纳.mp3 out2.mp4 可以指定合成时间:C:\FFMPEG\ffmpeg_x86_4.2.2\bin>ffmpeg.exe -i out1.mp4 -i 花僮-笑纳.mp3 -t 30 out3.mp4其中-t参数是指定时间.单位是秒.
复制代码


【2】保留视频原生添加新的音频


ffmpeg -i 花僮-笑纳.mp3 -i 123.mp4 -filter_complex amix=inputs=2 output.mp4
复制代码


【3】替换原来影片的音讯


ffmpeg -i tx_new.wav -i r001_2.flv -shortest -c copy n001_2.flv
复制代码

(10)给视频添加文字水印

【1】在图片的左上角(横坐标 10.纵坐标 100)添加水印:


wbyq@wbyq:/mnt/hgfs/linux-share-dir$ ffmpeg -i 123.mp4 -vf "drawtext=fontfile=simhei.ttf: text=‘DS小龙哥’:x=100:y=10:fontsize=24:fontcolor=white:shadowy=2" output.mp4 参数说明fontfile:字体类型  --simhei.ttf如果没有找到,可以在windows下的Fonts目录下拷贝过来,放到程序执行目录下-text:要添加的文字内容fontsize:字体大小fontcolor:字体颜色
复制代码



【2】常见案例


水印位置:(x,y)=(10,10)<=(left,top)距离左侧、顶部各10像素;                     贴图水印时间显示ffmpeg -i C:\Users\heshiping\Desktop\videoDown\2.mp4 -i C:\Users\heshiping\Desktop\videoDown\4.jpg -filter_complex  overlay=x='if(between(t,15,30),150,NAN)':0 -threads 5  -preset ultrafast  C:\Users\heshiping\Desktop\videoDown\15-30s.mp4  透明度ffmpeg -i C:\Users\heshiping\Desktop\videoDown\2.mp4 -i C:\Users\heshiping\Desktop\videoDown\4.jpg -filter_complex  "[1:v]colorkey=0x000000:0.6:1.0[ckout];[0:v][ckout]overlay=10:10[out]" -map "[out]"   -threads 5  -preset ultrafast C:\Users\heshiping\Desktop\videoDown\xuanzhuans.mp4 ffmpeg -i C:\Users\heshiping\Desktop\videoDown\2.mp4 -i C:\Users\heshiping\Desktop\videoDown\4.jpg -filter_complex  "[1:v]scale=100:100[wm];[0:v][wm]overlay=x='if(between(t,15,30),150,NAN)':50[HSP];[HSP]colorkey=0x000000:0.6:1.0[ckouts];[0:v][ckouts]overlay=150:50[out]" -map "[out]"  -threads 5  -preset ultrafast C:\Users\heshiping\Desktop\videoDown\缩放透明度时间显示位置.mp4 合成ffmpeg -i C:\Users\heshiping\Desktop\videoDown\2.mp4 -i C:\Users\heshiping\Desktop\videoDown\4.jpg -filter_complex  "[1:v]scale=500:500[sf];[0:v][sf]overlay=x='if(between(t,10,30),300,NAN)':150[cc];[cc]colorkey=0x000000:0.6:1.0[tmd];[0:v][tmd]overlay=300:150[out]" -map "[out]" -threads 5  -preset ultrafast  -max_muxing_queue_size 1024 C:\Users\heshiping\Desktop\videoDown\111.mp4 ffmpeg -i C:\Users\heshiping\Desktop\videoDown\2.mp4 -i C:\Users\heshiping\Desktop\videoDown\4.jpg -filter_complex  "[1:v]scale=500:500[sf];[0:v][sf]overlay=x='if(between(t,10,30),300,NAN)':150[cc];[cc]colorkey=0x000000:0.6:1.0[tmd];[0:v][tmd]overlay=300:150[out]"-map "[out]"   -threads 5  -preset ultrafast C:\Users\heshiping\Desktop\videoDown\final.mp4 ffmpeg -i C:\Users\heshiping\Desktop\videoDown\2.mp4 -i C:\Users\heshiping\Desktop\videoDown\4.jpg -filter_complex  "[1:v]scale=500:500[sf];[0:v][sf]overlay=x='if(between(t,10,30),300,NAN)':150[cc];[cc]colorkey=0x000000:0.6:1.0[tmd];[0:v][tmd]overlay=300:150[out]" -map "[out]" -threads 5  -preset ultrafast  -max_muxing_queue_size 1024 C:\Users\heshiping\Desktop\videoDown\111.mp4  //垂直翻转ffmpeg -i C:\\Users\\heshiping\\Desktop\\videoDown\\1.jpg -vf vflip -y C:\\Users\\heshiping\\Desktop\\videoDown\\1s.jpg//水平翻转ffmpeg -i C:\\Users\\heshiping\\Desktop\\videoDown\\66.webm -vf hflip -y C:\\Users\\heshiping\\Desktop\\videoDown\\66.webmffmpeg -i C:\Users\heshiping\Desktop\videoDown\4.jpg -vf vflip -y C:\Users\heshiping\Desktop\videoDown\vflip.jpg delogo 去除视频某处的logo。其实实现原理就是将给出区域进行高斯模糊处理。delogo=x=0:y=0:w=100:h=77:band=10x,y,w,h 构成一个Rect,band是模糊强度。  removelogo ,消除logo水印,和delogo 类似。  视频水印 透明度ffmpeg -i C:\Users\heshiping\Desktop\videoDown\21.mp4 -itsoffset 5 -i C:\Users\heshiping\Desktop\videoDown\c.webm -filter_complex [1:v]scale=900:500[sf];[sf]format=yuva444p,colorchannelmixer=aa=0.5[sf];[0:v][sf]overlay=x='if(between(t,5,13),0,NAN)':0 -y C:\Users\heshiping\Desktop\videoDown\eric1.mp4 视频水印旋转透明ffmpeg -i  C:\Users\heshiping\Desktop\videoDown\21.mp4 -itsoffset 10 -i C:\Users\heshiping\Desktop\videoDown\c.webm  -filter_complex [1:v]scale=300:200[sf];[sf]format=yuva444p,colorchannelmixer=aa=0.6[sf];[sf]rotate='45*PI/180:ow=hypot(iw,ih):oh=ow:c=none'[sf];[0:v][sf]overlay=x='if(between(t,10,18),100,NAN)':100 C:\Users\heshiping\Desktop\videoDown\ccccc.mp4 -y   转场滤镜ffmpeg -i /data/video/tencent/动漫/a8dukd400400_泽塔奥特曼_普通话版_18_mp4/a8dukd400400_泽塔奥特曼_普通话版_18_001121_001142.mp4 -i /data/video/tencent/动漫/a8dukd400400_泽塔奥特曼_普通话版_18_mp4/a8dukd400400_泽塔奥特曼_普通话版_18_001100_001121.mp4 -filter_complex "[0:v]split[v0a][v0b];[v0a]trim=0:20[v0020];[v0b]trim=20:21,setpts=PTS-STARTPTS[v02021];[1:v]split[v1a][v1b];[v1a]trim=0:20[v1020];[v1b]trim=20:21,setpts=PTS-STARTPTS[v12021];[v02021][v1020]gltransition=duration=2:source=/usr/local/src/ffmpeg-gl-transition/gl-transitions/transitions/InvertedPageCurl.glsl[g01];[v0020][g01][v12021]concat=n=3[outv];[outv]scale=1920:1080[outv]" -map "[outv]" -c:v libx264 -profile:v baseline -preset slow -movflags faststart -pix_fmt yuv420p -threads 5 -preset ultrafast /data/video/ovwq2f20210322171622763.mp4 -y  任意位置文字水印 ffmpeg -i C:\Users\heshiping\Desktop\videoDown\2021.mp4 -vf "drawtext=fontfile=MengNaJianCaiYun-2.ttf: text='heshiping':x=100:y=100:fontsize=29:fontcolor=yellow:shadowy=2" -b:v 3000k C:\Users\heshiping\Desktop\videoDown\222222.mp4 -y  滚动文字水印ffmpeg -i C:\Users\heshiping\Desktop\videoDown\2021.mp4 -vf "drawtext=fontfile=Arial.ttf: text='hu': y=h-line_h-10:x=(mod(2*n\,w+tw)-tw):fontsize=34:fontcolor=yellow:shadowy=2" -b:v 3000k C:\Users\heshiping\Desktop\videoDown\222222.mp4 -y 底部文字水印ffmpeg -i C:\Users\heshiping\Desktop\videoDown\2021.mp4 -vf "drawtext=fontfile=Arial.ttf:text='pruduction by http\://baidu.com':y=h-line_h-20:x=(w-text_w)/2:fontsize=34:fontcolor=yellow:shadowy=2" -b:v 3000k C:\Users\heshiping\Desktop\videoDown\222222.mp4 -y 水平运动ffmpeg -y -i demo.mp4 -vf drawtext=arialbd.ttf:text=HelloWorld:x=w-t*5:fontcolor=red:fontsize=30 demo_drawtext_h_dyn.mp4 垂直运动ffmpeg -y -i demo.mp4 -vf drawtext=arialbd.ttf:text=HelloWorld:x=w/2:y=h-t*5:fontcolor=red:fontsize=30 demo_drawtext_v_dyn.mp4
复制代码

(11)视频剪切

【1】案例 1


ffmpeg.exe -ss 10 -t 15 -accurate_seek -i love.flv -codec copy -avoid_negative_ts 1 cut.flv 参数解释:   ffmpeg.exe -ss <起始时间-秒> -t <向后截取-秒> -accurate_seek -i <输入视频文件名称> -codec copy -avoid_negative_ts 1 <输出视频文件名称> 可以单独指定音频和视频参数:-vcodec copy  保留原视频帧率-acodec copy  保留原视频音频采样率和通道数-codec copy   这一条指令包含了上面两条指令
复制代码


【2】案例 2


ffmpeg -i input.mp4 -ss 00:00:00 -t 10 out.ts-i : 指定视频-ss : 开始时间-t : 指定裁剪的秒数
复制代码


【3】案例 3


ffmpeg -i organ.mp3 -ss 00:00:xx -t 120 output.mp3
参数说明:-i 文件,orgin.mp3 为待处理源文件;-ss 裁剪时间,后跟裁剪开始时间,以及 -t 裁剪时间;output.mp3 为处理结果文件;
复制代码

(12)获取 flv 视频格式的时长

flv 格式的视频不能像其他视频一样直接通过 ffprobe 输出的 json 获取,可以通过它的命令行输出截取时间段转换得到时间。


    QProcess process;    process.setProcessChannelMode(QProcess::MergedChannels);    process.start("C:/FFMPEG/ffmpeg_x86_4.2.2/bin/ffprobe.exe -i D:/test1080.flv");    process.waitForFinished();    process.waitForReadyRead();    QString str  = process.readAllStandardOutput();    process.close();     //分析字符串    const char *src=str.toStdString().c_str();    char *p1=strstr(src,"Duration");    if(p1)    {        int addr=p1-src;        str = str.mid(addr+10);        str =str.section(',', 0,0);         qDebug("视频的时长(标准时间):%s",str.toStdString().c_str());         //解析数据        QTime t1=QTime::fromString(str);        int time_ms=t1.hour()*60*60*1000+t1.minute()*60*1000+t1.second()*1000+t1.msec();        qDebug()<<"最视频的时长(MS):"<<time_ms;         //反向解析回来对比        qDebug()<<"还原视频的时长(标准时间):"<<QTime(0,0,0,0).addMSecs(int(time_ms)).toString(QString::fromLatin1("HH:mm:ss.zzz"));    }
复制代码


输出结果:


视频的时长(标准时间):00:06:37.15最视频的时长(MS): 397150还原视频的时长(标准时间): "00:06:37.150"
复制代码

(13)视频实现各种特效

//渐入ffmpeg -i in.mp4 -vf fade=in:0:90 out.mp4                 //黑白                    ffmpeg -i in.mp4 -vf lutyuv="u=128:v=128" out.mp4   //锐化ffmpeg -i in.mp4 -vf unsharp=luma_msize_x=7:luma_msize_y=7:luma_amount=2.5 out.mp4   //反锐化ffmpeg -i in.mp4 -vf unsharp=7:7:-2:7:7:-2 out.mp4 //渐晕ffmpeg -i in.mp4 -vf vignette=PI/4 out.mp4//闪烁渐晕ffmpeg -i in.mp4 -vf vignette='PI/4+random(1)*PI/50':eval=frame out.mp4//视频颤抖ffmpeg -i in.mp4 -vf crop="in_w/2:in_h/2:(in_w-out_w)/2+((in_w-out_w)/2)*sin(n/10):(in_h-out_h)/2+((in_h-out_h)/2)*sin(n/7)" out.mp4  //色彩变幻ffmpeg -i in.mp4 -vf hue="H=2*PI*t:s=sin(2*PI*t)+1" out.mp4//模糊处理ffmpeg -i in.mp4 -vf boxblur=5:1:cr=0:ar=0 out.mp4//镜像翻转ffmpeg -i in.mp4 -vf crop=iw/2:ih:0:0,split[left][tmp];[tmp]hflip[right];[left]pad=iw*2[a];[a][right]overlay=w out.mp4//水平翻转ffmpeg -i in.mp4 -vf geq=p(W-X\\,Y) out.mp4//垂直翻转ffmpeg -i in.mp4 -vf vflip out.mp4//浮雕效果ffmpeg -i in.mp4 -vf format=gray,geq=lum_expr='(p(X,Y)+(256-p(X-4,Y-4)))/2' out.mp4//均匀噪声ffmpeg -i in.mp4 -vf noise=alls=20:allf=t+u out.mp4
复制代码

(14)转为关键帧(实现精确剪切)

平时剪辑视频,可能有些视频裁剪后的效果,如期望一致,00 秒开始,30 秒结束,总共 30 秒的视频,但是有些视频裁剪后你会发现可能开始和结束都不是很准确,有可能是从 00 秒开始,33 秒结束。这是为什么呢? 因为这些视频里 30 秒处地方刚好不是关键帧,而 ffmpeg 会在你输入的时间点附近调整到最接近的关键帧处,然后做接下来的事情。如果你不懂什么是关键帧,没关系,这也不影响你使用这个命令。 如果你的项目要求能够接受几秒的误差,那么这个命令完全就可以满足你的需要,接下来的内容你也没有必要往下看了。 如果你的项目里要求很严格,一定要到确定的时间。那么就要用另外一种方式。 上面的造成那样的原因是所选的时间不是关键帧,那如果我们将输入的视频先转换成所有的帧都为关键帧的视频,其实就是将所有的帧的编码方式转为帧内编码


ffmpeg -i r001.flv -strict -2 -qscale 0 -intra r002.flv # 转换关键帧 帧内编码
复制代码


剪出视频前 6 秒


ffmpeg -t 00:00:06 -i r002.flv -vcodec copy -acodec copy r001_1.flv# 指定开始时间和结束时间# ffmpeg -ss 00:00:00 -t 00:00:06 -i r002.flv -vcodec copy -acodec copy r001_1.flv# -ss 指定从什么时间开始# -t 指定需要截取多长时间# -i 指定输入文件
复制代码

(15)从视频中提取音频文件

# 从r002.mp4视频中提取音频,文件名字为r002.wav,格式为wavffmpeg -i g001_2.flv  -vn -acodec copy g001_2.wav
复制代码

(16)调整音频音量

这是改变音量的命令参数,在合成音频后,可能就是原视频声音很大,但是特效声音小,导致听起来忽大忽小,这种情况下可以统一调整一下音量。


0.5倍ffmpeg -i input.wav -af "volume=0.5" output.wav 1.5倍ffmpeg -i input.wav -af "volume=1.5" output.wav 使用分貝ffmpeg -i input.wav -af "volume=5dB" output.w
复制代码

(17)给视频添加 ASS 字幕文件

ffmpeg -i 001.mp4 -vf ass=demo.ass -b:v 3000K r001.flv
复制代码

(18)视频中加入动画

【1】在视频第 6 秒添加动画


ffmpeg -re -i n001_2.flv -vf "movie=dianzan.mov,scale=200*200[test]; [in][test] overlay=x=400:y=100:eof_action=2 [out]" -vcodec libx264 g001_2.flv#或者使用 gif 也可以 0 重复 1 不重复
复制代码


命令解释: 给 r001_2 视频加入动图,x,y 代表坐标,eof_action 表示动图结束后的动作,0 代表重复前一帧,1 代表停止所有流,2 代表保留主图层。

(19)给视频添加跑马灯效果(滚动字幕)

【1】从左往右滚


ffmpeg -i input.mp4 -vf "drawtext=text=string1 string2 string3 string4 string5 string6 string7 :expansion=normal:fontfile=foo.ttf: y=h-line_h-10:x=(mod(5*n\,w+tw)-tw): fontcolor=white: fontsize=40: shadowx=2: shadowy=2" output.mp4
复制代码


【2】从右往左滚


ffmpeg -i input.mp4 vf "drawtext=text=string1:fontfile=foo.ttf:y=h-line_h-10:x=w-(t-4.5)*w/5.5:fontcolor=white:fontsize=40:shadowx=2:shadowy=2" output.mp4
复制代码


【3】从右往左滚,单次滚动时长 10 秒,间隔 30 秒滚一次


ffmpeg -i input.mp4 -filter:v drawtext="fontfile=Microsoft YaHei Mono.ttf:text='Hello World':fontcolor=white@1.0:fontsize=36:y=h-line_h-10:x=w-tw-w/10*mod(t\,30):enable=gt(mod(t\,20)\,10)" -codec:v libx264 -codec:a copy -y output.mp4
复制代码

(20)FFMPEG 使用 GPU 加速转码处理视频

【1】软件硬件编码区别


视频转码时如果遇见视频比较大、时长很长的时候,转码压制需要等待很久且及占用 cpu,所以就在想有没有什么办法可以加速转码进度呢 ,故本篇文章记录 FFMPEG 如何调用显卡对转换编码格式或者压制进行加速。


软硬编解码的区分:软编码:使用 CPU 进行编码硬编码:使用非 CPU 进行编码,如显卡 GPU、专用的 DSP、FPGA、ASIC 芯片等


软硬编解码的区别:软编码:实现直接、简单,参数调整方便,升级易,但 CPU 负载重,性能较硬编码低,低码率下质量通常比硬编码要好一点。硬编码:性能高,低码率下通常质量低于软编码器,但部分产品在 GPU 硬件平台移植了优秀的软编码算法(如 X264)的,质量基本等同于软编码。


【2】查看支持的硬件加速方式


D:\out>ffmpeg -hwaccels    Hardware acceleration methods:cudadxva2qsvd3d11vaqsvcuvid
复制代码


以上输出代表系统所支持的硬件加速方式,后续会用到。


硬编码后缀解释


qsv:intel 显卡的快速视频同步技术(quick sync video)


nvenc:nvidia 显卡的硬件视频编码器(nvidia hardware video encoder)


cuvid:nvdec 的旧称,只有解码端。


cuda: 同上


amf:amd 显卡的 amf 硬件编码器(amd hardware encoder)


基本上所有的 Intel 电脑都支持 qsv 方式。


【3】硬件加速命令


ffmpeg -hwaccel cuvid -c:v h264_cuvid -i input.mp4 -c:v h264_nvenc -b:v 2048k -s 1920x1080 output.mp4
复制代码


常用命令参数解释-hwaccel cuvid:使用 cuvid 进行硬件加速-c:v h264_cuvid:使用 h264_cuvid 进行解码-c:v h264_nvenc:使用 h264_nvenc 进行编码(nvidia 硬件加速 x265)-b:v 2000k:比特率,值越大约清晰。-s 1920x1080:分辨率-b:v 3500K :视频平均比特率为 3500K-bufsize 6000K:缓存区大小 6000K,建议设定为 当前码率帧率 5,也许这里的 2pass 是针对缓冲区的,缓存未来 5s-maxrate 5000K:最大码率为 5000K,每帧的最高码率不超过这个数值-preset slow:预设方案是 slow,slow 已经是最好的选项了-pix_fmt p010le:输出的像素格式是 p010le 也就 10bit,只有新的硬件支持,例如:970m 不支持,1070 可以支持


【4】使用 CUDA 与 CUVID 解码


1. 使用 CUDA 的解码示例:ffmpeg -hwaccel cuda -i input output
2. 使用 CUVID 的解码示例:ffmpeg -c:v h264_cuvid -i input output
3. 使用 NVDEC 和 NVENC 进行全硬件转码:ffmpeg -hwaccel cuda -hwaccel_output_format cuda -i input -c:v h264_nvenc -preset slow output
4. 如果 ffmpeg 是在支持 libnpp 的情况下编译的,则它可用于将基于 GPU 的缩放器插入链中:ffmpeg -hwaccel_device 0 -hwaccel cuda -i input -vf scale_npp=-1:720 -c:v h264_nvenc -preset slow output.mkv该-hwaccel_device选项可用于指定 ffmpeg 中硬解码要使用的 GPU。
复制代码


【5】使用 qsv 解码


1. 编码使用硬件ffmpeg.exe -i 20180206210632.mp4 -vcodec h264_qsv -f mp4 20180206210632-2.mp4
2. 解码也指定硬件解码ffmpeg.exe -c:v h264_qsv -i 20180206210632.mp4 -vcodec h264_qsv -f mp4 20180206210632-3.mp4
3. 指定硬件加速qsvffmpeg.exe -hwaccel qsv -c:v h264_qsv -i 20180206210632.mp4 -vcodec h264_qsv -f mp4 20180206210632-4.mp4手机拍摄的视频上面转换报错。因为手机拍摄视频带有旋转信息,添加输入参数-noautorotate后为:ffmpeg.exe -hwaccel qsv -c:v h264_qsv -noautorotate -i 20180206210632.mp4 -vcodec h264_qsv -f mp4 20180206210632-5.mp4
复制代码


【6】案例


剪切视频片段如果输入的视频格式和输出的视频格式相同. 可以直接采用 -vcodec copy -acodec copy  参数. 可以加快时间ffmpeg -hwaccel  dxva2 -ss 00:00:10.100 -t 00:00:15.100 -i "D:/test1080.flv" -vcodec copy -acodec copy "D:/linux-share-dir/video_file/output1.mp4"
如果输入的视频格式和输出的视频格式不相同,就要重新编码. 不能采用 -vcodec copy -acodec copy 参数,否则会报错.
ffmpeg -hwaccel dxva2 -ss 00:00:10.100 -t 00:00:15.100 -i "D:/Video_WMV视频文件.wmv" -c:v h264_qsv "D:/linux-share-dir/video_file/output1.mp4"
ffmpeg -hwaccel dxva2 -ss 00:00:10.100 -t 00:00:15.100 -i "D:/test1080.flv" -c:v h264_qsv "D:/linux-share-dir/video_file/output1.mp4"

(1)去掉视频原声:--速度很快---不怎么消耗时间-忽略不计ffmpeg -hwaccel dxva2 -i "D:/test1080.flv" -c:v copy -an "D:/linux-share-dir/video_file/output1.mp4"
(2)合并音频到视频:---要重新CPU编码--费时间ffmpeg -hwaccel dxva2 -i "D:/linux-share-dir/video_file/output1.mp4" -i "C:/Users/11266/Music/xiaola.mp3" "D:/linux-share-dir/video_file/output2.mp4"
(3)合并音频到视频:---要重新编码--费时间--可以选择GPU硬件编码---速度很快ffmpeg -hwaccel dxva2 -i "D:/linux-share-dir/video_file/output1.mp4" -hwaccel dxva2 -i "C:/Users/11266/Music/xiaola.mp3" -c:v h264_qsv "D:/linux-share-dir/video_file/output2.mp4"

视频音频参数转换:ffmpeg -i "D:/test1080.flv" -y -qscale 0 -vcodec libx264 -acodec aac -ac 1 -ar 48000 out1.mp4

//添加图片水印C:/FFMPEG/ffmpeg_x86_4.2.2/bin/ffmpeg.exe -i D:/666.mp4 -vf "movie=D:/linux-share-dir/video_file/test/image/123.png[wm];[in][wm]overlay=30:10[out]" D:/linux-share-dir/video_file/test/output1.mp4参数解析:1. D:/666.mp4 输入的视频2. image/123.png 要添加进去的图片水印3. D:/linux-share-dir/video_file/test/output.mp4 合成水印之后输出的视频

//硬件解码、软件编码---主要是编码消耗时间---这个还是很慢ffmpeg -hwaccel dxva2 -i "D:/test1080.flv" -vf "movie=123.png[wm];[in][wm]overlay=30:10[out]" "D:/linux-share-dir/video_file/output1.mp4"

//硬件解码、软件编码---主要是编码消耗时间---使用GPU硬件编码,速度要快很多ffmpeg -hwaccel dxva2 -i "D:/test1080.flv" -vf "movie=123.png[wm];[in][wm]overlay=30:10[out]" -c:v h264_qsv "D:/linux-share-dir/video_file/output1.mp4"
复制代码

(21)ffmpeg 获取视频截图

使用 ffmpeg 可以非常方便的生成视频截图,ffmpeg 通过指定 -vcodec 参数为 mjpeg,或者指定 -f 参数为 mjpeg 时,可以输出 jpg 截图,指定 -vcodec 参数为 png,或者指定输出文件扩展名为 png,可输出 png 截图。如果参数指定不当,会导致 ffmpeg 处理速度非常缓慢。


1. 输出 jpgffmpeg -ss 00:00:05 -i RevolutionOS.rmvb sample.jpg  -r 1 -vframes 1 -an -vcodec mjpeg
2. 输出 pngffmpeg -ss 00:00:05 -i RevolutionOS.rmvb sample.png -r 1 -vframes 1 -an -vcodec mjpeg大概等待1秒钟,生成的jpg图像为19K,而png格式的图像为222k,大了很多倍,而质量上,并没有太大的差别,所以我决定生成jpg格式。
3. 50分钟处截屏ffmpeg -ss 00:50:00 -i RevolutionOS.rmvb sample.jpg -r 1 -vframes 1 -an -vcodec mjpeg或者使用 -f 参数指定输出的格式为 mjpeg ,效果一样ffmpeg -ss 00:50:00 -i RevolutionOS.rmvb sample.jpg -r 1 -vframes 1 -an -f mjpeg
复制代码

(22)视频尺寸不变,按比例缩放(画黑边)

命令示例:C:/FFMPEG/ffmpeg_x86_4.2.2/bin/ffmpeg.exe -i D:/123.mp4 -vf "scale=100:100,pad=500:500:0:300:black" D:/linux-share-dir/video_file/output.mp4参数解释:500:500 画布的尺寸  .  (w:h)100:100 视频帧在画布里的尺寸--按比例缩放的. (w:h)0:300   视频帧在画面上的位置. (x:y)black   画布的背景颜色 
如果有多个视频文件加黑边之后,后续还需要合成一个视频,可以在输出的时候统一重新采样:C:/FFMPEG/ffmpeg_x86_4.2.2/bin/ffmpeg.exe -i D:/Produce.mpg -vf "scale=100:100,pad=500:500:0:300:black" -y -qscale 0 -vcodec libx264 -acodec aac -ac 1 -ar 22050 -s 500*500 -r 30 D:/linux-share-dir/video_file/test/output3.mp4分辨率、帧率、音频采样率不一致是无法正常合并视频的。
复制代码

(23)视频与图片之间互转

视频转为图片:# ffmpeg -i 123.mp4 image_%d.jpg将 123.mp4 的视频每一帧画面保存为一张张图片。图片转为视频:# ffmpeg -f image2 -i image_%d.jpg video.mpg
复制代码

(24)ffmpeg 推流到 rtmp 服务器

RTMP是Real Time Messaging Protocol(实时消息传输协议)的首字母缩写。是Adobe公司开发的一个基于TCP的应用层协议,也就是说,RTMP是和HTTP/HTTPS一样,是应用层的一个协议族。RTMP在TCP通道上一般传输的是flv 格式流。请注意,RTMP是网络传输协议,而flv则是视频的封装格式。flv封装格式设计出来的目的是为了用于网络传输使用的,因此RTMP+FLV可以说是”黄金搭档“。
RTMP协议包括:基本协议及RTMPT/RTMPS/RTMPE等多种变种。从视频协议学习:推流拉流都擅长的 RTMP了解到,RTMP协议家族有以下几个点挺有趣,读者们不妨看看:
RTMP工作在TCP之上,默认使用端口1935,这个是基本形态;RTMPE在RTMP的基础上增加了加密功能;RTMPT封装在HTTP请求之上,可穿透防火墙;RTMPS类似RTMPT,增加了TLS/SSL的安全功能;RTMFP使用UDP进行传输的RTMP; (1). 在Linux上运行: 推流本地实时音频视频到流媒体服务器示例:[wbyq@wbyq linux_c]$ ffmpeg -f video4linux2 -r 12 -s 640x480 -i /dev/video0 -f alsa -i default -ar 44100 -ac 1 -f mp3 -qscale 10 -f flv "rtmp://127.0.0.1:8086/live/123"
参数解析:-f video4linux2 指定linux下的视频驱动框架-s 640x480 指定视频尺寸-i /dev/video0 摄像头节点f alsa 声卡驱动框架-i default 选择声卡,这里选择默认声卡-ar 44100 声音采样频率-ac 1 单声道-f mp3 MP3音频-qscale 10 设置画面质量,值越小画面质量越高f flv 指定封装格式"rtmp://127.0.0.1:8086/live/123" 流媒体服务器地址
(2). Linux下推流同时保存视频到本地示例:[wbyq@wbyq linux-share-dir]$ ffmpeg -thread_queue_size 128 -f video4linux2 -r 12 -s 1280x720 -i /dev/video0 -f alsa -i default -ar 44100 -ac 1 -f mp3 -qscale 5 -f flv "rtmp://127.0.0.1:8086/live/123" output.h264
参数解析:当这个任务消耗有点大时,-thread_queue_size 必须设置一个比较大的值,不然会看到 FFmpeg输出的日志信息中不停的提醒:[video4linux2,v4l2 @ 0x25fbc40] Thread message queue blocking; consider raising the thread_queue_size option (current value: 8),拍摄到的视频也会出现莫名其妙的错误,比如帧率很高,无法正常播放,视频不流畅等等。把 -thread_queue_size 设置为一个比较大的值,直到看不到该提示即可。
(3). 推流视频文件到流媒体服务器视频文件地址:/Users/jack/test.mp4推流拉流地址:rtmp://localhost:1935/rtmplive/homeacc:RTMP的音频格式flv: RTMP的视频格式ffmpeg -re -i /Users/jack/test.mp4 -vcodec libx264 -acodec aac -f flv rtmp://localhost:1935/rtmplive/home
复制代码

(25)ffmpeg 推流到 rtsp 服务器

(1)推流视频文件到 RTSP 服务器


ffmpeg -re -i /home/xx/Documents/in.mp4 -c copy -f rtsp rtsp://192.168.74.130:8554/room1-re  是以流的方式读取-i  就是输入的文件-f  格式化输出到哪里-c copy 编码器不变
复制代码


(2)将视频文件循环推到 RTSP 服务器


ffmpeg -re -stream_loop -1 -i aa.mp4 -c copy -f rtsp rtsp://192.168.80.49:8554/mystream
复制代码


(3)录制电脑屏幕并推流到 RTSP 服务器


[1]ffmpeg -f gdigrab -i desktop -vcodec libx264 -preset:v ultrafast -tune:v zerolatency -f rtsp rtsp://192.168.80.49:8554/mystream

[2]ffmpeg -re -thread_queue_size 128 -threads 8 -f x11grab -video_size 1920x1080 -framerate 26 -i :0 -vcodec libx264 -preset ultrafast -tune zerolatency -muxdelay 2 -fast-pskip true -buffer_size 10240000 -qp 50 -crf 26 -level 3 -rtsp_transport udp -s 960x540 -max_muxing_queue_size 128 -f rtsp rtsp://ip:port/live/test
复制代码


(4)推流摄像头视频到 RTSP 服务器(windows)


ffmpeg -f dshow -i video="Integrated Camera" -vcodec libx264 -preset:v ultrafast -tune:v zerolatency -rtsp_transport udp -f rtsp rtsp://127.0.0.1/stream
复制代码

六、总结

当前文章里先介绍 FFmpeg 工具集、以 MP4、MP3 为例介绍音视频文件的封装格式、编码格式,最后再列出了多个 ffmpeg 命令行处理音视频案例,方便大家快速了解 ffmpeg 的常用方法。但是 ffmpeg 的功能并不局限与此,当前文章只是重点介绍 ffmpeg 命令行处理方式,如果需要在项目里引用 ffmpeg 完成一些特定项目的开发。比如:视频播放器、音视频剪辑软件,特效制作软件等等,还需要对 ffmpeg 的源码进行深度了解,熟悉各个 API 的功能与调用方法。

发布于: 2023-05-05阅读数: 191
用户头像

DS小龙哥

关注

之所以觉得累,是因为说的比做的多。 2022-01-06 加入

熟悉C/C++、51单片机、STM32、Linux应用开发、Linux驱动开发、音视频开发、QT开发. 目前已经完成的项目涉及音视频、物联网、智能家居、工业控制领域

评论

发布
暂无评论
FFmpeg从入门到精通-云享读书会总结_三周年连更_DS小龙哥_InfoQ写作社区