为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

librtmp使用扩展时间戳时服务器会将连接断开解释

2018-02-14 11页 doc 87KB 25阅读

用户头像

is_654168

暂无简介

举报
librtmp使用扩展时间戳时服务器会将连接断开解释librtmp使用扩展时间戳时服务器会将连接断开解释 rtmpdump的librtmp时间戳有问题,服务 器会断开连接 分类: ffmpe c++g linux open-sourc 2013-10-28 21:49 700e人阅读 评论(7) 收藏 举 报 # header 0x44 0xff 0xff 0xff 0x00 0x01 0x19 0x08 # extended timestamp 0x7f 0xff 0xf8 0x00 # body 0xaf 0x01 0x01 0x40 0x22 0x80 ...
librtmp使用扩展时间戳时服务器会将连接断开解释
librtmp使用扩展时间戳时服务器会将连接断开解释 rtmpdump的librtmp时间戳有问题,服务 器会断开连接 分类: ffmpe c++g linux open-sourc 2013-10-28 21:49 700e人阅读 评论(7) 收藏 举 报 # header 0x44 0xff 0xff 0xff 0x00 0x01 0x19 0x08 # extended timestamp 0x7f 0xff 0xf8 0x00 # body 0xaf 0x01 0x01 0x40 0x22 0x80 0xa3 0x7f 0xf8 0x85 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d #header 0xc4 # extended timestamp # error here #body 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 0x2d 对于0xC这种后续的chunk包的extended timestamp该不该发,rtmp协议中说是不发,但是FMLE是发的,推流超过4.5小时就需要用extended timestamp了。 rtmpdump里面的librtmp,不会发这个包,,ffmpeg里面用--enable-librtmp就会使用这个rtmp的库,,而且是在开始就会发这个包。 6.1.3. Extended Timestamp [plain] view plaincopyprint? , This field is transmitted only when the normal time stamp in the , chunk message header is set to 0x00ffffff. If normal time stamp is , set to any value less than 0x00ffffff, this field MUST NOT be , present. This field MUST NOT be present if the timestamp field is not , present. Type 3 chunks MUST NOT have this field. This field is transmitted only when the normal time stamp in the chunk message header is set to 0x00ffffff. If normal time stamp is set to any value less than 0x00ffffff, this field MUST NOT be present. This field MUST NOT be present if the timestamp field is not present. Type 3 chunks MUST NOT have this field. 有可能是adobe变更了这个协议,也就是说,FMLE给FMS,FMS给flash-player,都是带这个时间戳的。 收包时,服务器端则需要检测下,若接下来的4字节不是extended timestamp,那么就忽略就好了。 发包时,只能采取配置,要么发,要么不发。默认发就好了。 看nginx-rtmp代码: ? [cpp] view plaincopyprint , ngx_rtmp_recv(ngx_event_t *rev) , { , for( ;; ) { ? /* parse headers */ ,, if (b->pos == b->start) { ,, /* chunk basic header */ ,, fmt = (*p >> 6) & 0x03; ,, csid = *p++ & 0x3f; ,, if (fmt <= 2 ) { ,, /* timestamp: big-endian 3b -> little-endian 4b */ ,, pp = (u_char*)timestamp; ,, ext = (timestamp == 0x00ffffff); ,, if (fmt <= 1) { ,? /* size: big-endian 3b -> little-endian 4b type*/ ,, pp = (u_char*)&h->mlen; ,, h->type = *(uint8_t*)p++; ,, if (fmt == 0) { ,, /* stream: little-endian 4b -> little-endian 4b */ ,, pp = (u_char*)&h->msid; ,, } ,, } ,, } ,, /* extended header */ ,? if (ext) { ,, pp = (u_char*)timestamp; ,, pp[3] = *p++; ,, pp[2] = *p++; ,, pp[1] = *p++; ,, pp[0] = *p++; ,, } ngx_rtmp_recv(ngx_event_t *rev) { for( ;; ) { /* parse headers */ if (b->pos == b->start) { /* chunk basic header */ fmt = (*p >> 6) & 0x03; csid = *p++ & 0x3f; if (fmt <= 2 ) { /* timestamp: big-endian 3b -> little-endian 4b */ pp = (u_char*)timestamp; ext = (timestamp == 0x00ffffff); if (fmt <= 1) { /* size: big-endian 3b -> little-endian 4b type*/ pp = (u_char*)&h->mlen; h->type = *(uint8_t*)p++; if (fmt == 0) { /* stream: little-endian 4b -> little-endian 4b */ pp = (u_char*)&h->msid; } } } /* extended header */ if (ext) { pp = (u_char*)timestamp; pp[3] = *p++; pp[2] = *p++; pp[1] = *p++; pp[0] = *p++; } 可见,不管是什么chunk,只要有extended-timestamp,nginx-rtmp都会读这个。所以 nginx-rtmp对接FMLE是没有问题的,对接librtmp有问题。 更好的做法是判断下读出来的extended timestamp是否是和之前的一样,如果不是一样 说明没有发,就忽略。 nginx-rtmp发包的逻辑: [cpp] view plaincopyprint? ,, ngx_rtmp_prepare_message ,, { ,, /* create fmt3 header for successive fragments */ ,? thsize = p - out->buf->pos; ,, ngx_memcpy(th, out->buf->pos, thsize); ,, th[0] |= 0xc0; ,, /* message header */ ,, if (fmt <= 2) { ,, } ,, ,, /* extended header */ ,, if (ext_timestamp) { ,, pp = (u_char*)&ext_timestamp; ,? *p++ = pp[3]; ,, *p++ = pp[2]; ,, *p++ = pp[1]; ,, *p++ = pp[0]; ,, ,, /* This CONTRADICTS the standard ,, * but that's the way flash client ,, * wants data to be encoded; ,, * ffmpeg complains */ ,, if (cscf->play_time_fix) { ,? ngx_memcpy(&th[thsize], p - 4, 4); ,, thsize += 4; ,, } ,, } ngx_rtmp_prepare_message { /* create fmt3 header for successive fragments */ thsize = p - out->buf->pos; ngx_memcpy(th, out->buf->pos, thsize); th[0] |= 0xc0; /* message header */ if (fmt <= 2) { } /* extended header */ if (ext_timestamp) { pp = (u_char*)&ext_timestamp; *p++ = pp[3]; *p++ = pp[2]; *p++ = pp[1]; *p++ = pp[0]; /* This CONTRADICTS the standard * but that's the way flash client * wants data to be encoded; * ffmpeg complains */ if (cscf->play_time_fix) { ngx_memcpy(&th[thsize], p - 4, 4); thsize += 4; } } nginx-rtmp还特意说明了flash客户端就是和rtmp规范不一样。 out->buf->pos就是指向包的第一个chunk,若有extended-timestamp,那么肯定会在第一个包加上extended timestamp;后面还有个th和thsize,就是给后续的type=3的chunk包的,会加上这4字节的extended timestamp: [cpp] view plaincopyprint? ,, /* This CONTRADICTS the standard ,, * but that's the way flash client ,, * wants data to be encoded; ,, * ffmpeg complains */ ,, if (cscf->play_time_fix) { ,, ngx_memcpy(&th[thsize], p - 4, 4); ,? thsize += 4; ,, } ,, ,, /* append headers to successive fragments */ ,, for(out = out->next; out; out = out->next) { ,, out->buf->pos -= thsize; ,, ngx_memcpy(out->buf->pos, th, thsize); ,, } /* This CONTRADICTS the standard * but that's the way flash client * wants data to be encoded; * ffmpeg complains */ if (cscf->play_time_fix) { ngx_memcpy(&th[thsize], p - 4, 4); thsize += 4; } /* append headers to successive fragments */ for(out = out->next; out; out = out->next) { out->buf->pos -= thsize; ngx_memcpy(out->buf->pos, th, thsize); } 所以nginx-rtmp收发包都是需要这个extended-timestamp,对于chunk type为3的包。 另外,把chunksize设置大一点,最大是65536,避免发type=3的chunk包,也是一个很好的方法。不过视频的I帧一般较大,超过64KB也有可能。 The maximum chunk size can be 65536 bytes and minimum 128 bytes. 按照这种规则,即type=3的chunk也发extended-timestamp,是没有问题: FMLE一直没有断开,客户端也没有断开。 服务器端是srs(simple rtmp server),也没有断开: 时间已经超过了24位,使用extended-timestamp: [plain] view plaincopyprint? ,, (gdb) p /x 21039918 ,, $1 = 0x1410b2e (gdb) p /x 21039918 $1 = 0x1410b2e 而nginx呢,是采用第一个包发完全的extended-timestamp,但是后续都是发type=1 的chunk,即时间戳差值。 完毕。
/
本文档为【librtmp使用扩展时间戳时服务器会将连接断开解释】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索