从事【音视频】的开发者,看过来,如果记不住 FFmepg 命令,可以收藏,不记得的时候,掏出来翻翻
ffmpeg --help
大概分为 6 个部分,具体如下:
ffmpeg 信息查询部分
公共操作参数部分
文件主要操作参数部分
视频操作参数部分
音频操作参数部分
字母操作参数部分
查看支持的容器格式
查看支持的编解码格式
查看支持的滤镜
转码
ffprobe 常用命令
-show_packets
查看多媒体数据包信息
-show_format
查看多媒体的封装格式
-show_frames
查看视频文件中的帧信息
-show_streams
查看多媒体文件中的流信息
-printf_format
或-of
格式化输出支持 XML、INI、JSON、CSV、FLAT 等
ffplay
可视化
Visualize information exported by some codecs.
http://ffmpeg.org/ffmpeg-all.html#codecview
https://trac.ffmpeg.org/wiki/Debug/MacroblocksAndMotionVectors
Visualize forward predicted MVs of all frames using
ffplay -flags2 +export_mvs input.mp4 -vf codecview=mv_type=fp
Visualize multi-directionals MVs of P and B-Frames using
ffplay -flags2 +export_mvs input.mp4 -vf codecview=mv=pf+bf+bb
ffmpeg 转封装格式
需要知道 源容器 和 目标容器 的可容纳的编码格式
编码格式如果相互兼容,可以用
-c copy
拷贝原有的 streamffmpeg -i input.mp4 -c copy -f flv output.flv
编码格式如果不兼容,需要转化成目标文件支持的编码
ffmpeg -i input_ac3.mp4 -vcodec copy -acodec aac -f flv output.flv
HLS
FFmpeg 转 HLS 举例
常规的从文件转换 HLS 直播时:
ffmpeg -re -i input.mp4 -c copy -f hls -bsf:v h264_mp4toannexb output.m3u8 # -bsf:v h264_mp4toannexb 作用是将 MP4 中的 H.264 数据转换成 H.264 AnnexB 标准编码,AnnexB 标准的编码常见于实时传输流中
如果源文件为 FLV、TS 等可以作为直播传输流的视频,则不需要这个参数。
ffmpeg 推流上传 HLS 相关的 M3U8 以及 TS 文件
Nginx 配置 webdav 模块
ffmpeg -re -i input.mp4 -c copy -f hls -hls_time 3 -hls_list_size 0 -method PUT -t 30 http://127.0.0.1/test/output.m3u8
音视频文件音视频流抽取
FFmpeg 抽取音视频文件中的 AAC 音频流
ffmpeg -i input.mp4 -vn -acodec copy output.aac
FFmpeg 抽取音视频文件中的 H.264 视频流
ffmpeg -i input.mp4 -vcodec copy -an output.h264
FFmpeg 抽取音视频文件中的 H.265 视频流(前提文件视频编码格式为 hevc)
ffmpeg -i input.mp4 -vcodec copy -an -bsf hevc_mp4toannexb -f hevc output.hevcffmpeg 转码
h264 转 h265(HEVC)
aac 转 MP3(需要安装 libmp3lame)
x264
安装
查看
设置编码参数
编码器预设参数设置 preset 通常通过 preset 来设置编码的速度,影响清晰度
ffmpeg -i input.mp4 -vcodec libx264 -preset ultrafast -b:v 2000k output.mp4
H.264 编码优化参数 tune 在使用 ffmpeg 与 x264 进行 H.264 直播编码并进行推流时,只用 tune 参数的 zerolatency 将会提升效率,因为其降低了因编码导致的延迟。
H.264 的 profile 与 level 设置 baseline profile 编码的 H.264 视频不会包含 B Slice,而使用 main profile、high profile 编码出来的视频,均可以包含 B Slice
ffmpeg -i input.mp4 -vcodec libx264 -profile:v baseline -level 3.1 -s 352x288 -an -y -t 10 output_baseline.ts
ffmpeg -i input.mp4 -vcodec libx264 -profile:v high -level 3.1 -s 352x288 -an -y -t 10 output_high.ts
查看包含 B 帧的情况:
ffprobe -v quiet -show_frames -select_streams v output_baseline.ts | grep "pict_type=B" | wc -l
当进行实时流媒体直播时,采用 baseline 编码相对 main 或 high 的 profile 会更可靠些。
控制场景切花关键帧插入参数 sc_threshold ffmpeg 通过-g 参数设置以帧数间隔为 GOP 的长度,但是当遇到场景切换时,例如从一个画面突然变成另一个画面时,会强行插入一个关键帧,这是 GOP 的间隔将会重新开始,可以通过使用 sc_threshold 参数进行设定以决定是否在场景切换时插入关键帧。 ffmpeg 命令控制编码时的 GOP 大小
ffmpeg -i AVC_high_1280x720_2013.mp4 -c:v libx264 -g 50 -t 60 output.mp4
为了使得 GOP 的插入更加均匀,使用参数 sc_thresholdffmpeg -i AVC_high_1280x720_2013.mp4 -c:v libx264 -g 50 -sc_threshold 0 -t 60 -y output.mp4
设置 x264 内部参数 x264opts 去掉 B 帧
ffmpeg -i input.mp4 -c:v libx264 -x264opts "bframes=0" -g 50 -sc_threshold 0 output.mp4
控制 I 帧、P 帧、B 帧的频率与规律 例如设置 GOP 中,每 2 个 P 帧之间存放 3 个 B 帧:ffmpeg -i input.mp4 -c:v libx264 -x264opts "bframes=3:b-adapt=0" -g 50 -sc_threshold 0 output.mp4
CBR 恒定码率设置参数 nal-hrd (固定码率好处,可能是网络传输)
VBR:可变码率
CBR:恒定码率
ABR:平均码率。VBR 和 CBR 混合产物。
ffmpeg -i input.mp4 -c:v libx264 -x264opts "bframes=10:b-adapt=0" -b:v 1000k -maxrate 1000k -minrate 1000k -bufsize 50k -nal-hrd cbr -g 50 -sc_threshold 0 output.ts # 设置 B 帧的个数,并且是每 2 个 P 帧之间包含 10 个 B 帧 # 设置视频码率为 1000 kbit/s # 设置最大码率为 1000 kbit/s # 设置最小码率为 1000 kbit/s # 设置编码的 buffer 大小为 50KB # 设置 H.264 的编码 HRD 信号形式为 CBR # 设置每 50 帧一个 GOP # 设置场景切换不强行插入关键帧
MP3/AAC
MP3 转码
ffmpeg -i INPUT -acodec libmp3lame output.mp3
参数控制
# -q 控制码率(0~9) 高->低 ffmpeg -i input.mp3 -acodec libmp3lame -q:a 8 output.mp3 # -b 设置为 CBR ffmpeg -i input.mp3 -acodec libmp3lame -b:a 64k output.mp3 # -abr 设置为 abr 编码 ffmpeg -i input.mp3 -acodec libmp3lame -b:a 64k -abr 1 output.mp3
ffmpeg 流媒体
ffmpeg 发布与录制 RTMP 流
FFmpeg 操作 RTMP 的参数
rtmp_app、rtmp_playpath 参数
通过 rtmp_app、rtmp_playpath 参数设置 rtmp 的推流发布点
ffmpeg -re -i AVC_high_1280x720_2013.mp4 -c copy -f flv -rtmp_app live -rtmp_playpath play rtmp://127.0.0.1
等价于
ffmpeg -re -i AVC_high_1280x720_2013.mp4 -c copy -f flv rtmp://127.0.0.1/live/play
ffmpeg 录制 RTSP 流
FFmpeg 操作 RTSP 的参数
TCP 方式录制 RTSP 直播流
ffmpeg 默认使用的 rtsp 拉流方式为 UDP,为了避免丢包导致的花屏、绿屏、灰屏、马赛克等问题,将 UDP 改为 TCP 传输:
User-Agent 设置参数
ffmpeg -user-agent "Alex-Player" -i rtsp://input:554/live/1/stream.sdp -c copy -f mp4 -u output.mp4FFmpeg 录制 HTTP 流
FFmpeg 操作 HTTP 的参数
FFmpeg 录制和发布 TCP 与 UDP 流
略
FFmpeg 推多路流
推流(tee 协议输出多路流)
ffmpeg -re -i AVC_high_1280x720_2013.mp4 -vcodec libx264 -acodec aac -map 0 -f flv "tee:rtmp://127.0.0.1/live/p1|rtmp://127.0.0.1/live/p2"
验证
ffmpeg -i rtmp://127.0.0.1/live/p1 -i rtmp://127.0.0.1/live/p2
ffmpeg 滤镜使用
http://ffmpeg.org/ffmpeg-filters.html
FFmpeg 滤镜 Filter 描述格式
FFmpeg 滤镜 Filter 的参数排列方式 [输入流或标记]滤镜参数[临时标记名];[输入流或标记]滤镜参数[临时标记名]… 输入两个文件,一个视频,一个图片,将 logo 进行缩放,然后放在视频的左上角:
ffmpeg -i input.mp4 -i input.jpg -filter_complex " [1:v] scale=176:144[logo];[0:v][logo]overlay=x=0:y=0" output.mp4 # [0:v]/[1:v]代表第几个输入的视频
FFmpeg 为视频加水印
drawtext
滤镜ffmpeg -h filter=drawtext # 文字水印 ffmpeg -i input.mp4 -ss 50 -vf "drawtext=fontsize=100:fontfile=/usr/share/fonts/truetype/freefont/FreeSerif.ttf :text='Hello World':fontcolor='yellow':x=20:y=20" output.mp4 # 动态日期 ffmpeg -i input.mp4 -ss 50 -vf "drawtext=fontsize=100:fontfile=/usr/share/fonts/truetype/freefont/FreeSerif.ttf :text='%{localtime\:%Y\-%m\-%d %H-%M-%S}':fontcolor='yellow':x=20:y=20" output.mp4 # 闪烁 ffmpeg -i input.mp4 -ss 50 -vf "drawtext=fontsize=100:fontfile=/usr/share/fonts/truetype/freefont/FreeSerif.ttf :text='%{localtime\:%Y\-%m\-%d %H-%M-%S}':fontcolor='yellow':x=20:y=20:enable=lt(mod(t\,3)\,1)" output.mp4
movie
滤镜# 图片水印 ffmpeg -i input.mp4 -vf "movie=logo.png[wm];[in][wm]overlay=30:10[out]" output.mp4 # colorkey 半透明 ffmpeg -i input.mp4 -ss 55 -vf "movie=../picture/3d_data.png,colorkey=black:1.0:0.1[wm];[in][wm]overlay=30:10[out]" output.mp4
overlay
滤镜# 画中画 ffmpeg -re -i input.mp4 -vf "movie=sub.mp4,scale=480x320[test];[in][test]overlay[out]" -vcodec libx264 output.flv # 跑马灯 ffmpeg -re -i input.mp4 -vf "movie=sub.wmv,scale=480x320[test];[in][test]overlay=x='if(gte(t,2), -w+(t-2)*50, NAN)':y=0[out]" -vcodec libx264 output.flv # 视频多宫格处理 ffmpeg -i input1.mp4 -i input2.mp4 -i input3.mp4 -i input4.mp4 -filter_complex " nullsrc=size=1280x720 [background]; [0:v] setpts=PTS-STARTPTS, scale=640x360 [upleft]; [1:v] setpts=PTS-STARTPTS, scale=640x360 [upright]; [2:v] setpts=PTS-STARTPTS, scale=640x360 [downleft]; [3:v] setpts=PTS-STARTPTS, scale=640x360 [downright]; [background][upleft] overlay=shortest=1 [background+upleft]; [background+upleft][upright] overlay=shortest=1:x=640 [background+up]; [background+up][downleft] overlay=shortest=1:y=360 [background+up+downleft]; [background+up+downleft][downright] overlay=shortest=1:x=640:y=360 " output.mp4
FFmpeg 音频流滤镜操作
双声道合并单声道
fmpeg -i input.mp3 -ac 1 output.mp3
双声道提取
map_channel
ffmpeg -i input.mp3 -map_channel 0.0.0 left.mp3 -map_channel 0.0.1 right.mp3
pan
ffmpeg -i input.mp3 -filter_complex "[0:0]pan=1c|c0=c0[left];[0:0]pan=1c|c0=c1[right]" -map "[left]" left.mp3 -map "[right]" right.mp3
双声道转双音频流
ffmpeg -i input.mp4 -filter_complex channelsplit=channel_layout=stereo output.mka ffprobe output.mka # 可以看到有两个 stream
不常用,大多数播放器也只会播放第一个流
单声道转双声道
ffmpeg -i left.aac -ac 2 output.m4a
这样的双声道并不是真正的双声道,而是单声道处理成的多声道,效果不会比原来多声道效果好两个音频源合并双声道
ffmpeg -i left.mp3 -i right.mp3 -filter_complex "[0:a][1:a]amerge=inputs=2[aout]" -map "[aout]" output.mka
多个音频合并为多声道
ffmpeg -i front_left.wav -i front_right.wav -i front_center.wav -i lfe.wav -i back_left.wav -i back_right.wav -filter_complex "[0:a][1:a][2:a][3:a][4:a][5:a]amerge=inputs=6[aout]" -map "[aout]" output.wavFFmpeg 音频音量探测
音频音量获得
ffmpeg -i input.wav -filter_complex volumedetect -f null -
绘制音频波形
ffmpeg -i input.wav -filter_complex "showwavespic=s=640x120" -frames:v 1 output.png # 不通声道的波形图 ffmpeg -i input.wav -filter_complex "showwavespic=s=640x120:split_channels=1" -frames:v 1 output.png
FFmpeg 为视频加字母
ASS 字母流写入视频流
ffmpeg -i input.mp4 -vf ass=t1.ass -f mp4 output.mp4
ASS 字母流写入封装容器
ffmpeg -i input.mp4 -vf ass=t1.ass -acodec copy -vcodec copy -scodec copy output.mp4 # 输入的视频文件汇总原本同样带有字幕流,希望使用 t1.ass 字幕流,通过 map 写入 # 下面命令会分别将第一个输入文件的第一个流和第二个流与第二个输入文件的第一个流写入 output.mkv ffmpeg -i input.mp4 -i t1.ass -map 0:0 -map 0:1 -map 1:0 -acodec copy -vcodec copy -scodec copy output.mkv
FFmpeg 视频抠图合并
chromakey 抠图和背景视频合并的操作
# 查询颜色支持 ffmpeg -colors # chromakey 滤镜将绿色背景中的人物抠出来,贴到 input.mp4 为背景的视频中 ffmpeg -i input.mp4 -i input_green.mp4 -filter_complex "[1:v]chromakey=Green:0.1:0.2[ckout];[0:v][ckout]overlay[out]" -map "[out]" output.mp4 # FFmpeg 中除了有 chromakey 滤镜外,还有 colorkey 参数,chromakey 滤镜主要用于 YUV 数据,所以一般来说做绿幕处理更有优势;而 colorkey 处理纯色均可以,因为 colorkey 主要用于 RGB 数据。
FFmpeg 3D 视频处理
stereo3d
滤镜
# 黄蓝 ffplay -vf "stereo3d=sbsl:aybd" AVC_high_1280x720_2013.mp4 # 红蓝 ffplay -vf "stereo3d=sbsl:aybg" AVC_high_1280x720_2013.mp4
FFmpeg 定时视频截图
vframe
参数截取一张图片ffmpeg -i input.flv -ss 00:00:7.435 -vframes 1 output.png
fps
滤镜定时获得图片
# 每隔 1 秒钟生成一张 PNG 图片 ffmpeg -i input.flv -vf fps=1 out%d.png # 每隔一封中生成一张 jpg 图片 ffmpeg -i input.flv -vf fps=1/60 out%d.jpg # select 按照关键帧截取图片 ffmpeg -i input.flv -vf "select='eq(pict_type,PICT_TYPE_I)'" -vsync vfr thumb%04d.png
FFmpeg 生成测试源数据
音频测试流 lavfi 模拟音频源的 abuffer、aevalsrc、anullsrc、flite、anoisesrc、sine 滤镜生成音频流
# 白噪声 ffmpeg -re -f lavfi -i aevalsrc="-2+random(0)" -t 5 output.mp3 # 正弦波 ffmpeg -re -f lavfi -i "sine" -t 5 output.mp3
视频测试流 通过 FFmpeg 模拟多种视频源:allrgb、allyuv、color、haldclutsrc、nullsrc、rgbtestsrc、smptebars、smptehdbars、testsrc、testsrc2、yuvtestsrc
# 生成长度为 5.3 秒、图像大小为 QCIF 分辨率、帧率为 25fps 的视频图像数据,并编码成 H.264 ffmpeg -re -f lavfi -i testsrc=duration=5.3:size=qcif:rate=25 -vcodec libx264 -r:v 25 output.mp4 # 纯红 ffmpeg -re -f lavfi -i color=c=red@0.2:s=qcif:r=25 -vcodec libx264 -r:v 25 output.mp4 # 随机雪花 ffmpeg -re -f lavfi -i "nullsrc=s=256x256,geq=random(1)*255:128:128" -vcodec libx264 -r:v 25 output.mp4
FFmpeg 对音视频倍速处理
atempo
音频倍速处理 取值范围:0.5 ~ 2.0# 半速处理 ffmpeg -i input.wav -filter_complex "atempo=tempo=0.5" -acodec aac output.aac
setpts
视频倍速处理 使用 PTS 控制播放速度的# 半速处理 ffmpeg -re -i input.mp4 -filter_complex "setpts=PTS*2" output.mp4
ffmpeg 采集设备
Linux 下查看设备列表
ffmpeg -h demuxer=fbdev
Linux 采集设备 fbdev FrameBuffer 是一个比较有年份的设备,专门用于图像展示操作,早期的图形界面也是基于 FrameBuffer 进行绘制的,有时在向外界展示 Linux 的命令行操作又不希望别人看到你的桌面时,可以通过获取 FrameBuffer 设备图像数据进行编码后推流或录制:
ffmpeg -framerate 30 -f fbdev -i /dev/fb0 output.mp4 # ctrl+alt+F1 进入命令行界面 # ctrl+alt+F7 进入图形界面
Linux 采集设备 v4l2 v4l2 主要用来采集摄像头,而摄像头通常支持多种像素格式,有些摄像头还支持直接输出已经编码好的 H.264 数据
查看参数
ffmpeg -h demuxer=v4l2
查看 v4l2 摄像头锁支持的色彩格式及分辨率
ffmpeg -hide_banner -f v4l2 -list_formats all -i /dev/vide0
采集摄像头
ffmpeg -hide_banner -s 1920x1080 -i /dev/vide0 output.avi
Linux 采集设备 x11grab
Linux 下面采集桌面图像时,通常采用 x11grab 设备采集图像,输入设备的设备名规则:
# 桌面录制(帧率:25,图像分辨率:1366x768,采集的设备:0.0) ffmpeg -f x11grab -framerate 25 -video_size 1366x768 -i :0.0 out.mp4 # 桌面录制指定起始位置(:0.0+300,200 指定了 x 坐标 300,y 坐标 200) # 注意:video_size 不要超过实际采集区域的大小 ffmpeg -f x11grab -framerate 25 -video_size 352x288 -i :0.0+300,200 out.mp4 # 桌面录制带鼠标记录的视频 ffmpeg -f x11grab -video_size 1366x768 -follow_mouse 1 -i :0.0 out.mp4
其他
x265 安装
下载
网站 1:http://www.videolan.org/developers/x265.html
hg clone http://hg.videolan.org/x265
网站 2:https://bitbucket.org/multicoreware/x265
hg clone https://bitbucket.org/multicoreware/x265
编译
sudo apt-get install mercurial cmake cmake-curses-gui build-essential yasm cd x265/build/linux ./make-Makefiles.bash make sudo make install
DTS、PTS 的概念
DTS、PTS 的概念如下所述:
DTS(Decoding Time Stamp):即解码时间戳,这个时间戳的意义在于告诉播放器该在什么时候解码这一帧的数据。
PTS(Presentation Time Stamp):即显示时间戳,这个时间戳用来告诉播放器该在什么时候显示这一帧的数据。
需要注意的是:虽然 DTS、PTS 是用于指导播放端的行为,但它们是在编码的时候由编码器生成的。
当视频流中没有 B 帧时,通常 DTS 和 PTS 的顺序是一致的。但如果有 B 帧时,就回到了我们前面说的问题:解码顺序和播放顺序不一致了。
比如一个视频中,帧的显示顺序是:I B B P,现在我们需要在解码 B 帧时知道 P 帧中信息,因此这几帧在视频流中的顺序可能是:I P B B,这时候就体现出每帧都有 DTS 和 PTS 的作用了。DTS 告诉我们该按什么顺序解码这几帧图像,PTS 告诉我们该按什么顺序显示这几帧图像。顺序大概如下:
其他常用命令
1、将文件当作源推送到 RTMP 服务器
参数解释 -r 以本地帧频读数据,主要用于模拟捕获设备。表示 ffmpeg 将按照帧率发送数据,不会按照最高的效率发送
2、将直播文件保存至本地
3、将其中一个直播流中的视频改用 H.264 压缩,音频不变,推送到另外一个直播服务器
4、将其中一个直播流中的视频改用 H.264 压缩,音频改用 aac 压缩,推送到另外一个直播服务器
5、将其中一个直播流中的视频不变,音频改用 aac 压缩,推送到另外一个直播服务器
6、将一个高清流复制为几个不同清晰度的流重新发布,其中音频不变
7、将当前摄像头以及扬声器通过 DSHOW 采集,使用 H.264/AAC 压缩后推送到 RTMP 服务器
8、将一个 JPG 图片经过 H.264 压缩后输出为 MP4 文件
9、将 MP3 转化为 AAC
10、将 AAC 文件转化为 flv 文件,编码格式采用 AAC
本文涉及的资料全部打包放到我 Github 仓:
GitHub:2022年,最新 ffmpeg 资料整理,项目(调试可用),命令手册,文章,编解码论文,视频讲解,面试题全套资料
有需要的可以前去下载,或者觉得还不错,请给我 Star,感谢支持!
评论