[RTMP] 国内各大视频直播CDN厂商推流抢流行为分析
背景
当存在一个推流客户端正在向rtmp://xxx.com/live/yyy推流时,又有另外一个推流客户端同时对这个地址进行推流,会发生什么呢?
查阅了 Adobe RTMP Spec 发现规范本身并未说明和定义这个场景下RTMP服务器应该怎么处理。
最近在实际工作中遇到部分客户对推流地址资源管理不恰当而导致重复推流报错的问题,且在查问题的过程中发现各个CDN厂商对“抢流”的处理各不相同,查阅相关文档说明发现资料甚少,故专门对它们的抢流行为做如下分析。
步骤
- 打开Wireshark捕获网卡,过滤规则:tcp && tcp.port == 1935(之所以不直接写rtmpt是因为还想观察传输层的行为)
- 获取对应厂商的推拉流URL,假设推流地址是:rtmp://xxx.com/live/yyy
- 使用ffmpeg推送一个本地电影文件:ffmpeg -re -i Movie-1.flv -vcodec h264 -f flv "rtmp://xxx.com/live/yyy"
- 使用另一个ffmpeg推送另一个本地电影文件到同个URL:ffmpeg -re -i Movie-2.flv -vcodec h264 -f flv "rtmp://xxx.com/live/yyy"
- 使用ffplay播放拉流地址内容
- 观察现象并分析Wireshark抓包结果
厂商
数据
注:下列结果仅代表发表本文的时候的各CDN厂家行为,随着厂商对服务器的更新迭代,可能会有所改变。
| 厂商 | 现象 | 结论 | 官方文档说明 | 与文档描述一致 | 
|---|---|---|---|---|
| 网宿 | 二次推流报错, ffplay拉流播放的是Movie-1内容 | 抓包分析发现第二次推流的RTMP连接能握手成功,但是 publish()请求发出之后服务器应答onStatus('NetStream.Publish.BadName')(见参考文档) | 直播推流与拉流 | ️ | 
| 阿里云 | 二次推流报错, ffplay拉流播放的是Movie-1内容 | 抓包分析发现第二次推流的RTMP连接能握手成功,但是推流几秒之后CDN服务器会发来TCP RST包强制断开RTMP的TCP连接 | 未找到 | |
| 腾讯云 | 二次推流成功, ffplay拉流播放的是Movie-1内容关闭第一个推流的程序,播放内容变成Movie-2的内容 | 官方文档表明会拒绝第二个推流请求,但是实际实验下来竟然是可以重复推且不报错,不知道腾讯云这么实现有没有其他用意 | 推流失败问题排查 | |
| 七牛云 | 二次推流报错, ffplay拉流播放的是Movie-1内容 | RTMP能握手成功,但是推流几秒之后服务器会发来TCP RST包强制断开RTMP的TCP连接 与官方文档中提到的后者挤掉前者的说法不一致 | 推流不成功的原因和解决方法 | |
| 金山云 | 二次推流报错, ffplay拉流播放的是Movie-1内容 | 抓包分析发现第二次推流的RTMP连接能握手成功,但是 publish()请求发出之后服务器应答onStatus('NetStream.Publish.AlreadyExistStreamName')(见参考文档) | 推拉流接入 | ️ | 
结论
总的来说,按当前实验结果来看,在这种细枝末节的功能点上,金山云的文档说明最清晰最规范,点个赞!
网宿的行为符合Flash AS3的定义,至少有据可依。
而腾讯云与七牛云的文档说明均存在错误的地方(至少本次实验中是这样的),尤其是腾讯云的现象让我很意外。
而阿里云竟然连这块的文档都没有。。(也许是我没搜到,若有的话望指正)
参考
[RTMP] 国内各大视频直播CDN厂商推流抢流行为分析的更多相关文章
- EasyDSS流媒体服务器软件(支持RTMP/HLS/HTTP-FLV/视频点播/视频直播)-正式环境安装部署攻略
		EasyDSS流媒体服务器软件,提供一站式的转码.点播.直播.时移回放服务,极大地简化了开发和集成的工作. 其中,点播功能主要包含:上传.转码.分发.直播功能,主要包含:直播.录像, 直播支持RTMP ... 
- 阿里云李刚:下一代低延时的直播CDN
		在上周落幕帷幕的多媒体领域技术盛会——LiveVideoStackCon音视频技术大会上,阿里云的高级技术专家李刚进行了<下一代低延时的直播CDN>技术分享.主讲人李刚,多年关注在CDN这 ... 
