ffmpge:视频处理工具
api远程调用shell(https://github.com/HountryLiu/ffmpeg-api-tool)
1. 音视频基础知识
视频:
- 编码压缩
音视频方面,压缩被称为encode(编码)。
常用压缩标准:
-
JPEG 标准,用于单张图片压缩。标准文档 ISO/IEC 10918-1
-
H.262 标准,用于视频编解码,标准文档 ISO/IEC 13818-2
-
H.263 标准,用于视频编解码。
-
H.264 标准,在 2022年 目前是应用非常广泛的标准。
-
VP9,Google 出的视频编解码标准。
-
AVS,中国的视频压缩标准。
- 封装格式(容器格式):
作用:提供一个预定的规则,将视频数据、音频数据等,放到一个文件中。
常见封装格式:FLV、MP4、MKV、MPEG-TS
MP4封装格式:
MP4文件由多个box组成,每个box存储不同的信息,且box之间是树状结构。
ftyp:File Type Box,描述文件遵从的MP4规范与版本;
moov:Movie Box,媒体的metadata信息,有且仅有一个;
mdat:Media Data Box,存放实际的媒体数据,一般有多个;
mvhd(Movie Header Box):存储文件的时长等基本信息。
trak(Track Box):通常一个音频流 或者视频流 对应一个 trak box。
-
DTS(Decoding Time Stamp):即解码时间戳,这个时间戳的意义在于告诉播放器该在什么时候解码这一帧的数据。
-
PTS(Presentation Time Stamp):即显示时间戳,这个时间戳用来告诉播放器该在什么时候显示这一帧的数据。
-
Duration: 当前视频帧显示时长。以30FPS帧率为例,显示时长为33ms
-
帧类型
I 帧(Intra coded frames):关键帧,使用帧内压缩,不使用运动补偿,不依赖其它帧,可以独立解码。
P 帧(Predicted frames): 采用帧间编码方式,即同时利用了空间和时间上的相关性。P 帧图像只采用前向``时间预测,可以提高压缩效率和图像质量。P 帧图像中可以包含帧内编码的部分,即 P 帧中的每一个宏块可以 是前向预测,也可以是帧内编码。P帧解码依赖于前面的I帧或者P帧。
B 帧(Bi-directional predicted frames):采用帧间编码方式,且采用双向时间预测,可以大大提高压缩倍数。也就是其在时间相关性上,还依赖后面的视频帧,也正是由于 B 帧图像采用了后面的帧作为参考,因此造成视频帧的传输顺序和显示顺序是不同的。B帧解码既要依赖于前面的P帧或I帧,还依赖于其之后的P帧
因为I、P、B帧类型的存在,所以会导致视频解码顺序和编码顺序不同。
- 图像组(GOP)--一组帧或者一组图像
指两个关键帧(I帧)之间的距离。在码率不变的前提下,GOP值越大,P、B帧的数量会越多,平均每个I、P、B帧所占用的字节数就越多,也就更容易获取较好的图像质量;Reference(参考周期 指两个P帧之间的距离)越大,B帧的数量越多,同理也更容易获得较好的图像质量。
需要说明的是,通过提高GOP值来提高图像质量是有限度的,在遇到场景切换的情况时,H.264编码器会自动强制插入一个I帧,此时实际的GOP值被缩短了。另一方面,在一个GOP中,P、B帧是由I帧预测得到的,当I帧的图像质量比较差时,会影响到一个GOP中后续P、B帧的图像质量,直到下一个GOP开始才有可能得以恢复,所以GOP值也不宜设置过大。
音频:
音频数据在计算机中是经过采样、量化、归一化后保存为PCM数据的。PCM(Pulse Code Modulation,脉冲编码调制)音频数据是未经压缩的音频采样数据裸流,它是由模拟信号经过采样、量化、编码转换成的标准数字音频数据。 通常有3个参数来描述PCM数据:
- 采样率:是指每秒钟使用多少个样本来表示音频。通常采样率有:8kHz(电话)、16kHz、44.1kHz(CD)、48kHz(DVD)
- 通道数:常见的音频有立体声(stereo)和单声道(mono)两种类型,立体声包含左声道和右声道。另外还有环绕立体声等其它不太常用的类型。我们常见的mono是只有1个声道;stereo通常是2个声道。
- 样本格式:每个样本使用什么样的表达数值来进行表达,通常有8位、16位、32位,可以是浮点数,也可以是整型。
2. ffmpeg基础知识
基础术语:
-
容器(Container)
一种文件格式,比如flv,mkv等。包含下面5种流以及文件头信息。
-
流(Stream)
一种视频数据信息的传输方式,5种流:音频,视频,字幕,附件,数据。
-
帧(Frame)
帧代表一幅静止的图像,分为I帧,P帧,B帧。
-
编解码器(Codec)
是对视频进行压缩或者解压缩,CODEC = COde(编码) +DECode(解码)。
-
复用/解复用(mux/demux)
把不同的流按照某种容器的规则放入容器,这种行为叫做复用(mux)。
把不同的流从某种容器中解析出来,这种行为叫做解复用(demux)。
-
帧率
帧率也叫帧频率,帧率是视频文件中每一秒的帧数,肉眼想看到连续移动图像至少需要15帧。
-
码率
比特率(也叫码率,数据率)是一个确定整体视频/音频质量的参数,秒为单位处理的字节数,码率和视频质量成正比,在视频文件中中比特率用bps来表达。
3. ffmpeg使用
- 命令行使用方法:
ffmpeg [global options] {[infile options]['-i' 'infile'] ...} {[outfile options] 'outfile' ...
- 基本选项
能力集列表:
- -formats:列出支持的文件格式。
- -codecs:列出支持的编解码器。
- -decoders:列出支持的解码器。
- -encoders:列出支持的编码器。
- -protocols:列出支持的协议。
- -bsfs:列出支持的比特流过滤器。
- -filters:列出支持的滤镜。
- -pix_fmts:列出支持的图像采样格式。
- -sample_fmts:列出支持的声音采样格式
常用输入选项:
- -i filename:指定输入文件名。
- -f fmt:强制设定文件格式,需使用能力集列表中的名称(缺省是根据扩展名选择的)。
- -ss hh:mm:ss[.xxx]:设定输入文件的起始时间点,启动后将跳转到此时间点然后开始读取数据。
对于输入,以下选项通常是自动识别的,但也可以强制设定。
- -c codec:指定解码器,需使用能力集列表中的名称。
- -acodec codec:指定声音的解码器,需使用能力集列表中的名称。
- -vcodec codec:指定视频的解码器,需使用能力集列表中的名称。
- -b:v bitrate:设定视频流的比特率,整数,单位bps。
- -r fps:设定视频流的帧率,整数,单位fps。
- -s WxH : 设定视频的画面大小。也可以通过挂载画面缩放滤镜实现。
- -pix_fmt format:设定视频流的图像格式(如RGB还是YUV)。
- -ar sample rate:设定音频流的采样率,整数,单位Hz。
- -ab bitrate:设定音频流的比特率,整数,单位bps。
- -ac channels:设置音频流的声道数目。
常用输出选项
- -f fmt:强制设定文件格式,需使用能力集列表中的名称(缺省是根据扩展名选择的)。
- -c codec:指定编码器,需使用能力集列表中的名称(编码器设定为”copy“表示不进行编解码)。
- -acodec codec:指定声音的编码器,需使用能力集列表中的名称(编码器设定为”copy“表示不进行编解码)。
- -vcodec codec:指定视频的编码器,需使用能力集列表中的名称(编解码器设定为”copy“表示不进行编解码)。
- -r fps:设定视频编码器的帧率,整数,单位fps。
- -pix_fmt format:设置视频编码器使用的图像格式(如RGB还是YUV)。
- -ar sample rate:设定音频编码器的采样率,整数,单位Hz。
- -b bitrate:设定音视频编码器输出的比特率,整数,单位bps。
- -ab bitrate:设定音频编码器输出的比特率,整数,单位bps。
- -ac channels:设置音频编码器的声道数目。
- -an 忽略任何音频流。
- -vn 忽略任何视频流。
- -t hh:mm:ss[.xxx]:设定输出文件的时间长度。
- -to hh:mm:ss[.xxx]:如果没有设定输出文件的时间长度的画可以设定终止时间点。
流标识:
FFMPEG的某些选项可以对一个特定的媒体流起作用,这种情况下需要在选项后面增加一个流标识。流标识允许以下几种格式:
- 流序号。譬如“:1”表示第二个流。
- 流类型。譬如“:a“表示音频流,流类型可以和流序号合并使用,譬如“ : a :1 ”表示第二个音频流。
- 节目。节目和流序号可以合并使用。
- 流标识。流标识是一个内部标识号。
假如要设定第二个音频流为copy,则需要指定-codec1: a :1copy
视屏选项:
- -vframes:等价于frames:v,输出选项,用于指定输出的视频帧数目。
- -aspect:设置宽高比,如4:3、16:9、1.3333、1.7777等。
- -bits_per_raw_sample:设置每个像素点的比特数。
- -vstats:产生video统计信息。
- -vf:等价于filter:v,用于设定一个图像的后处理过滤链,其参数为一个描述图像后处理链的字符串。
- -vtag:等价于tag:v,用于设定视频流的标签。
- -force_fps:强制设定视频帧率。
- -force_key_frames:显式控制关键帧的插入,参数为字符串,可以是一个时间戳,也可以是一个“expr:”前缀的表达式。如“-force_key_frames 0:05:00”、“-force_key_frames expr:gte(t,n_forced*5)”
高级选项:
- -re:要求按照既定速率处理输入数据,这个速率即是输入文件的帧率。
- -map:指定输出文件的流映射关系。例如 “-map 1:0 -map 1:1”要求将第二个输入文件的第一个流和第二个流写入到输出文件。如果没有-map选项,ffmpeg采用缺省的映射关系。
常用命令:
- 将一个老式的avi文件转成mp4
ffmpeg -i final.avi -acodec copy -vcodec copy final.mp4
- 从一个视频文件中抽取一帧图像
ffmpeg -y -i test.mp4 -ss 00:03:22.000 -vframes 1 -an test.jpg
- 裁剪视频
ffmpeg -i final.avi -vf scale=640:640 square.avi
ffmpeg –i test.avi –r 1 –f image2 image-%3d.jpeg //提取图片
ffmpeg -ss 0:1:30 -t 0:0:20 -i input.avi -vcodec copy -acodec copy output.avi //剪切视频
//-r 提取图像的频率,-ss 开始时间,-t 持续时间
- 使用alsa接口录制一段音频存放到某个wav文件中
ffmpeg -f alsa -i hw:0 -t 100 alsaout.wav
- 将一个mp4文件的音视频流实时转码之后发送给某个远程设备,远程设备可以通过http获取的sdp文件来接收rtp媒体数据
ffmpeg -re -i example.mp4 -acodec copy -vcodec libx264 -s 480x270 -map 0:0 -f rtp rtp://10.131.202.62:1234 -map 0:1 -f rtp rtp://10.131.202.62:1238 > /var/www/live.sdp
- 剪辑视频且输出到标准输出流中
ffmpeg -i example.mp4 -ss 00:05:00 -t 00:03:00 -f mpegts -
- 分离视频音频流
ffmpeg -i input_file -vcodec copy -an output_file_video //分离视频流
ffmpeg -i input_file -acodec copy -vn output_file_audio //分离音频流
-vn 禁止视频录制 -an 禁止音频录制
- 视频转码
ffmpeg –i test.mp4 –vcodec h264 –s 352*278 –an –f m4v test.264 //转码为码流原始文件
ffmpeg –i test.mp4 –vcodec h264 –bf 0 –g 25 –s 352*278 –an –f m4v test.264 //转码为码流原始文件
ffmpeg –i test.avi -vcodec mpeg4 –vtag xvid –qsame test_xvid.avi //转码为封装文件
//-bf B帧数目控制,-g 关键帧间隔控制,-s 分辨率控制
- 视频封装
ffmpeg –i video_file –i audio_file –vcodec copy –acodec copy output_file
- 视频录制
ffmpeg –i rtsp://192.168.3.205:5555/test –vcodec copy out.avi
4. ffplay使用
- ffplay:使用了 ffmpeg 和 sdl 库的简单的可移植的媒体播放器。
命令行: ffplay [选项] ['输入文件']
- 使用示例:
播放test.mkv的视频,播放完成后自动退出
ffplay -autoexit test.mp4
以 320 × 240 的大小播放 test.mp4
ffplay -x 320 -y 240 test.mp4
- 通用选项
'-L' 显示 license
'-h, -?, -help, --help [arg]' 打印帮助信息;可以指定一个参数 arg ,如果不指定,只打印基本选项
可选的 arg 选项:
'long' 除基本选项外,还将打印高级选项
'full' 打印一个完整的选项列表,包含 encoders, decoders, demuxers, muxers, filters 等的共享以及私有选项
'decoder=decoder_name' 打印名称为 "decoder_name" 的解码器的详细信息
'encoder=encoder_name' 打印名称为 "encoder_name" 的编码器的详细信息
'demuxer=demuxer_name' 打印名称为 "demuxer_name" 的 demuxer 的详细信息
'muxer=muxer_name' 打印名称为 "muxer_name" 的 muxer 的详细信息
'filter=filter_name' 打印名称为 "filter_name" 的过滤器的详细信息
'-version' 显示版本信息
'-formats' 显示有效的格式
'-codecs' 显示 libavcodec 已知的所有编解码器
'-decoders' 显示有效的解码器
'-encoders' 显示有效的编码器
'-bsfs' 显示有效的比特流过滤器
'-protocols' 显示有效的协议
'-filters' 显示 libavfilter 有效的过滤器
'-pix_fmts' 显示有效的像素格式
'-sample_fmts' 显示有效的采样格式
'-layouts' 显示通道名称以及标准通道布局
'-colors' 显示认可的颜色名称
'-hide_banner' 禁止打印欢迎语;也就是禁止默认会显示的版权信息、编译选项以及库版本信息等
- 主要选项
'-x width' 强制以 "width" 宽度显示
'-y height' 强制以 "height" 高度显示
'-an' 禁止音频
'-vn' 禁止视频
'-ss pos' 跳转到指定的位置(秒)
'-t duration' 播放 "duration" 秒音/视频
'-bytes' 按字节跳转
'-nodisp' 禁止图像显示(只输出音频)
'-f fmt' 强制使用 "fmt" 格式
'-window_title title' 设置窗口标题(默认为输入文件名)
'-loop number' 循环播放 "number" 次(0将一直循环)
'-showmode mode' 设置显示模式
可选的 mode :
'0, video' 显示视频
'1, waves' 显示音频波形
'2, rdft' 显示音频频带
默认值为 'video',你可以在播放进行时,按 "w" 键在这几种模式间切换
'-i input_file' 指定输入文件
- 高级选项
'-sync type' 设置主时钟为音频、视频、或者外部。默认为音频。主时钟用来进行音视频同步
'-threads count' 设置线程个数
'-autoexit' 播放完成后自动退出
'-exitonkeydown' 任意键按下时退出
'-exitonmousedown' 任意鼠标按键按下时退出
'-acodec codec_name' 强制指定音频解码器为 "codec_name"
'-vcodec codec_name' 强制指定视频解码器为 "codec_name"
'-scodec codec_name' 强制指定字幕解码器为 "codec_name"
- 快捷键
'q, ESC' 退出
'f' 全屏
'p, SPC' 暂停
'w' 切换显示模式(视频/音频波形/音频频带)
's' 步进到下一帧
'left/right' 快退/快进 10 秒
'down/up' 快退/快进 1 分钟
'page down/page up' 跳转到前一章/下一章(如果没有章节,快退/快进 10 分钟)
'mouse click' 跳转到鼠标点击的位置(根据鼠标在显示窗口点击的位置计算百分比)
5. ffprobe使用
- ffprobe:一个多媒体流分析工具。它从多媒体流中收集信息,并且以人类和机器可读的形式打印出来。它可以用来检测多媒体流的容器类型,以及每一个多媒体流的格式和类型。它可以作为一个独立的应用来使用,也可以结合文本过滤器执行更复杂的处理。
- 使用示例
最简单的使用方式
ffprobe test.mp4
不显示欢迎信息
ffprobe -hide_banner test.mp4
以JSON格式显示每个流的信息
ffprobe -hide_banner -print_format json -show_streams test.mp4
显示容器格式相关信息
ffprobe -hide_banner -show_format test.mp4
- 主要选项
'-f format' 强制使用的格式
'-unit' 显示值的单位
'-prefix' 显示的值使用标准国际单位制词头
'-byte_binary_prefix' 对字节值强制使用二进制前缀
'-sexagesimal' 时间值使用六十进位的格式 HH:MM:SS.MICROSECONDS
'-pretty' 美化显示值的格式。它相当于 "-unit -prefix -byte_binary_prefix -sexagesimal"
'-of, -print_format writer_name[=writer_options]'
设置输出打印格式。writer_name 指定打印程序 (writer) 的名称,writer_options
指定传递给 writer 的选项。例如:将输出打印为 JSON 格式:-print_format json
'-select_streams stream_specifier'
只选择 stream_specifier 指定的流。该选项只影响那些与流相关的选项
(例如:show_streams, show_packets, 等)。
举例:只显示音频流,使用命令:
ffprobe -show_streams -select_streams a INPUT
'-show_data' 显示有效载荷数据,以十六进制和ASCII转储。与 '-show_packets' 结合使用,它将
dump 包数据;与 '-show_streams' 结合使用,它将 dump codec 附加数据。
'-show_error' 显示探测输入文件时的错误信息
'-show_format' 显示输入多媒体流的容器格式信息
'-show_packets' 显示输入多媒体流中每一个包的信息
'-show_frames' 显示输入多媒体流中的每一帧以及字幕的信息
'-show_streams' 显示输入多媒体流中每一个流的信息
'-show_programs' 显示输入多媒体流中程序以及它们的流的信息
'-show_chapters' 显示格式中存储的章节信息
'-count_frames' 计算每一个流中的帧数,在相应的段中进行显示
'-count_packets' 计算每一个流中的包数,在相应的段中进行显示
'-show_program_version' 显示程序版本及配置相关信息
'-show_library_versions' 显示库版本相关信息
'-show_versions' 显示程序和库版本相关信息。相当于同时设置'-show_program_version' 和
'-show_library_versions'
'-i input_file' 指定输入文件
6. 图片去水印
ffmpeg -i 去水印测试.jpg -vf delogo=x=460:y=545:w=168:h=35:show=0 out.jpg
show= 0 表示不展示去水印的位置 1表示展示
-vf表示使用的处理滤镜
x、y 表示去除水印的左表
w、h表示去除水印的范围