SRT推流WebRTC播放闪断问题和解法

引言


WebRTC和SRT都是热门的技术栈,为了验证其在音视频传输的低延时性,引入了流媒体服务器SRS,开箱即用的快速部署,让闪电不用分精力做别的,直击核心诉求。

提出问题


原本计划摄像头用SRT推流到SRS,用RTMP观察延时数据,意外发现WebRTC也可以播放,而且秒开视频。于是在摄像头硬件上添加音视频码流推到SRS,在测试过程中发现浏览器播放端撑不过一晚即会中断,而且只有重启SRS或者摄像头才可以恢复。

分析问题


后来又发现SRS支持SRT拉流播放,于是用FFPLAYER播放SRT地址,即使浏览器播放端中断了,SRT拉流播放还是可以播放的,于是确认摄像头加上音视频的推流模块并不是引起SRS中断浏览器播放的原因。

但通过SRS的日志又发现一些出错信息,所以找了第三方推流软件进行再验证,使用专业版芯象导播软件经过一晚测试,浏览器播放端却没有中断。推流端和流媒体都没问题,难道是WebRTC的问题?

带着疑问,只能向谷歌请教了,好在之前看过一些Chrome调试WebRTC的文章,知道有个chrome://webrtc-internals网址可以调试网络状态和数据收发情况。也没发现任何问题,这样三端没问题即都有问题了。

经过反复测试SRT拉流,虽然会中断播放,但重新播放仍然能打开视频。于是剩下的排查手段只有分析SRS日志了,其实日志中出现serve error code的地方有三、四种,并不好确认是哪个出错码才引起问题现象。于是记录出现问题的时间,测试时摄像头是对着时间钟的,中断会停在某个时刻,这样就可以分析出引起问题的大概时间,最后从日志里发现出现serve error code=5011会引发问题。

再结合日志分析整个架构,摄像头通过SRT推流,先到SRS的SRT服务,然后转封装给RTMP服务,最后转RTC封装给浏览器播放端。这个过程里,SRT服务和RTMP服务是服务器本地localhost传输,理论上不会中断的。

在srt_to_rtmp.cpp中有个rtmp_client对象,负责把SRT数据转封装publish给RTMP服务。在on_ts_audio函数里需要判断是否有初始化过_aac_specific_config,该变量是string类型,保存了AAC的ADTS解码参数。每次建立RTMP推流即会发送codec.aac_packet_type=0(SrsAudioAacFrameTraitSequenceHeader)类型的消息包。在srs_kernel_codec.cpp中从收到的RTMP消息包中,判断acodec->is_aac_codec_ok是否收到SrsAudioAacFrameTraitSequenceHeader消息包。没收到即通知rtmp_client关停RTMP推流,因此导致5011错误。


同样在on_ts_video函数里需要判断是否有初始化过_h264_pps和_h264_sps,两变量都是string类型,分别保存了H.264的pps和sps解码参数,每次建立RTMP推流即会发送SrsVideoAvcFrameTraitSequenceHeader类型的消息包。在srs_kernel_codec.cpp中从收到的RTMP消息包中,判断vcodec->is_avc_codec_ok是否收到SrsVideoAvcFrameTraitSequenceHeader消息包,没收到即报音频同样错误。


 

解决问题


定位出引起问题的地方,以及分析了代码流程后,再回头从SRS日志中发现RTMP服务和浏览器播放端之间网络抖动时断开了连接,一段时间后没有视频消费者,会导致关闭RTMP服务的Publish线程,而SRT服务在收到设备推送的SRT数据,又会重新连接到RTMP服务。连接后需要重新发送音频和视频的解码参数(ADTS,SPS,PPS)到RTMP服务,但SRT服务没有关停过,而SRS此处逻辑忽略了此时需重发这些信息,以及清除发送缓冲(_send_map)。需清除_send_map是因为缓存中还有不带ADTS的音频消息包,一旦发送到RTMP服务就出现5011错误,在srs_app_conn.cpp的资源管理器(SrsResourceManager)中强制把RTMP当作僵尸线程关闭,如此这般循环使得浏览器即使重启也打开不了视频。

首先在rtmp_packet_queue对象中增加clear_queue函数,在rtmp_client每次connect中清除_send_map缓存,代码片段1、2如下:

//清除发送缓存
void rtmp_packet_queue::clear_queue() {
    _send_map.clear();
}
代码片段1:新增清除发送缓存函数