- 直播技术:从性能参数到业务大数据,浅谈直播CDN服务监控
		线上服务的有效监控和数据收集,一直是后端服务离不开的话题.直播作为一种经典的分布式系统,监控以及数据收集更是必不可少的工作.如何对海量的服务集群有效的监控和保活,又如何抓取集群中的碎片数据中来优化服务 ... 
- EasyDSS高性能RTMP、HLS(m3u8)、HTTP-FLV、RTSP流媒体服务器功能简介---视频直播、直播鉴权(如何完美将EasyDSS过渡到新版)
		作为RTMP流媒体服务器,接受RTMP推流.进行实时的直播流分发是EasyDSS流媒体服务自身一大核心功能.写本篇博文的一个目的是向大家介绍EasyDSS新版的直播间.匿名直播.和虚拟直播的功能, 另 ... 
- Android中直播视频技术探究之---视频直播服务端环境搭建(Nginx+RTMP)
		一.前言 前面介绍了Android中视频直播中的一个重要类ByteBuffer,不了解的同学可以 点击查看 到这里开始,我们开始动手开发了,因为我们后续肯定是需要直播视频功能,然后把视频推流到服务端, ... 
- 利用Nginx搭建RTMP视频直播,点播服务器,ffmpeg推流,回看
		一.环境和工具 ubuntu 14.04 desktop 不用server的原因是一部分的演示用到了linux视频播放和直播软件,自己还要装桌面,麻烦. 不建议使用 最新的16TLS,我一开始 ... 
- EasyDSS高性能RTMP、HLS(m3u8)、HTTP-FLV、RTSP流媒体服务器的视频直播录像、检索、回放方案
		需求背景: 近期遇到客户反馈对于直播摄像机录像功能是有一定的需求点的,其实EasyDarwin团队早就研发出对应功能,只是用户对于产品没有足够了解,因此本篇将对录像功能来做一次介绍. 首先,录像就是对 ... 
- 使用ckplayer搭建rtmp视频直播应用
		视频直播才有的是RTMP协议进行视频实时流传输,在这里我们用到的软件都是 adobe 公司的一个是:Flash Media Server4 另一个是flash media live encoder 这 ... 
- nginx RTMP FFmpeg 视频直播
		/**************************************************************************** * nginx RTMP FFmpeg 视频 ... 
随机推荐
- PHP语言基础知识
			目录 前言 第一章 PHP语言学习介绍 1.1 PHP部署安装环境 1.2 PHP代码工具选择 第二章 PHP代码基本语法 2.1 PHP函数知识介绍 2.2 PHP常量变量介绍 2.2.1 PHP变 ... 
- gnuplot添加直线和箭头
			http://blog.csdn.net/bill_chuang/article/details/18215051 6.在图中添加直线和箭头 gnuplot> set arrow from 0. ... 
- 安装VisualStudioCode
			下载VisualStudioCode https://code.visualstudio.com/ 安装插件 
- Cisco Packet Tracer NAT模拟实验
			Cisco Packet Tracer NAT模拟实验 by: 铁乐猫 date: 2020-09-22 cisco packet tracer : 7.2.2 NAT简介 NAT允许将私有IP地址映 ... 
- 交换机配置OSPF负载分担
			组网图形 OSPF负载分担简介 等价负载分担ECMP(Equal-Cost Multiple Path),是指在两个网络节点之间同时存在多条路径时,节点间的流量在多条路径上平均分摊.负载分担的作用是减 ... 
- layui的登录页面设计
			主要的结构 先导入layui的主要的js和css等 <html> <head> <meta charset="utf-8"> <title ... 
- 图解 IP 基础知识!
			我把自己以往的文章汇总成为了 Github ,欢迎各位大佬 star https://github.com/crisxuan/bestJavaer IP 协议 路由器对分组进行转发后,就会把数据包传到 ... 
- linux中搭建phpmyadmin详细流程
			一.phpmyadmin部署流程 1.1介绍 phpMyAdmin是一个以PHP为基础,以Web-Base方式架构在网站主机上的MySQL的数据库管理工具,让管理者可用Web接口管理MySQL数据库. ... 
- CentOS8 部署SqlServer
			官方文档https://docs.microsoft.com/zh-cn/sql/linux/quickstart-install-connect-red-hat?view=sql-server-li ... 
- webform中配置服务器控件的样式
			前台 Style <asp:Label ID="Label1" runat="server" Text="Label" Style=& ... 
