常用命令
查找命令信息
ffmpeg -h #查看帮助信息
ffmpeg -h full #查看所有帮助信息
ffmpeg -version #查看版本
ffmpeg -buildconf #查看编译配置
ffmpeg -formats #查看可用格式
ffmpeg -muxers #查询可用复用器
ffmpeg -pix_fmts #查询可用的像素格式
ffmpeg -filters #查询可用的过滤器
ffmpeg -protocols #查询可用的协议
ffmpeg -codecs #查看可用编解码器
ffmpeg -decoders #查看可用解码器
ffmpeg -encoders #查看可用编码器
####查看
ffmpeg -hwaccels #查看所有可用的硬件加速器。
ffmpeg -h encoder=mjpeg #查看指定编码可用参数
ffmpeg -h decoder=mjpeg_cuvid#查看指定解码可用参数
ffmpeg -codecs | grep cuvid #模糊查找编码类型
ffmpeg -decoders | grep hevc #模糊查找解码类型
ffmpeg常用参数
-loglevel debug #设置日志类型(error,debug)
-i #设置输入流
-f #设置输出格式
-ss #设置开始时间
-t #设置时间长度
-vframes #设置输出的视频帧数
-r #设置帧速率
-b #设置视频码率
-s #设置画面宽高
-vf #设置视频过滤参数
-vcodec #设置视频编解码器;有copy 则表示同原始数据;
-re #以本地帧频读数据,主要用于模拟捕获设备
######用例######
##抽帧
ffmpeg -loglevel debug -rtsp_transport tcp -i rtsp://127.0.0.1:554/h264/ch1/main/av_stream -vf fps=1/1 %d.jpg
ffmpeg -i rtsp://127.0.0.1:554/h264/ch1/main/av_stream -vf fps=1/2 -qscale:v 2 mp4-%05d.jpeg
ffmpeg -re -rtsp_transport tcp -i rtsp://127.0.0.1:554/h264/ch1/main/av_stream -c mjpeg -vf fps=1/1 -d mjpeg_cuvid -strftime 1 %Y%m%d%H%M%S.jpg
ffmpeg -v quiet -loglevel error -re -rtsp_transport tcp -stimeout 5000000 -i rtsp://127.0.0.1:554/h264/ch1/main/av_stream -vf fps=1/1 -strftime 1 http://127.0.0.1:5081/task/getimage/0/c810662e16e711edaf4ce0a509004e110001-%Y%m%d%H%M%S.jpg
##获取视频画面分辨率
ffprobe -stimeout 5000000 -v quiet -loglevel error -select_streams v:0 -show_entries stream=width,height -rtsp_transport tcp -i rtsp://127.0.0.1:554/h264/ch1/main/av_stream
##过滤帧类型(I/P/B/S/SI)
ffmpeg -re -rtsp_transport tcp -i rtsp://127.0.0.1:6001/pss/l_860802 -vf "select=eq(pict_type\,I)",fps=1/1 -strftime 1 %Y%m%d%H%M%S-i.jpg
ffmpeg -i 1c428ca3710f178163640506224fe3ca.mp4 -vf fps=1/1 -vf "select=eq(pict_type\,I)" -strftime 1 %Y%m%d%H%M%S-i.jpg
ffmpeg -rtsp_transport tcp -i rtsp://127.0.0.1:554/h264/ch1/main/av_stream -acodec copy -vcodec copy -f flv 111.flv
#图片转视频
ffmpeg -f image2 -i temp/%d.jpg -s 640*640 test_640.mp4
ffmpeg -r 20 -f image2 -i %d.jpeg output.mp4 #r放前面变化帧数,影响播放时长
##合并
ffmpeg -f concat -safe 0 -r 1/2 -i kk.txt -vsync vfr -pix_fmt yuv420p 1.mp4
#kk.txt
file './temp/1.jpg' duration 2
#合并视频
ffmpeg -f concat -safe -i zz.txt -c copy -y res.mp4
简单介绍
流媒体协议:rtmp、rtsp\http、udp、rtp等
定义说明
DTS(Decoding Time Stamp) #解码时间戳;压缩帧的解码时间
PTS(Presentation Time Stamp) #显示时间戳;将压缩帧解码后得到的原始帧的显示时间
time_base #时间基;时间戳的单位;两者相成可以得到实际的时刻值(以秒等为单位)
timestamp #时间戳
tbn #容器中的时间基;关系AVStream.time_base
tbc #编解码器中的时间基;关系AVCodecContext.time_base
tbr #帧率或者场率(帧率的2倍)
帧类型
I帧(关键帧):帧内编码;包含完整的图像信息;不含运动矢量;常用于其它类型的帧之间;
P帧(单预测帧):帧间编码帧;利用之前的I帧或P帧;运动预测;一个I帧多个P帧;太多丢失的信息也多;
B帧(双向预测帧):帧间编码帧;利用双向帧(I或者P帧)进行预测编码;有着更高的压缩率但需要更高CPU占用和缓冲时间;不适用于实时性要求高的;
I帧越大P帧越小;I帧越小P帧越大
I帧大小取决于图像本身内容和压缩算法的空间部分
P帧的大小取决于图像变化的剧烈程度
P帧是预测来的,如果变化大,那么变化大,P帧就大
CBR和VBR下P帧的大小策略会不同,CBR时P帧大小基本恒定
采集顺序;编码顺序;传播顺序;解码顺序;显示顺序;
采集和显示顺序相同;其他三种顺序相同;
注意
I帧可以通过裸流判断抽帧;P/B帧不可以,因为基于上下帧编解码;
时间相关定义
- time_base:时间基;ffmpeg中时间戳的单位;定义了每个刻度多少秒;将秒分成n份;每个刻度1/n秒;time_base={1,n};
- pts:显示时间戳;表示压缩帧解码后得到的原始帧的显示时间;pts*time_base才是以秒为单位的时间戳;
- dts:解码时间;表示压缩帧的解码时间;dts*time_base才是以秒为单位的时间戳;
- tbr:帧率或者场率(帧率*2);
- tbc:编解码器中的时间基;等于 AVCodecContext.time_base 的倒数;
- tbn:容器中的时间基;等于AVStream.time_base 的倒数;
AV_TIME_BASE(AV_TIME_BASE_Q分数形式):内部时间基;用于ffmpeg内部处理;计算后的单位为us
注意:
- B帧pts和dts不一样;其他类型帧两者一致;
- 不同的封装格式时间基不一样;
- ffmpeg中处理音视的不同阶段对应的不同的时间基(eg:AVCodecContext/AVStream)
###时间值形式转换
static inline double av_q2d(AVRational a) #将时间基从AVRational类型转为Double类型;
###时间基转换函数
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq) av_const;
void av_packet_rescale_ts(AVPacket *pkt, AVRational tb_src, AVRational tb_dst);
###AVStream stream;
AVPacket packet;
packet 播放时刻值:timestamp(单位秒) = packet.pts × av_q2d(stream.time_base);
packet 播放时长值:duration(单位秒) = packet.duration × av_q2d(stream.time_base);
bit_rate 码率;越大视频占用内存越大
硬编解码
Intel:提供QSV/VAAPI;VAAPI可支持nvidia驱动;
Nvidia:NVENC/CUVID/NVDEC/VDPAU;VDPAU不支持编码;
NVIDA
NVDEC/NVENC是NVIDIA硬件加速编解码API;FFmpeg称为CUDA;
ffmpeg -hwaccels #可以查询系统支持的硬件加速器
ffmpeg -codecs | grep cuvid ##查看nvida硬编解码器
-hwaccel_device:指定硬编解码的GPU
解码
-
支持H264;H265;MPEG-2等;
-
FFmpeg 提供 NVDEC 和 CUVID hwaccels;不同之处在于帧在内存中的解码和转发方式;
ffmpeg -hwaccel cuda -i input output #CUDA ffmpeg -c:v h264_cuvid -i input output #CUVID
编码
-
支持H264;H265等;
-
Fmpeg提供NVENC,使用前编译时需要加上–enable-nvenc;
ffmpeg -i input -c:v h264_nvenc -profile high444p -pixel_format yuv444p -preset default output.mp4
编译安装
FFmpeg官网安装包下载
nv-codec-headers下载地址
普通配置
tar -xvf ffmpeg_4.2.7.orig.tar.xz
cd ffmpeg_4.2.7.orig/ffmpeg-4.2.7/
./configure --enable-shared --prefix=/usr/local/ffmpeg-4.2
sudo make && sudo make install
sudo ln -s /usr/local/ffmpeg-4.2/bin/ffmpeg /usr/bin/ffmpeg #添加软链接
#配置环境变量
gedit ~/.bashrc
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/ffmpeg-4.2/lib/ #在最后一行加入
source ~/.bashrc #生效
FFmpeg+Nvidia GPU硬件加速
### install nv-codec-headers
tar -zxvf nv-codec-headers_9.1.23.1.orig.tar.gz ##注意安装版本支持的最小驱动;当前支持 435.21 or newer
cd nv-codec-headers_9.1.23.1 && make install
### install ffmpeg
export PKG_CONFIG_PATH=/usr/lib/x86_64-linux-gnu/pkgconfig
./configure \
--extra-cflags="-I/usr/local/cuda/include/" \
--extra-ldflags=-L/usr/local/cuda/lib64 \
--enable-shared \
--enable-nvenc \
--enable-cuda \
--enable-cuvid \
--disable-x86asm \
--prefix=/usr/local/ffmpeg
make -j8
make install
#### 安装参数说明
--enable-shared ##生成动态库
--enable-nvenc #使用nvenc编码
--disable-x86asm #禁用独立x86程序集;报错可以直接禁用
#### 安装错误信息记录
1.编译出现缺少ffnvcodec错误时(硬件编解码的处理框架底层使用到NVCODEC组件;)
安装nv-codec-headers;
2.docker容器内cannot found libnvcuvid.so:
容器启动设置环境变量 -e NVIDIA_DRIVER_CAPABILITIES=all
NVIDIA_DRIVER_CAPABILITIES用于设置容器内允许使用显卡的能力;默认为utility,compute;
ffmpeg编译后没有ffplay
ffplay依赖sdl2环境;无则不会自动生成关于ffplay的编译选项;
SDL(Simple DirectMedia Layer)是一个跨平台的多媒体和游戏开发包,提供2D,音频,事件驱动,多线程和定时器等服务,它使用C语言写成,提供了多种控制图像、声音、输出的函数,让开发者只要用相同或是相似的代码就可以开发出跨多个平台(Linux、Windows、Mac OS X等)的应用软件。
sudo apt-get install libsdl2-2.0
sudo apt-get install libsdl2-dev
彻底卸载FFmpeg
sudo dpkg -l | grep ffmpeg
sudo find / | grep -w ffmpeg | sudo xargs rm -r -f
sudo apt-get --purge remove ffmpeg
sudo apt-get --purge autoremove