srs_error_t rtmp_client::connect() {
    srs_error_t err = srs_success;
    srs_utime_t cto = SRS_CONSTS_RTMP_TIMEOUT;
    srs_utime_t sto = SRS_CONSTS_RTMP_PULSE;

    _last_live_ts = now_ms();
    if (_connect_flag) {
        return srs_success;
    }

    if (_rtmp_conn_ptr.get() != nullptr) {
        return srs_error_wrap(err, "repeated connect %s failed, cto=%dms, sto=%dms.",
                            _url.c_str(), srsu2msi(cto), srsu2msi(sto));
    }

    _rtmp_conn_ptr = std::make_shared<SrsSimpleRtmpClient>(_url, cto, sto);

    //增加清除发送缓存
    srs_trace("clear send queue url:%s", _url.c_str());
    _rtmp_queue.clear_queue();

    if ((err = _rtmp_conn_ptr->connect()) != srs_success) {
        close();
        return srs_error_wrap(err, "connect %s failed, cto=%dms, sto=%dms.",
                            _url.c_str(), srsu2msi(cto), srsu2msi(sto));
    }

    if ((err = _rtmp_conn_ptr->publish(SRS_CONSTS_RTMP_PROTOCOL_CHUNK_SIZE)) != srs_success) {
        close();
        return srs_error_wrap(err, "rtmp client in srt2rtmp  publish fail url:%s", _url.c_str());
    }
    _connect_flag = true;

    return err;
}
代码片段2:在connect中调用清除发送缓存

为了每次新建RTMP推流能初始化音视频解码参数,在rtmp_client的close函数中需重置_aac_specific_config、_h264_spa和_h264_pps,代码片段3如下:

void rtmp_client::close() {
    _connect_flag = false;
    if (!_rtmp_conn_ptr) {
        return;
    }
    srs_trace("rtmp client close url:%s", _url.c_str());
    _rtmp_conn_ptr->close();
    _rtmp_conn_ptr = nullptr;

    //关闭时重置音频和视频解码信息
    _aac_specific_config = "";
    _h264_sps = "";
    _h264_pps = "";
}
代码片段3:在close中重置音频和视频解码信息

结论


问题能解决,说明SRS前辈搭的框架优秀毋庸置疑。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/884761.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

视频压缩怎么压缩更小?分享释放视频占用空间的小技巧

想问问同样在做视频自媒体博主的你&#xff0c;都是怎么解决占满内存的视频素材的&#xff1f; 是有听说有一部分博主会把录制好的&#xff0c;还未使用的视频素材&#xff0c;用工具压缩他们的体积&#xff0c;以减少占用内存空间。 小编也有试过&#xff0c;发现视频的体积是…

oracle解决关联查询报invalid number问题

出现问题的原因和背景 oracle进行关联查询的时候因为字段存在多个用逗号切割的id&#xff0c;导致查询的过程中报无效数字或非法数字 问题复现 新建表A CREATE TABLE "A" (id NUMBER NOT NULL,name VARCHAR2(255 BYTE) )INSERT INTO "A" VALUES (1, 上海…

【Spring】lombok、dbUtil插件应用

一、lombok插件 1. 功能&#xff1a;对实体类自动&#xff0c;动态生成get、set方法&#xff0c;无参、有参构造..... 2. 步骤&#xff1a; &#xff08;1&#xff09;idea安装插件(只做一次) &#xff08;2&#xff09;添加坐标 &#xff08;3&#xff09;编写注解 NoArgsCo…

Codeforces Round 975 (Div. 2) A-C 题解

这次看到 C 题分数 1750 就开始害怕了&#xff0c;用小号打的比赛&#xff0c;一直觉得做不出来&#xff0c;最后才想到 A. Max Plus Size 题意 给你一些整数&#xff0c;选择一些涂成红色&#xff0c;两两不能相邻&#xff0c;你的得分为&#xff1a; [ 红色元素的个数 ] …

Tableau数据可视化入门

目录 一、实验名称 二、实验目的 三、实验原理 四、实验环境 五、实验步骤 1、Tableau界面引导 2、数据来源 3、数据预处理操作 4、制作中国各个地区的利润图表 4.1条形图 4.2气泡图 5、制作填充地球图 一、实验名称&#xff1a; 实验一&#xff1a;Tableau数据可视…

PyCharm 的安装和配置

环境要求&#xff1a; OS&#xff1a;Windows / macOS / Linux (此处使用 Windows 10 进行演示)Python&#xff1a;包括但不限于 Anaconda&#xff0c;miniconda&#xff0c;Python。在 Windows 下只要能找到 python.exe 即可 Download 进入 PyCharm 官网&#xff0c;选择对…

gitlab修改访问端口

目录 1.找到gitlab.rb文件&#xff0c;一般在/etc/gitlab/路径下 2.打开配置文件&#xff0c;加上代码 3.重新配置 4.重启gitlab 1.找到gitlab.rb文件&#xff0c;一般在/etc/gitlab/路径下 2.打开配置文件&#xff0c;加上代码 打开文件 sudo vi gitlab.rb 加上默认端口配…

上交所服务器崩溃:金融交易背后的技术隐患暴露杭州BGP高防服务器43.228.71.X

一、上交所宕机事件始末 2024 年 9 月 27 日&#xff0c;上交所交易系统突发崩溃&#xff0c;这一事件犹如一颗巨石投入平静的湖面&#xff0c;引起了轩然大波。当天上午&#xff0c;众多投资者反馈券商交易出现延迟问题&#xff0c;随后上交所发布了《关于股票竞价交易出现异常…

OJ在线评测系统 前端创建题目(增) 更新题目(改) 题目列表(查) 以及做题页面的开发 基于VUECLI脚手架画界面

