当前位置: 首页 > news >正文

记一次关于SRS的webrtc音频播放前15秒卡顿的排查过程

一。背景

业务中有一个上位机浏览器对广播设备进行语音对讲的场景,使用了SRS作为流媒体服务器。上行语音流的流程为:后台程序采集设备实时音频,封装为rtmp协议推送到SRS,前端浏览器使用Webrtc协议播放实时音频。现场反馈:每次对讲过程中都出现前约15秒在浏览器端听到广播设备的音频卡顿和丢音,之后的音频通话恢复流畅。通过排查发现是由于客户电脑上配置了多个虚拟的网络IP造成的。最终将电脑上无关的IP移除之后,不再出现前15秒卡顿的现象。

二。场景复现

在解决了现场问题之后,能够定位到大约是由于客户端配置了对个IP地址,浏览器播放webrtc时在前期的ICE协商网络Candidate阶段出现了问题。为了彻底搞清楚异常的原理,在公司进行了场景复现和原理及代码分析。通过这次现场问题的解决以及深入研究,增加了对webrtc的了解。

1.在自己的笔记本电脑网卡上添加多个虚拟IP地址。

image

 2.在服务器端搭建一个SRS服务,并使用ffmpeg将MP4文件使用rtmp协议推流到SRS,模拟现场的设备上行语音流。推流指令:ffmpeg -re -stream_loop -1 -i weather.mp4 -c copy -f flv rtmp://172.23.57.85:1935/live/test

3.使用SRS的浏览器端工具进行webrtc播放,发现的确也出现前15秒卡顿的现象。

image

4..查看SRS的日志输出。发现有多次RTC: session address change的过程,持续时间刚好大约15秒

image

 5.查看客户端的抓包也发现有多个STUN的过程:

image

 6.通过以上证据能够很清楚的指向了问题出现的原因,就是由于在前15秒内,浏览器端使用多个IP地址进行stun的联调测试时,造成了srs不断切换webrtc的UDP连接造成的。

三。源码分析

1.根据SRS的关键日志,顺藤摸瓜进行源码分析,发现问题出在了srs对stun包的处理逻辑上。

2.首先查看srs的on_udp_packet函数,接收到UDP包时,会判断udp包的类型,有3种类型:stun包,srtcp包,srtp包

image

 3.当srs检测到udp包类型是stun包并且是binding request请求是,就会进入到update_sendonly_socket阶段。

image

4.在update_sendonly_socket函数中会首先检查skt是否就是当前使用的udp连接。webrtc稳定之后就应该是,主要是用于视频流传输过程中的stun保活报文。

5.如果与当前的udp连接连接不同,srs把这个连接添加到缓存,并粗暴的认为这个连接是有效的,切换当前sendonly_skt_的udp通道为错误的stun连接。

6.在前15秒内,浏览器不断使用不同的ip进行stun探测时,srs也相应不断的在切换udp通道,但其实有些通道是错误的,因此造成srtp发送数据的中断,从而造成卡顿和丢音的发生。

四。原理分析

根据上述的场景复现和源码分析,发现关键环节是webrtc的ICE协商机制。因此需要深入探究一下ICE协商的原理。并且还要带着两个问题:1)srs为收到stun的请求包了,说明通道是通的,为什么浏览器收不到stun的回复呢?2)srs既然不能粗暴的根据收到stun请求就认为udp连接是有效的,那么应该如何判断udp通道的有效性呢?

1.ICE的介绍(来自于大模型总结)

ICE 是 WebRTC 能够穿透复杂网络环境、实现点对点直连的核心机制。它的目标很简单:为两个想要通信的终端(比如两个浏览器)找到一条最优的、可通的网络路径。为什么需要ICE?在理想情况下,两个位于同一局域网内的设备可以直接用内网 IP 地址连接。但在现实中,互联网上的设备往往位于:1)防火墙之后:阻止外部发起的连接。2)NAT 设备之后:设备只有私有 IP,通过公网 IP 与外界通信。3)复杂的网络策略下:可能有多个网卡(Wi-Fi、有线、蜂窝网络)。因此,仅知道对方的公网 IP 和端口是不够的,因为对方的 NAT 可能不会允许你的数据包进入。ICE 就是为了系统性地解决这个“如何连接”的问题。

2.ICE的流程:ICE网络协商会对每一个候选地址(Candidate )进行stun的连通性检测。

image

3.浏览器作为webrtc的发起方进行STUN检测分为两个阶段:1)联调性检查的stun request;2)包含提名的stun request。

4.只有上述两个阶段都正常通过之后,才认为这个udp通道是有效的,是可以进行后续的音视频srtp发送的。

