ffmpeg图片与视频命令笔记
引言
FFmpeg是一个开源免费跨平台的视频和音频流方案,它包含了非常先进的音频/视频编解码库libavcodec,为了保证高可移植性和编解码质量,libavcodec里很多codec都是从头开发的。FFmpeg在Linux平台下开发,但它同样也可以在其它操作系统环境中编译运行。
本篇除了会涉及到音频相关参数,但不会有音频相关操作或者详细解析,主要是针对图片与视频本身进行命令总结,不过在此之前,我想总结一下图片和视频的一些相关介绍。
ffmpeg中图片转换
RGB和YUV
说到图片自然最常见的是RGB,关于RGB,它的色彩模式是工业界的一种颜色标准,是通过对红®、绿(G)、蓝(B)三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色,而在我们保存图片下的格式png、jpg等默认都是以RGB进行存储,一般没有提供YUV格式的图片保存,那么什么是YUV呢?简单来说,YUV 和我们熟悉的 RGB 差不多,都是颜色编码方式,只不过它们的三个字母代表的意义与 RGB 不同,YUV 的 “Y” 表示明亮度(Luminance或Luma),也就是灰度值;而 ”U” 和 ”V” 表示的则是色度(Chrominance或Chroma),描述影像色彩及饱和度,用于指定像素的颜色。
常见的YUV的采样有YUV444,YUV422,YUV420:
YUV 4:4:4采样,每一个Y对应一组UV分量,表示完全取样。
YUV 4:2:2采样,每两个Y共用一组UV分量,表示2:1的水平取样,垂直完全采样。
YUV 4:2:0采样,每四个Y共用一组UV分量,表示2:1的水平取样,垂直2:1采样
更详细的定义可以参阅以下链接,介绍得很详细以及还有ffmpeg源码解读。
如何理解 YUV ?
ffmpeg图片命令
所以我们可以知道了YUV格式,而RGB和YUV格式在ffmpeg里的转换命令如下,具体源码部分怎么转的可以看上面的链接:
ffmpeg -i picture4.jpg -s 1080x720 -pix_fmt yuv420p picture4.yuv
ffplay -f rawvideo -video_size 1080x720 picture4.yuv
ffmpeg的语法格式以及大致的一些基本参数为:
ffmpeg [[options][`-i’ input_file]]… {[options] output_file}…
知道了语法,这里还有一些常用的设置或者图片命令,这里记录一下:
# 把darkdoor.[001-100].jpg序列帧和001.mp3音频文件利用mpeg4编码方式合成视频文件darkdoor.avi:
$ ffmpeg -i 001.mp3 -i darkdoor.%3d.jpg -s 1024x768 -author skypp -vcodec mpeg4 darkdoor.avi
# 要查看你的ffmpeg支持哪些格式,可以用如下命令:
$ ffmpeg -formats | less
# 还可以把视频文件导出成jpg序列帧:
$ ffmpeg -i bc-cinematic-en.avi example.%d.jpg
# 输出 YUV420P 原始数据
$ ffmpeg -i test.mp4 test.yuv
# 从视频前10s中提取图像,1s提取一帧
$ ffmpeg -i test.mp4 -t 10 -r 1 -f image2 pic-%03d.jpeg
# 截取一张352x240尺寸大小的,格式为jpg的图片
$ ffmpeg -i test.asf -y -f image2 -t 0.001 -s 352x240 a.jpg
# 把视频的前30帧转换成一个Animated Gif
$ ffmpeg -i test.asf -vframes 30 -y -f gif a.gif
# 截取指定时间的缩微图,-ss后跟的时间单位为秒
$ ffmpeg -i test.avi -y -f image2 -ss 8 -t 0.001 -s 350x240 test.jpg
rtmp和rtsp流
由于rtmp和rtsp没有研究多久,我这里主要引用一篇大佬文章:
一、什么是RTSP
RTSP(Real Time Streaming Protocol)实时流传输协议。是 TCP/IP 协议体系中的一个应用层协议,RTSP在体系结构上位于RTP和RTCP之上,它使用TCP或UDP完成数据传输如下图1所示。
二、RTSP、RTP、RTCP之间关系
RTSP发起/终结流媒体、RTP传输流媒体数据、RTCP对RTP进行控制、同步。如图2所示
三、RTSP交互过程
RTSP分为服务器与客户端,RTSP协议定义了服务器-客户端之间的接口,主要有OPTIONS,DESCRIBE,SETUP,PLAY,TEARDOWN,RECOED,ANNOUNCE。RTSP并不包括具体数据的传输,该功能一般由RTP与RTCP协议来实现,并可以通过TCP或UDP两种底层传输方式进行。
另外mark一篇写得很详细的关于rtsp流整个协议的组成结构博文:
EasyDarwin开源社区流媒体视频课程:流媒体传输控制协议(RTSP RTP SDP)详解之RTSP
具体的关于rtsp和rtmp的区别我觉得还是得去看看底层,目前以我的理解,rtsp和rtmp虽然实现都比较复杂,但在我的实验里面,rtsp比rtmp误错率高,误码率没仔细观察过,但应该也会高一点,难道因为它是管流分离的,需要1-3个通道,而rtmp只需要一个?或者我用的是rtmp-Nginx和srs,根据GitHub中大牛直播SDK,它们都是RTMP的服务器,而RTSP的是Darwin Stream Server,但我的问题是出现在解码,在同等情况下,多路RTSP的掉线情况永远比多路RTMP的测试高,这个也是我纠结了一两天无果,最后多加了一层rtsp转rtmp的逻辑而没有再对rtsp进行直接解码,然后问题得到缓解,如果有大佬知道为什么,可以私信我或者在评论区回复。
ffmpeg中视频相关
在上面关于ffmpeg图片相关的操作下的参数表格这里做得并不全面,只是列了一些常用的,更多的以及解释可以看看wiki会有所收获:
https://zh.wikipedia.org/wiki/FFmpeg
ffmpeg命令
ffmpeg -re -i test.mp4 -vcodec libx264 -acodec aac -f flv rtmp://localhost:1935/live/fff01
- 视频文件地址:test.mp4
- 推流拉流地址:rtmp://localhost:1935/live/fff01
- acc:RTMP的音频格式
- flv: RTMP的视频格式
这里能推srs是因为我在本地搭建了srs服务器,关于搭建可以看我之前的博文,这里不再介绍,另外加了-vcodec libx264其实就已经在转码了,ffmpeg默认是flv,如果要获取到mp4的支持,需要安装libx264,这个也在srs搭建那篇博文有写。
下面引用一些常用的命令,mp4和avi相关:
# 分离视频流 / 音频流
ffmpeg -i input_file -vcodec copy -an output_file_video
ffmpeg -i input_file -acodec copy -vn output_file_audio
# 视频解复用
ffmpeg –i test.mp4 –vcodec copy –an –f m4v test.264ffmpeg –i test.avi –vcodec copy –an –f m4v test.264
# 转码为码流原始文件
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
# 视频录制
ffmpeg –i rtsp://localhost:1935/test –vcodec copy out.avi
# mp4视频转flv
ffmpeg -i test.mp4 -acodec copy -vcodec copy -f flv test.flv
ts相关:
# H264视频转ts视频流
ffmpeg -i test.h264 -vcodec copy -f mpegts test.ts
# ts视频转mp4
ffmpeg -i test.ts -acodec copy -vcodec copy -f mp4 test.mp4
# udp视频流的推送
ffmpeg -re -i 1.ts -c copy -f mpegts udp://192.168.0.106:1234
# 切割ts分片
ffmpeg -i input.mp4 -c:v libx264 -c:a aac -strict -2 -f hls -hls_list_size 6 -hls_time 5 output1.m3u8
YUV相关:
# YUV序列播放
ffplay -f rawvideo -video_size 1920x1080 input.yuv
# YUV序列转AVI
ffmpeg –s w*h –pix_fmt yuv420p –i input.yuv –vcodec mpeg4 output.avi
# 从第0帧开始截取30帧
ffmpeg -s widthxheight -i input.yuv -c:v rawvideo -filter:v select="gt(n\, -1)" -vframes 30 out30.yuv
# 或者 0 - 30
ffmpeg -s widthxheight -i input.yuv -c:v rawvideo -filter:v select="between(n\, 0\, 29)" out30.yuv
ffmpeg视频流优化方向
ffmpeg 推流端可以通过一些控制参数来降低推流的延迟,主要优化方向是提高编码的效率、减少缓冲大小,当然有时候要牺牲一些代码质量和带宽。 关于ffmpeg 的转码延时测试与设置优化,总结了一些优化措施可以参考一下:
关闭 sync-lookahead
降低 rc-lookahead,但别小于 10,默认是-1
降低 threads(比如从 12 降到 6)
禁用 rc-lookahead
禁用 b-frames
缩小 GOP
开启 x264 的 -preset fast/faster/verfast/superfast/ultrafast 参数
使用-tune zerolatency 参数
前面的我没有尝试,后面几个参数,我之前是查到一篇关于-preset参数的实验,最后说是加-preset ultrafast和-tune zerolatency能达到速度延迟在0.2 ~ 0.6间,经过我实验确实有效,在多进程下能提高ffmpeg的消费情况。
ffmpeg加入GPU使用情况
关于ffmpeg中使用GPU,因为目前是两大主流显卡:AMD和NVIDIA,我这里主要用的NVIDIA的,然后它的官网中是有关于自家支持ffmpeg使用的NVENC和h264:
它主要是和CPU下的libx264对比:
Turing H.264 Video Encoding Speed and Quality
可以从Performance and Quality Results 质量检测结果中发现h264的各种性能都高于x264,但我个人实际体验过程中发现并没有多少优越性,画质上差不多,可能x264还要快一点?。。(狗头),其实里面线段还是很接近的,这里只能说仁者见仁智者见智,这个问题引用知乎的讨论帖:
GPU转码效果为什么不如纯CPU?
而关于GPU下的使用命令,可以看看wiki,它详细的描述了ffmpeg对GPU的可靠性还有一系列参数对接:
只要能编译成功,命令同样很简单,我之前的文章也写过编译以及测试,这里引用几个上面链接中的命令:
# Sample decode using CUDA:
ffmpeg -hwaccel cuda -i input output
# Sample decode using CUVID:
ffmpeg -c:v h264_cuvid -i input output
# Full hardware transcode with NVDEC and NVENC:
ffmpeg -hwaccel cuda -hwaccel_output_format cuda -i input -c:v h264_nvenc -preset slow output
# If ffmpeg was compiled with support for libnpp, it can be used to insert a GPU based scaler into the chain:
ffmpeg -hwaccel_device 0 -hwaccel cuda -i input -vf scale_npp=-1:720 -c:v h264_nvenc -preset slow output.mkv
原文链接:ffmpeg图片与视频命令笔记_ffmpeg 图片_submarineas的博客-CSDN博客
★文末名片可以免费领取音视频开发学习资料,内容包括(FFmpeg ,webRTC ,rtmp ,hls ,rtsp ,ffplay ,srs)以及音视频学习路线图等等。
见下方!↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
更多推荐
所有评论(0)