rtmp推流时间戳兼容问题
一直用简单的librtmp或者其他开源推流实现方式。没有太关注细节问题。
直到最近一次测试长时间推流。遇到了3字节时间戳溢出问题,即时间戳超过0xffffff,服务器断开。
复现方式:
用yasea推流到SRS或者Nginx-rtmp。
yasea版本要求2017-08-30以及以前的版本。
SRS不做特殊要求,本次使用v2.0.243 release版。
Nginx-rtmp版本不做特殊要求,本次使用Nginx: 1.13.3。
yasea推流到srs,超过4.5小时,当时间戳超过0xffffff,srs报错:
chunk stream is fresh, fmt must be , actual is . cid=, ret=(Resource temporarily unavailable)
read message header failed. ret=(Resource temporarily unavailable)
recv interlaced message failed. ret=(Resource temporarily unavailable)
thread process message failed. ret=(Resource temporarily unavailable)
thread recv cycle failed, ignored and retry, ret=
recv thread failed. ret=(Resource temporarily unavailable)
cleanup when unpublish
stream service cycle failed. ret=(Resource temporarily unavailable)
yasea推流到Nginx-rtmp,超过4.5小时,没问题。
第一反应不禁怀疑,srs兼容性有问题。随后用obs推流到srs和Nginx-rtmp,超过5个小时都没问题。
仔细阅读rtmp_specification_1.0.pdf 6.1.2 Chunk Message Header
page16开始。
yasea只发送了Type=0和Type=3的Chunks。
唯一不确定的环节就是extended timestamp的使用。
于是查看yasea代码和srs代码,既然是时间戳溢出处理的问题,就专注于这个角度。
每次测试都要等待4.5个小时,实在不应该。
于是找到对应时间戳的地方,加一个初始值。对应于:
audio.getHeader().setAbsoluteTimestamp(dts+0x00ffefff);
video.getHeader().setAbsoluteTimestamp(dts+0x00ffefff);
rtmpPacket.getHeader().setAbsoluteTimestamp((int) chunkStreamInfo.markAbsoluteTimestampTx()+0x00ffefff);
这样很快就运行到ffffff了。几分钟。
在分包发送的接口处打印时间戳日志,extended timestamp对应于:
com/github/faucamp/simplertmp/packets/RtmpHeader.java中writeTo()中
case TYPE_0_FULL: 和 case TYPE_3_RELATIVE_SINGLE_BYTE:
第一次尝试:
去掉Type=3中,Util.writeUnsignedInt32(out, extendedTimestamp);
注释掉下面一行:
Util.writeUnsignedInt32(out, extendedTimestamp);
推流时间戳超过0xffffff,推srs正常,推Nginx-rtmp报错。
第二次尝试:
Type=3的extended timestamp保证在Type=0后使用
只需要更改下面一句:
if (absoluteTimestamp >= 0xffffff)
改成
if (extendedTimestamp >= 0)
推流时间戳超过0xffffff,推srs偶尔报错,推Nginx-rtmp正常。
偶尔还是会出现问题。原因未明。
第三次尝试:
Type=3的时间戳和同一包分chunk时Type=0的时间戳,保持一致。
在上一次基础上改Type=3的代码如下:
推流时间戳超过0xffffff,推srs正常,推Nginx-rtmp正常。
然而在rtmp_specification_1.0.pdf文档中确实没有明确的规定。这个时间戳应该怎么做。
微信群里和srs、yasea两个项目的作者沟通,发现确实是这个问题。
srs大神winlin科普了一下,考虑周全的话,两种做法都要兼容。
如果Type=3有时间戳,这个时间戳就应该等于同一包中Type=0的时间戳。
如果Type=3没有时间戳。就用同一包中Type=0的传上来的时间戳。
实际上ffmpeg是这么做的,srs也是这么做的,Nginx-rtmp并没有兼容两者。
为了简单实用Type=1或者2,就不要发了。
所以是yasea引用的faucamp/simplertmp库有bug。
相关的问题,winlin的博客也有提到。参考:http://blog.csdn.net/win_lin/article/details/13363699
rtmp推流时间戳兼容问题的更多相关文章
- ffmpeg+EasyDSS流媒体服务器实现稳定的rtmp推流直播
本文转自EasyDarwin团队成员Alex的博客:http://blog.csdn.net/cai6811376/article/details/74783269 需求 在做EasyDSS开发时,总 ...
- EasyRTMP实现的rtmp推流的基本协议流程
EasyRTMP介绍 EasyRTMP是结合了多种音视频缓存及网络技术的一个rtmp直播推流端,包括:圆形缓冲区(circular buffer).智能丢帧.自动重连.rtmp协议等等多种技术,能够非 ...
- 3款知名RTMP推流模块比较:OBS VS SmartPublisher VS Flash Media Live Encoder
OBS 功能强大,几乎所有你想要的场景它都有,用起来很顺手.可以将桌面.摄像头.程序窗口通过rtmp推送到流媒体服务器上. 当然如果你是开发者,想基于OBS做二次开发,实现二次产品化的化,难度比较大, ...
- 安卓直播开源: RTMP 推流SDK
前些日子在github上提交了基于GPUImage的IOS直播推流SDK(https://github.com/runner365/GPUImageRtmpPush) 最近整理了android直播推流 ...
- C++ 实现的netstat -an 的功能<转>-目的为获取rtmp推流地址如果是域名的话查看1935的ip
目的可能是为了获取rtmp真正的推流ip 如果rtmp推流地址是域名,往CDN推流的话,需要nslookup 的那种DNS解析,然后获取的几个ip 可以使用netstat -n 等命令查看 1935 ...
- 前端多媒体(7)—— 在浏览器中实现rtmp推流
示例:https://young-cowboy.github.io/gallery/rtmp_client/index.html 在国内的直播场景中通常使用,rtmp协议作为推流协议.RTMP是Rea ...
- win10下一分钟快速搭建rtmp推流服务器
为了让大家少踩笔者踩过的坑,目前将工作中搭建rtmp推流服务器的步骤总结如下: 步骤1: 下载 nginx 1.7.11.3 Gryphon 下载链接: http://nginx-win.ecsds. ...
- Android 安卓直播开源: RTMP 推流SDK
前些日子在github上提交了基于GPUImage的iOS直播推流SDK(https://github.com/runner365/GPUImageRtmpPush) 最近整理了Android直播推流 ...
- 命令行利用ffmpeg实现rtmp推流《转》
ffmpeg在以前介绍过,是一个相当强大的工具,我们这次利用它实现rtmp推流(最终推流地址统一为rtmp://127.0.0.1:1935/live/123). 1.首先下载ffmpeg和ffpla ...
随机推荐
- THUSC2016 游记
浑浑噩噩地就出发了,只记得可以翘课,不知道自己要干什么去. Day 0 5点起床,到潮汕机场坐飞机.第一次坐飞机非常不爽起飞和降落时的加速度……终于还是转转地铁.动车在下午4点左右抵达目的地,西 ...
- Vijos P1113 不高兴的津津【模拟】
不高兴的津津 描述 津津上初中了.妈妈认为津津应该更加用功学习,所以津津除了上学之外,还要参加妈妈为她报名的各科复习班.另外每周妈妈还会送她去学习朗诵.舞蹈和钢琴.但是津津如果一天上课超过八个小时就会 ...
- HDU 1241 DFS
Oil Deposits Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tota ...
- c++(单向链表)
有的时候,处于内存中的数据并不是连续的.那么这时候,我们就需要在数据结构中添加一个属性,这个属性会记录下面一个数据的地址.有了这个地址之后,所有的数据就像一条链子一样串起来了,那么这个地址属性就起到了 ...
- 利用Selenium+PhantomJS 实现截图
using OpenQA.Selenium; using OpenQA.Selenium.PhantomJS; using System; using System.Drawing; using Sy ...
- Spark环境搭建(中)——Hadoop安装
1. 下载Hadoop 1.1 官网下载Hadoop http://www.apache.org/dyn/closer.cgi/hadoop/common/hadoop-2.9.0/hadoop-2. ...
- Spark算子--leftOuterJoin和rightOuterJoin
转载请标明出处http://www.cnblogs.com/haozhengfei/p/cb71cd3ac5d7965a2c61891659264d54.html leftOuterJoin和righ ...
- 网站地图怎么做?dedecms网站地图制作方法听语音
网站地图怎么生成?下面分享织梦dedecms系统网站地图的生成方式,怎么制作网站地图,方法很简单.下面介绍一下网站地图优化方法及制作方法. 工具/原料 一个网站 方法/步骤 第一步 登录网站后台 第二 ...
- [SinGuLaRiTy] 复习模板-搜索
[SinGuLaRiTy-1043] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. 桶排序 void bucketSort(int a[], ...
- OpenCV鼠标滑轮事件
鼠标的滑轮事件实现图像的缩放很方便,具体在回调函数中如下写: 其中scale可以在外部定义为全局变量,通过响应CV_EVENT_MOUSEWHEEL滑轮事件获取Scale的具体值. 获取Scale值需 ...