《ffmpeg开发实战:从零基础到短视频上线》一书在第10章介绍了轻量级流媒体服务器mediamtx,通过该工具可以测试rtsp/rtmp等流媒体协议的推拉流。不过mediamtx的功能实在是太简单了,无法应用于真实直播的生产环境,真正能用于生产环境的流媒体服务器还要看srs或者zlmediakit。
zlmediakit是一款国产的开源流媒体服务器,支持rtsp、rtmp、srt等主流直播协议,它的安装说明参见之前的文章《linux环境安装zlmediakit实现视频推流》。结合zlmediakit与ffmpeg实现rtsp/rtmp协议的推流功能,已在《linux环境安装zlmediakit实现视频推流》一文中详细介绍,这里单独讲解如何通过zlmediakit与ffmpeg实现srt协议的推流功能。
zlmediakit在编译和启动的时候已经默认支持srt,查看zlmediakit的配置文件config.ini,找到srt部分的配置信息如下,可见zlmediakit默认把9000端口分配给srt协议。
[srt]
latencymul=4
pktbufsize=8192
port=9000
timeoutsec=5
除此以外,zlmediakit无需另外调整什么配置,只要在启动之后运行下面的ffmpeg命令即可将视频文件向srt地址推流。注意,务必确保linux服务器上的ffmpeg已经集成了libsrt库,否则ffmpeg无法向srt地址推流,详细的集成步骤参见之前的文章《linux环境给ffmpeg集成libsrt和librist》。
ffmpeg -re -stream_loop -1 -i "/usr/local/src/test/cctv5.ts" -c copy -f mpegts 'srt://127.0.0.1:9000?streamid=#!::r=live/test,m=publish'
注意,上面命令中的srt地址后半段为“r=live/test,m=publish”,其中“r=live/test”表示srt的服务名称叫做“live/test”,而“m=publish”表示该地址属于发布功能也就是给推流方使用。
zlmediakit对视频源文件的封装格式也有要求,不仅要求源文件为ts格式,还要求推流格式也为ts格式,所以ffmpeg命令中添加了“-f mpegts”表示转换成mpeg的ts流格式。如果源文件不是ts格式,或者没转成mpegts格式,后续通过ffplay播放srt链接都会报下面的错误。
non-existing pps 0 referenced
此外,zlmediakit支持的音视频编码标准罗列在src/extension/frame.h中,详细的音视频支持标准如下所示。
#define codec_map(xx) \
xx(codech264, trackvideo, 0, "h264", psi_stream_h264, mov_object_h264) \
xx(codech265, trackvideo, 1, "h265", psi_stream_h265, mov_object_hevc) \
xx(codecaac, trackaudio, 2, "mpeg4-generic", psi_stream_aac, mov_object_aac) \
xx(codecg711a, trackaudio, 3, "pcma", psi_stream_audio_g711a, mov_object_g711a) \
xx(codecg711u, trackaudio, 4, "pcmu", psi_stream_audio_g711u, mov_object_g711u) \
xx(codecopus, trackaudio, 5, "opus", psi_stream_audio_opus, mov_object_opus) \
xx(codecl16, trackaudio, 6, "l16", psi_stream_reserved, mov_object_none) \
xx(codecvp8, trackvideo, 7, "vp8", psi_stream_vp8, mov_object_vp8) \
xx(codecvp9, trackvideo, 8, "vp9", psi_stream_vp9, mov_object_vp9) \
xx(codecav1, trackvideo, 9, "av1", psi_stream_av1, mov_object_av1) \
xx(codecjpeg, trackvideo, 10, "jpeg", psi_stream_jpeg_2000, mov_object_jpeg)
由此可见,如果待推流的视频文件不属于上面的音视频编码标准,将无法通过srt服务地址正常推流。
运行ffmpeg的srt推流命令之后,zlmediakit输出以下的日志信息,可见其srt推流功能正常运行。
[mediaserver] [576478-event poller 0] srtsession.cpp:103 onrecv | 1-11(127.0.0.1:33630)
[mediaserver] [576478-event poller 0] srttransportimp.cpp:166 operator() | test(127.0.0.1:33630) 允许 srt 推流
[mediaserver] [576478-event poller 0] decoder.cpp:143 ontrack | got track: h264
[mediaserver] [576478-event poller 0] decoder.cpp:143 ontrack | got track: mpeg4-generic
[mediaserver] [576478-event poller 0] decoder.cpp:97 onstream | add track finished
[mediaserver] [576478-event poller 0] mediasink.cpp:161 emitalltrackready | all track ready use 172ms
[mediaserver] [576478-event poller 0] mediasource.cpp:517 emitevent | 媒体注册:fmp4://__defaultvhost__/live/test
[mediaserver] [576478-event poller 0] multimediasourcemuxer.cpp:551 onalltrackready | stream: schema://__defaultvhost__/app/stream , codec info: mpeg4-generic[48000/2/16] h264[1280/720/25]
[mediaserver] [576478-event poller 0] mediasource.cpp:517 emitevent | 媒体注册:rtmp://__defaultvhost__/live/test
[mediaserver] [576478-event poller 0] mediasource.cpp:517 emitevent | 媒体注册:rtsp://__defaultvhost__/live/test
[mediaserver] [576478-event poller 0] mediasource.cpp:517 emitevent | 媒体注册:ts://__defaultvhost__/live/test
[mediaserver] [576478-event poller 0] mediasource.cpp:517 emitevent | 媒体注册:hls://__defaultvhost__/live/test
接着按照《ffmpeg开发实战:从零基础到短视频上线》一书“1.3 windows系统安装ffmpeg”的介绍,在个人电脑上安装ffmpeg并打开msys的命令行,运行下面的ffplay命令,期望从srt地址拉流播放。注意,务必确保电脑上的ffmpeg已经集成了libsrt库,否则ffplay无法播放srt链接,详细的集成步骤参见之前的文章《windows环境给ffmpeg集成libsrt》。
ffplay -i 'srt://124.xxx.xxx.xxx:9000?streamid=#!::r=live/test,m=request'
上面的srt拉流地址与之前的推流地址大同小异,除了把内网ip换成外网ip之外,就是把链接末尾的“m=publish”改成了“m=request”,其中request表示请求也就是用于拉流方。
ffplay运行后弹出播放器窗口,正常播放视频画面和声音。同时观察zlmediakit的服务日志如下所示:
[mediaserver] [576478-event poller 0] srtsession.cpp:103 onrecv | 2-16(112.5.138.145:57022)
[mediaserver] [576478-event poller 0] srttransport.cpp:731 onshutdown | peer close connection
[mediaserver] [576478-event poller 0] srtsession.cpp:118 onerror | 2-16(112.5.138.145:57022) 6(peer close connection)
[mediaserver] [576478-event poller 0] srttransportimp.cpp:14 ~srttransportimp | test(112.5.138.145:57022) srt 播放器(__defaultvhost__/live/test)断开,耗时(s):16
从以上日志可见,zlmediakit通过srt协议成功实现了视频直播的srt推拉流功能。
更多详细的ffmpeg开发知识参见《ffmpeg开发实战:从零基础到短视频上线》。
发表评论