音视频流媒体,而用于处理流媒体的压缩、录制、编辑操作,开源并强大的工具屈指可数,FFmpeg就是常见的流媒体处理工具。
一、FFmpeg发布与录制RTMP流
RTMP推流需要配合RTMP流媒体服务器。
在流媒体中,直播是一种常见的技术中,而RTMP直播则是最为常见的一种实时直播,目前大部分直播产品都采用RTMP协议。
rtmp流操作参数如下:
rtmp推流命令
1 | # 本地视频文件推流 |
rtmp录制流/拉流
1 | # 录制rtmp到本地文件 |
发布点和流名称
在url地址”rtmp://127.0.0.1/live/test”中,live为发布点,test为流名称。可以使用rtmp_app参数和rtmp_playpath参数来设置。
因此推拉流可以换成如下命令:
1 | # 推流 |
rtmp_pageurl、rtmp_swfurl、rtmp_tcurl参数
在RTMP的Connect命令中包含了很多Object,这些Object中有一个pageUrl。可以使用rtmp_pageurl来设置这个字段以做标识,这与HTTP请求中的referer防盗链基本可以认为是起相同作用的,在RTMP服务器中可以根据这个信息进行referer防盗链操作。按照这个方式还可以设置swfUrl参数以及tcUrl的值。
1 | $ ffmpeg -rtmp_pageurl "http://127.0.0.1" -i "rtmp://127.0.0.1/live/test" |
二、FFmpeg发布与录制RTSP流
RTSP曾经是最常见的直播方式。后来在互联网中已经大多数转向RTMP、HTTP+FLV、HLS、DASH等方式。RTSP如今在安防领域中其依然主流。
RTSP传输协议可以有多种方式,不仅可以通过UDP,还可以通过TCP、HTTP隧道等。
rtsp流操作参数如下:
TCP方式录制RTSP直播流
FFmpeg默认使用的RTSP拉流的方式为UDP传输方式,为了避免丢包导致的花屏、绿屏、灰屏、马赛克等问题,还可以考虑将UDP传输方式改为TCP传输方式。
1 | # 使用tcp拉流 |
rtsp的tcp连接流程:
1、发起OPTIONS操作,查询RTSP服务器支持的方法,一般支持:DESCRIBE、SETUP、TEARDOWN、PLAY、PAUSE、OPTIONS、GET_PARAMETER、SET_PARAMETER等。
2、发起DESCRIBE操作,RTSP服务器返回了流数据的描述,数据为视频数据,编码为H.264格式,通过RTP进行传输。
3、发起SETUP操作,建立会话,获取会话Session,用于后续的操作。
4、带着这个Session发起PLAY操作,得到RTSP服务器的OK状态之后,即可进入接收视频数据的操作,也就是播放操作或录制操作等。
5、如果希望退出播放,或者停止录制,则可以通过TEARDOWN来操作。
另外可以设置user-agent参数,来区分用户端标识,用于防盗链等。
摄影机rtsp转rtmp推流
1 | $ ffmpeg -i "rtsp://admin:123456@127.0.0.1:554/h264/stream1" -vcodec libx264 -acodec aac -f flv -r 25 -b 2097152 -s 1280x720 -an "rtmp://127.0.0.1/live/test" |
三、FFmpeg录制HTTP流
http流操作参数如下:
在使用FFmpeg打开直播或者点播文件时,可以通过seek操作进行播放进度移动、定位等操作。
1 | # seekable参数使用,截取http视频30s后的内容 |
可以设置headers、user_agent等参数
1 | # 设置referer等headers和UA,可用于鉴权等控制 |
http拉流录制转封装
1 | # 拉取FLV直播流录制为flv |
HTTP流切片
FFmpeg支持文件列表方式的切片直播、点播流,除了HLS之外,还支持HDS流格式、DASH流格式等。
- HLS(HTTP Live Streaming),苹果公司提出,目前领先。
- HDS(HTTP Dynamic Streaming),Adobe公司提出。
- DASH(Dynamic Adaptive Streaming over HTTP),国际标准组MPEG制定的技术标准,避免苹果一家独大。目前B站从18年开始使用该格式,以保证了不同码率、纯音频的无缝切换。
1 | # HDS切片,输出到hds_folder文件夹 |
四、FFmpeg录制和发布UDP/TCP流
FFmpeg支持流媒体时不仅仅支持RTMP、HTTP这类高层协议,同样也支持UDP、TCP这类底层协议的流媒体的录制与发布。
TCP
tcp流操作参数如下:
1 | # 监听TCP时指定格式与TCP客户端连接所发布的格式相同时(本例为flv)均正常,如果不同,将会出现解析格式异常 |
UDP
udp流操作参数如下:
1 | # UDP监听接收流,监听udp端口6666并录制到本地,超时时间为10s |
五、FFmpeg推多路流
管道方式输出多路流
FFmpeg进行编码与转封装,编码消耗的资源比较多,转封装则相对较少,很多时候只需要转一次编码并且输出多个封装,在FFmpeg不支持tee文件封装之前,只能采用系统管道方式输出
1 | # 将会在RTMP服务器127.0.0.1中包含两路直播流,一路为test1,另外一路为test22,两路直播流的信息相同 |
tee封装格式输出多路流
1 | # 使用-f tee,ffmpeg编码一次,输出tee封装格式 |
tee协议输出多路流
FFmpeg在3.1.3版本之后支持tee协议输出多路流,使用方式更简单粗暴。
1 | $ ffmpeg -re -i input.mp4 -vcodec libx264 -acodec aac -f flv "tee:rtmp://127.0.0.1/live/test1 | rtmp://127.0.0.1/live/test2" |
六、视频采集
Windows平台采集
在Windows平台上,我们可以使用vfwcap去采集摄像头,但是这种方式已经过时了,虽然FFmpeg也提供了支持,但是推荐使用dshow去采集摄像头和麦克风。
1 | # 利用dshow枚举设备 |
对于windows的桌面采集,使用gdigrab。
1 | # 使用gdigrab采集桌面 |
Mac平台采集
1 | # 查看到当前支持的设备 |
从输出的信息中可以看到,当前系统中包含了3个设备,分别如下。
- [0] FaceTime HD Camera -视频输入
- [1] Capture screen 0 -视频输入
- [0] Built-in Microphone -音频输入
1 | # 采集摄像头,需要指定video_size和framerate,-i参数可以使用"FaceTime HD Camera" |
Linux平台采集
FFmpeg在Linux下支持的采集设备多种多样,包含FrameBuffer(fbdev)设备操作、v4l2设备操作、DV1394设备操作、OSS设备操作、x11grab设备操作等。