年後着手Node版本EasyDarwin的開發工做,截止到今天2018年03月27日上線了第一個版本,今天小米發佈了MIX2S, 致敬! 致敬!html
目前這個初版暫時僅支持RTSP Over TCP, 不過RTSP Over UDP也會很快實現.整體來講, RTSP協議比較簡單.開發過程當中對RTSP協議的理解主要參考了 rtsp協議詳解 這篇文章.sdp的解析一開始本身寫的, 反覆參考資料瞭解sdp各個字段的含義.後來偶然在npm上找到 sdp-transform 這個庫, 處理sdp信息很是方便, 果斷star了.git
記錄sdp兩個細節的地方:github
m
媒體描述下面有個屬性名爲 control
的屬性, 它的值和後續 SETUP
請求的 uri
的尾巴是對應的, 椐此能夠明確 SETUP
是音頻仍是視頻.web
SETUP
攜帶的請求頭 Transport
中有個參數叫 interleaved
, 這個東西常見的內容是一個偶數-一個奇數
, 這兩個數值表明RTP傳輸的通道標識
.一個RTP包前面有4個節字的頭: 1個字節的固定$(0x24)符;1個字節通道標識;2個字節的RTP包長度.對應的正是這個頭裏面的第2個字節.通常偶數表示數據通道, 奇數表示控制通道.npm
理解以上兩點, 有助於在RTP傳輸過程當中, 針對特定的視頻格式, 緩存GOP,實現秒開效果.緩存
從TCP流式數據中解析RTP包, 對NodeJS的處理效率是個考驗.在初始階段, 簡單的利用 socket data 事件回調, 只要接收到數據, 就走一次協議解析. 實測發現一路播放的狀況下都很卡頓. 最後是參考了 Node-Media-Server 中的 BufferPool 實現, 利用 Generator 和 yield. 只有當接收數據長度達到要求的時候, 纔去作協議解析. 這樣效率獲得巨大提高, 播放不卡頓了. 中間還嘗試過利用 socket pipe 將RTP包流轉給播放端, 這樣作確實效率很高, 也能夠解決播放卡頓. 可是這種方式下, 解不到單個RTP包, 就沒法作GOP緩存, 因此棄用了.服務器
結合sdp中的媒體描述和 SETUP Transport interleaved 的值, 能夠識別出一個RTP包攜帶的內容是媒體數據仍是控制數據, 若是是媒體數據, 是音頻仍是視頻, 若是是視頻, 那麼視頻數據的編碼格式是什麼. 基於這些, 當收到攜帶h264數據的RTP包時, 作關鍵幀識別, 緩存GOP.網絡
在RTP包中識別h264關鍵幀, 須要瞭解RTP包格式, h264 nalu type, fu-a 分包這些內容.這裏我主要參考了CSDN上這篇博客 RTP協議全解析(H264碼流和PS流)socket
用Node實現EasyDarwin那樣的RTSP流媒體轉發, 最後的效果是使人滿意的.目前的代碼量很小.Node在處理字節流的過程當中, 反覆使用了自帶的Buffer庫函數. concat, slice, readXXXBE(以大端方式讀網絡字節序). 在這一版中, 我給它搭配了一個 HTTP Server, 提供了可視化的統計信息展現. 總之, Node.js 的引入將大大提升EasyDarwin開源流媒體服務的開發效率, 提高EasyDarwin的易用性.svg
EasyDarwin開源流媒體服務器:www.EasyDarwin.org
EasyDSS商用流媒體解決方案:www.EasyDSS.com
EasyNVR無插件直播方案:www.EasyNVR.com
Copyright © EasyDarwin Team 2012-2019