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 ...
随机推荐
- print与printf的区别
print与printf的区别 1,print 中不能使用%s ,%d 或%c: 2,print 自动换行,printf 没有自动换行. 纯粹做下笔记哈!很多东西不知道,也就只能这样了!
- 洛谷 P1219 八皇后【经典DFS,温习搜索】
P1219 八皇后 题目描述 检查一个如下的6 x 6的跳棋棋盘,有六个棋子被放置在棋盘上,使得每行.每列有且只有一个,每条对角线(包括两条主对角线的所有平行线)上至多有一个棋子. 上面的布局可以用序 ...
- codeforce 375_2_b_c
codeforce 375_2 标签: 水题 好久没有打代码,竟然一场比赛两次卡在边界条件上....跪 b.题意很简单...纯模拟就可以了,开始忘记了当字符串结束的时候也要更新两个值,所以就错了 #i ...
- 斐波那契数列 Library
http://acm.tju.edu.cn/toj/showp3267.html3267. Library Time Limit: 1.0 Seconds Memory Limit: 6553 ...
- Trees on the level(指针法和非指针法构造二叉树)
Trees on the level Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Other ...
- Legal or Not(拓扑排序判环)
http://acm.hdu.edu.cn/showproblem.php?pid=3342 Legal or Not Time Limit: 2000/1000 MS (Java/Others) ...
- 安装myeclipse后,打开时弹出:“该站点安全证书的吊销证书不可用”,怎样解决?
1.当弹出"该站点安全证书的吊销信息不可用.是否继续?"的对话框时,点击"查看证书",切换到"详细信息"TAB页,找到其"CRL分 ...
- Javascript Array 非常用方法解析
在ECMAScript5的Array中已经有了Array.prototype.forEach,Array.prototype.filter,Array.prototype.map等方法 1. map ...
- PHPCMS模板里面使用自定义函数
首先我在/phpcms/libs/functions/extention.func.php里面新增了一个函数 ============================================= ...
- IOS中UIScrollView的contentSize、contentOffset和contentInset属性
IOS中,UIScrollView是可以滚动的视图,其中最常用的UITableView就是继承了UIScrollView. 跟所有的view一样,UIScrollView有一个frame属 性,同时, ...