rtmp推流時間戳記相容問題,rtmp推戳相容

來源:互聯網
上載者:User

rtmp推流時間戳記相容問題,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 0, actual is 1. cid=25, ret=2001(Resource temporarily unavailable)read message header failed. ret=2001(Resource temporarily unavailable)recv interlaced message failed. ret=2001(Resource temporarily unavailable)thread process message failed. ret=2001(Resource temporarily unavailable)thread recv cycle failed, ignored and retry, ret=2001recv thread failed. ret=2001(Resource temporarily unavailable)cleanup when unpublishstream service cycle failed. ret=2001(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的代碼如下:

if (extendedTimestamp > 0) {Util.writeUnsignedInt32(out, extendedTimestamp);}

推流時間戳記超過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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.