​《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开发实战:从零基础到短视频上线》一书。

FFmpeg开发笔记(四十二)使用ZLMediaKit开启SRT视频直播服务的更多相关文章

  1. 网站开发进阶(四十二)巧用clear:both

    网站开发进阶(四十二)巧用clear:both 前言 我们在制作网页中用div+css或者称xhtml+css都会遇到一些很诡异的情况,明明布局正确,但是整个画面却混乱起来了,有时候在IE6下看的很正 ...

  2. FFmpeg开发笔记(十):ffmpeg在ubuntu上的交叉编译移植到海思HI35xx平台

    FFmpeg和SDL开发专栏(点击传送门) 上一篇:<FFmpeg开发笔记(九):ffmpeg解码rtsp流并使用SDL同步播放>下一篇:敬请期待   前言   将ffmpeg移植到海思H ...

  3. Java开发学习(四十二)----MyBatisPlus查询语句之条件查询

    一.条件查询的类 MyBatisPlus将书写复杂的SQL查询条件进行了封装,使用编程的形式完成查询条件的组合. 这个我们在前面都有见过,比如查询所有和分页查询的时候,都有看到过一个Wrapper类, ...

  4. 树莓派开发笔记(十二):入手研华ADVANTECH工控树莓派UNO-220套件(一):介绍和运行系统

    前言   树莓派也可以做商业应用,工业控制,其稳定性和可靠性已经得到了验证,故而工业控制,一些停车场等场景也有采用树莓派作为主控的,本片介绍了研华ADVANTECH的树莓派套件组UNO-220-P4N ...

  5. .net开发笔记(十二) 设计时与运行时的区别(续)

    上一篇博客详细讲到了设计时(DesignTime)和运行时(RunTime)的概念与区别,不过没有给出实际的Demo,今天整理了一下,做了一个例子,贴出来分享一下,巩固前一篇博客讲到的内容. 简单回顾 ...

  6. BizTalk 开发系列(四十二) 为BizTalk应用程序打包不同的环境Binding

    我们在使用微软或者其他公司提供的BizTalk应用程序MSI包的时候经常会有一个目标环境的选择选项.该选项可以在不同的环境下使用不同的绑定(BizTalk应用程序配置)感觉很高级. 其实这个非常的简单 ...

  7. 安卓开发笔记(十二):SQLite数据库储存(上)

    SQLite数据库存储(上) 创建数据库 Android专门提供了一个 SQLiteOpenHelper帮助类对数据库进行创建和升级 SQLiteOpenHelper需要创建一个自己的帮助类去继承它并 ...

  8. Android UI开发第四十二篇——实现实现易信的圆形图像和对话列表的图像显示部分

    显示图像时,很多个性化显示,圆形或圆角.气泡等等,我们这一篇文章探讨一下圆形和气泡的显示,仿照易信中的实现,先看下效果图: 代码: public class RoundImageView extend ...

  9. Java开发笔记(十二)布尔变量论道与或非

    在编程语言的设计之初,它们除了可以进行数学计算,还常常用于逻辑推理和条件判断.为了实现逻辑判断的功能,Java引入了一种布尔类型boolean,用来表示“真”和“假”.该类型的变量只允许两个取值,即t ...

  10. PID控制器开发笔记之十二:模糊PID控制器的实现

    在现实控制中,被控系统并非是线性时不变的,往往需要动态调整PID的参数,而模糊控制正好能够满足这一需求,所以在接下来的这一节我们将讨论模糊PID控制器的相关问题.模糊PID控制器是将模糊算法与PID控 ...

随机推荐

  1. 分享一个关于Avl树的迭代器算法

    1 研究过程 前段时间在研究avl树的迭代实现,在节点不使用parent指针的情况下,如何使用堆栈来实现双向地迭代.我参考了网络上的大部分迭代器实现,要么是使用了parent指针(就像c++的map容 ...

  2. DevOps全面综述:从概念到实践

    这篇文章详尽介绍了DevOps的背景.核心实践.工具和技术,探讨了团队协作.文化建设及组织变革,旨在帮助企业高效实现持续交付和创新. 关注作者,分享互联网架构.云服务技术的全维度知识.作者拥有10+年 ...

  3. output打印ElasticSearch搜索条件searchSourceBuilder对象 toString方法

    打印搜索条件:log.info(searchSourceBuilder.toString());log.info("es搜索条件:[{}]", searchSourceBuilde ...

  4. Imdeploy笔记

    Smiling & Weeping ---- 天气不好的时候,我会小心地把自己心上的裂缝补起来.为什么?... LMDeploy 的量化和部署 1 环境配置 2 服务部署 2.1 模型转换 2 ...

  5. python selenium使用无头模式执行用例

    什么是无头模式? Headless Browser模式是浏览器的无界面状态,即在不打开浏览器界面的情况下使用浏览器. 该模式的好处如下: 1)可以加快web自动化测试的执行时间,对于web自动化测试, ...

  6. Springcloud开发之OpenFeign调用和认证

    SpringCloud开发cloud具有巨大的灵活性. 在调用其它服务的时候有多种方式,虽然本质一样,但是细节还是有所差异. 一.概述 当a服务调用b服务的时候有多种方式进行: 1.通过openFei ...

  7. 关于tomcat中servlet的url-pattern匹配规则

    首先需要明确几点容易混淆的规则: servlet容器中的匹配规则既不是简单的通配,也不是正则表达式,而是特定的规则.所以不要用通配符或者正则表达式的匹配规则来看待servlet的url-pattern ...

  8. .NET 个人博客系统

    前言 之前通过github学习了一个.net core的博客项目,最近也是完成了博客的备案,完善了一下.该项目是传统的MVC项目,可以进行主题的切换,采用Bootstrap进行前台页面的展示,有配套的 ...

  9. FFmpeg开发笔记(三十三)分析ZLMediaKit对H.264流的插帧操作

    ​<FFmpeg开发实战:从零基础到短视频上线>一书的"3.4.3  把原始的H264文件封装为MP4格式"介绍了如何把H.264裸流封装为MP4文件.那么在网络上传输 ...

  10. 背包DP——多重背包

    多重背包也是 0-1 背包的一个变式.与 0-1 背包的区别在于每种物品有 k 个,而非一个. 朴素 直接把相同的每个物品视作各个单独的物品,没有关联,仅条件相同: 转换后直接用01背包的状态转移方程 ...