5.为什么srs能收到stun request,但是回复的stun response在浏览器端却收不到。是由于网络NAT的原因。

6.NAT丢包的技术细节:

# 浏览器发送请求时(客户端抓包视角)
源IP:192.168.1.134:56734 → 目标:172.23.57.85:8000# 经NAT转换后(公网视角)
源IP:公网IP_B:50001 → 目标:172.23.57.85:8000  # NAT创建临时映射# SRS回复(公网视角)
源IP:172.23.57.85:8000 → 目标:公网IP_B:50001# 问题发生点:
NAT设备检查映射表 → 无"公网IP_B:50001 ↔ 192.168.1.134:56734"条目 → 丢弃包

7.浏览器端的通道决策机制是什么?为什么前15秒在不断的stun请求。(来自大模型)

image

 8.通过上述的原理分析,基本能够从原理层面理清webrtc前15秒音频卡顿的原因了。问题的根本原因是SRS过早的认为stun通道有效,并切换了udp通道。

image

五。ZLM的实现方案

1.srs为什么那么设计,是处于什么样的考虑,还是就简单只是一个实现不够完善的bug?由于对srs的设计和代码了解的还没那么深刻,并且项目上能够接受删除掉无效的IP这种处理方式,就不再去深究了。

2.使用zlmediakit作为流媒体服务用同样的场景进行测试,效果如何呢?一如既往的没让人失望!!前15秒一点也不卡顿。

3.分析了下zlmediakit中关于iceServer的代码,通过状态切换的方式,做的很完善。当收到stun请求,必须判断stun包中包含了Candidate提名信息之后。才将stun的状态置为COMPLETED完成状态。

image

 4.浏览器与ZLM之间符合规范的ICE协商流程

image

 5.关于抓包也能印证。能够连通的后续stun包中都包含了

image

 6.通过此次现场问题的排查,并且对webrtc的ICE机制进行了较深入的分析,加深了对webrtc的理解。再次证明了webrtc是一个很博大精深的领域,需要不断的去学习积累。

http://www.jsqmd.com/news/325931/

相关文章:

  • LeetCode 2976.转换字符串的最小成本 I:floyd算法(全源最短路)
  • 一天一个Python库:markupsafe - 让你的字符串安全又优雅
  • ETASOLUTIONS钰泰 ETA1617S2G SOT23-6 LED驱动
  • 《实时渲染》第2章-图形渲染管线-2.5像素处理
  • CISO的战略抉择:面对“量子破解”威胁,是否该押注量子密钥分发?
  • 2026年非标热收缩包装机售后服务佳的厂家排名,哪家更靠谱
  • 暂时无法解决的关于STM32F103的RTC日期更新问题
  • 水利数采网关在智慧水务系统中的应用
  • 瑞安市华东包装机械有限公司技术实力如何,附可靠品牌排名
  • 盘点国内工业葡萄糖供货商,靠谱品牌推荐哪家
  • IT 的“控”与业务的“放”:构建基于 Web 原生架构的安全数据共享便捷的平台
  • 育龙化工生产工艺如何,起批量及优惠政策怎样
  • C++ 封装 C FFI 接口最佳实践:以 Hugging Face Tokenizer 为例
  • 2026年工业交换机品牌有哪些值得选,飞畅科技靠谱吗
  • 工业智能相机优质供货商的产品性价比排名如何?
  • 盘点镜视界,规模、产品及加盟培训支持情况大汇总
  • 震惊!2026年70%测试数据由AI合成
  • 2026年东北新中式家具品牌排名,致电库岸家具选靠谱之选
  • 剖析2026年温度变送器制造商,哪家口碑和性价比双高
  • 聊聊靠谱的新中式家具品牌商,新中式客厅家具特色全揭秘
  • 情感化量子测试:当代码需要“共情力”
  • 2026年天津新中式家具口碑推荐,库岸家具怎么样
  • 第二章 一致性协议
  • 5分钟掌握:绿色软件测试的国际新标准
  • 计算机毕业设计springboot基于JAVA的物流管理系统的设计与实现 基于SpringBoot框架的供应链运输调度平台设计与实现 基于Java技术的智能货运信息管理系统开发与实践
  • 基于SpringBoot的薪酬信息管理系统
  • AI重构测试生态下的内容突围之道
  • 2026年软件测试公众号热点解析:AI工作疲劳警报系统下的爆款密码
  • 心电辅助诊断-体检表格智能识读系统的设计与实现
  • 计算机毕业设计springboot基于VUE的儿童教育网站 基于SpringBoot与Vue框架的幼小衔接在线学习平台的设计与实现 采用SSM+Vue技术栈开发的少儿在线启蒙教育系统