因工做須要,須要將原來的ocx控件切換成webrtc控件來播放,小區端的攝像頭音視頻。由於webrtc官方不是針對於當前的應用場景,因此有對當前場景做一些針對性的修改。以media server做爲中介,溝通device和瀏覽器。將media server當成p2p的p,實現p2p通訊。也算是業界上的一個創新。前端
這篇文章主要是對當前工做的總結。
a.主要難點有stun協議在media server上的實現,將media servers模擬成p2p的p;
b.公司內部網關對>=1464字節的報文追加了6字節vss-monitor尾部數據,填充爲00.
c.相應sdp報文在瀏覽器、和攝像頭之間的交互;
d.webrtc使用sdes模式,協商key,做爲srtp加密的密鑰。
e.chrome的webrtc未開源,只能經過開啓日誌模式,記錄全程日誌,和查看相相似的chrome開源代碼來查看類似邏輯,由於webrtc小版本間代碼修改很小,因此基本能夠參考。且日誌文件可能有1個g,對debug技術有點要求。
nginx
a. 原來由ocx發startvideo、stopvideo、heartbeat三個請求,由於去除了ocx,因此由前端完成; b. 將全部object標籤替換成video標籤。web
一、remote sdp中的fmtp字段,須要與rtp包中的payload type對應,如推給client的h264的payload type是96,則setRemoteDescription時,傳入的sdk,對應h264的fmtp值也應該爲96。
二、海康可視對講發出的音視頻ssrc是相同的,這將致使webrtc將音頻視頻一塊兒解析,將致使rtp index索引重複的問題。要在server端將ssrc設置成不一樣便可。
3. stun協議,須要server push給client相應的喚醒包,至關於心跳;須要發USERNAME、PRIORITY、MESSAGE-INTEGRITY、FINGERPRINT.
a、其中username是固定的,server固定寫死爲:LzAA,client固定爲LzAB.
b、PRIORITY固定值爲1853824767,取自chrome發出的stun request.
c、MESSAGE-INTEGRITY,取固定密鑰」xxxxxx」,先後端同時寫死,相關參考: 算法
因long-term在turn中轉服務器方案纔會使用及出現,須要相應bind-fail,從新交互等流程,也須要realm等參數,而realm是域名之意,通常只在turn服務器中出現。故推測p2p方案適用於short-term方案。
SASLprep算法的意思,是析取適用於username、password命名規則的字符,會將特殊字符去除,由於media server未實現該算法,故建議password爲字母數字組合。
d、FINGERPRINT,循環冗餘校驗字段直接調用stunlib-master裏參考的代碼生成。chrome
四、stun協議,server須要實現與client對應的stun response包;須要包含MESSAGE-INTEGRITY、FINGERPRINT,否則chrome webrtc將看成非法stun response處理,ice連通性檢測失敗,直接拋棄音視頻流。windows
五、以太網包大小超過1464字節時,公司網關將追加6字節padding字段,如圖:這將致使srtp簽名校驗失敗,不能播放視頻流。 能夠將server端的以太網mtu設置成更小值,這樣不會觸發網關加6字節padding。 後端
六、stun協議,client須要指定server與client的ice-ufrag密鑰,用於計算message簽名; 及指定client與server固定硬編碼的用戶名; 及srtp的密鑰也硬編碼成固定密鑰,media server與client使用同一密鑰加解密音視頻流(存在安全風險,可由websocket push給密戶端密鑰,每次會議都不一致,後期可優化)。數組
七、stun協議bind request間隔建議50ms,這樣client能保持在當前會話失效前,又能收到bind request,從而繼續保活當前的流媒體會話。瀏覽器
八、需修改remote sdp爲」a=rtpmap:8 PCMA/8000\n」,這樣將支持g.711a解碼,同時對rtp payload type爲8的看成g.711a處理。安全
九、前端須要調用this.pc.addStream(this.localStream),這樣才能將本地音頻或視頻push給media server。 this.localStream爲本地流,this.pc爲RTCPeerConnection對象,由於沒有使用stun(ice外網ip輔助服務器)、turn(中轉服務器),iceServers可傳[]。
其中DtlsSrtpKeyAgreement須要爲false,強制啓動sdes加密,不採用默認dtls協議srtp密鑰機制,由於dtls須要配置公私鑰環境,協調出流媒體加密的密鑰,這將更復雜,且沒有必要。
十、因webrtc須要Https環境,不能與media server直接交互,故改變了原來直連視頻組件的接口,由nginx路由轉發到視頻組件,再由視頻組件管理視頻預覽的生命週期。
11.前端可由candidate監聽中,獲得當前的ip地址。如圖所示:
在」 typ host」以前的數字便是ip和端口,可截取」 typ host」前面的字符串,再根據空格拆分紅數組,獲得最後面的兩個值,即爲ip和port。 需注意特殊狀況,當前ip可能會是webrtc默認stun服務器的ip,通常是169開頭,此時獲得的ip要能通內網ip規則檢測,如172.26,192.168等規則,纔是咱們的須要的ip和port數據。 目前採用的是寫死當前ip地址的方式,可由後期修改。12.如只需接收遠程的視頻或音頻,去除sdp的video或audio描述時,
如要去除m=audio 9 RTP/SAVPF 8,及後面全部描述信息,直到出現m=video爲止,此時」a=group:BUNDLE 0 1\n」,應該改爲」a=group:BUNDLE 0\n」。
5、調試總結:
一、chrome端開啓日誌輸出到本地目錄:
a、export CHROME_LOG_FILE=~/Documents/chrome_debug.log
b、open /Applications/Google\ Chrome.app --args --enable-logging --v=4 --vmodule=/webrtc/=1
二、將本地的抓包文件解析成h264,lua腳本可百度,目前在windows調試成功。
三、不要開socks的全局模式,由於是在內網調試。
四、和當前mac chrome版本72.0.3626.119,對應的chrome代碼,可由此查看webrtc的相關邏輯,注意開ss的全局模式才能打開: cs.chromium.org/chromium/sr…