目录 前端创建页面的开发一 创建一个路由 用acro design写 前端创建页面的开发二 题目管理页面 搜索 最終效果 题目更新页面的开发 携带参数的那种 修改路由 页码更新细节 我们先处理菜单项的权限控制和权限隐藏 在这里改 属性绑定一个函数 可以参考聚合搜索项目…

某客户Oracle RAC无法启动故障快速解决

某日&#xff0c;9:50左右接到好友协助需求&#xff0c;某个客户Oracle RAC无法启动&#xff0c;并发过来一个报错截图&#xff0c;如下&#xff1a; 和客户维护人员对接后&#xff0c;远程登录服务端进行故障分析。 查看hosts信息&#xff0c;首先进行心跳测试&#xff0c;测…

RK3568的型号区分

RK3568是瑞芯微公司设计开发和生产的MPU芯片产品。RK3568芯片是一款定位中高端的通用型SOC&#xff0c;采用22nm制程工艺&#xff0c;集成4核ARM架构A55处理器和Mali G52 2EE图形处理器&#xff0c;支持4K解码和1080P编码。内置独立的NPU&#xff0c;0.8Tops算力&#xff0c;可…

【tower-boot 系列】开源RocketMQ和阿里云rockerMq 4.x和5.x集成 (一)

RocketMQ 简单介绍 阿里云rockerMq 4.x和5.x集成 一、云平台创建实例 参考文档&#xff1a; 阿里云api 阿里云 创建实例 二、skd集成思路 公司用的RocketMQ一般是自建开源apache的RocketMQ和上阿里云的RocketMQ&#xff0c;目前阿里云支持4.x和5.x版本 项目集成思路&…

巨控协议转换网关GRM321GRM322GRM323应用场景

巨控工业协议网关GRM321,GRM322,GRM323是网口型网关&#xff0c;支持各种PLC的TCP协议&#xff0c;具备多路RS485,RS232和三个TCP网口。能实现RS485&#xff0c;RS232和TCP的工业协议的零代码无缝转换&#xff0c;能极大节约工程师编程时间&#xff0c;保障数据采集的可靠性。 …

无人机侦测:频谱无线电侦测设备技术详解

无人机侦测中的频谱无线电侦测设备技术是一项复杂而关键的技术&#xff0c;它主要通过分析无线电频谱中的信号来探测和识别无人机。以下是该技术的详细解析&#xff1a; 一、技术原理 频谱探测技术&#xff1a;该技术通过分析信号在频域上的分布和特性&#xff0c;来识别、测…

[大语言模型-论文精读] ACL2024-长尾知识在检索增强型大型语言模型中的作用

ACL2024-长尾知识在检索增强型大型语言模型中的作用 On the Role of Long-tail Knowledge in Retrieval Augmented Large Language Models Authors: Dongyang Li, Junbing Yan, Taolin Zhang, Chengyu Wang, Xiaofeng He, Longtao Huang, Hui Xue, Jun Huang 1.概览 问题解决&…

荣业食品销售费用每年上亿元:主要产品收入大降,电商占比过低

《港湾商业观察》黄懿 今年3月&#xff0c;广东荣业食品有限公司的控股公司Wing Yip Food Holdings Group Limited&#xff08;下称“荣业食品”&#xff09;向美国SEC递交了纳斯达克上市申请。 据悉&#xff0c;2023年11月&#xff0c;商务部宣布移除了一批共计55家因长期经…

AI大模型的基本流程

这篇文章主要是记录自己的问题&#xff0c;虽然说AI大数据模型已经出现了很久&#xff0c;但是一直找不到它与企业的关系&#xff0c;因为有ghat gpt,只要应用这个人工智能就可以了&#xff0c;所以思想一直没有转变过来。 昨天梳理了一下AI大数据的模型&#xff0c;解答了我的…

VMware 虚拟机配置固定 IP

相关链接&#xff1a; SSH 服务配置与 Network error: Connection refused 解决 1. 查看 VMware 网络配置 点击【编辑】 -> 【虚拟网络编辑器】 选择【更改设置】查看 VMnet8 配置信息 选择【NAT设置】 查看当前虚拟机的网关是 192.168.17.2&#xff08;也可以进行修改…

Tpflow:提升开发效率的PHP工作流引擎

Tpflow&#xff1a;提升开发效率的PHP工作流引擎 今天要跟大家介绍的是一款能够显著提升开发效率的工具——Tpflow&#xff01;它是一个专门为PHP开发者设计的工作流引擎&#xff0c;致力于帮助你减少80%以上的代码量&#xff0c;轻松管理复杂的业务流程。让我们一起来看看它的…

java计算机毕设课设—超级玛丽游戏(附源码、文章、相关截图、部署视频)

这是什么系统&#xff1f; 资源获取方式在最下方 java计算机毕设课设—超级玛丽游戏(附源码、文章、相关截图、部署视频) 超级玛丽游戏是一款经典的平台游戏&#xff0c;自1985年推出以来&#xff0c;已成为全球玩家心目中的经典之作。玩家操控玛丽奥在多样化的关卡中进行冒…