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 ...
随机推荐
- bzoj:3994:vijos1949: [SDOI2015]约数个数和
Description 设d(x)为x的约数个数,给定N.M,求 Input 输入文件包含多组测试数据. 第一行,一个整数T,表示测试数据的组数. 接下来的T行,每行两个整数N.M. O ...
- 51Nod 1046 A^B Mod C(日常复习快速幂)
1046 A^B Mod C 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 给出3个正整数A B C,求A^B Mod C. 例如,3 5 8,3^5 Mod 8 = ...
- JAVA爬虫实践(实践四:webMagic和phantomjs和淘宝爬虫)
webMagic虽然方便,但是也有它不适用的地方,比如定向的某个单页面爬虫,或者存在大量ajax请求,页面的跳转请求全都混淆在js里. 这时可以用webMagic结合phantomjs来真实模拟页面请 ...
- oracle 数据库——知识点总结(加示例)
新入oracle数据库,把目前学到的知识点记录下来,可能都比较基础,但还是比较全的,里面的示例都是自己在PL/SQL中跑过的,如果有错误,还望各位大侠指出哈. 创建用户 1.创建用户(使用管理员身份创 ...
- 基础二 day4 日记
1.list增删改查 l1 = [1,'alex',True,[1,2,3],(2,3,4),{'name':'alex'}]l1 = ['alex',True,'wusir','ritian','t ...
- Sqoop介绍
Sqoop介绍 http://sqoop.apache.org http://sqoop.apache.org/docs/1.4.6/SqoopUserGuide.html 1.什么是Sqoop? ...
- PHP UEditor富文本编辑器 显示 后端配置项没有正常加载,上传插件不能正常使用
UEditor是由百度web前端研发部开发所见即所得富文本web编辑器,具有轻量,可定制,注重用户体验等特点,开源基于MIT协议,允许自由使用和修改代码... 问题描述 我的编辑器在本地测试的时候没问 ...
- 织梦dedecmsV5.7联动类型无法显示的处理方法
最近织梦dedecms在新的功能中添加了一个联动类型这样的一个功能.所谓的联动类型,类似于一级目录下有二级目录,二级目录下又有三级目录,可以理解为数据结构中树形结构.级和级之间都是有着联系的.为了让大 ...
- 邓_mysql_面试
问题1:你如何确定 MySQL 是否处于运行状态? 答案: Debian 上运行命令service mysql status,在RedHat 上运行命令service mysqld status.然后 ...
- JXLS使用方法(文件上传读取)xlsx文件读取
1.官方文档:http://jxls.sourceforge.net/reference/reader.html 2.demo git地址:https://bitbucket.org/leonate/ ...