生活随笔
收集整理的這篇文章主要介紹了
webrtc一对一通话
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
webrtc一對一通話
目錄
一對一通話原理 RTCPeerConnection 實現WebRTC音視頻通話思路 部署到公網
1. 一對一通話原理
對于WebRTC應用開發人員而言,主要是關注RTCPeerConnection類,主要分為以下四塊 信令設計; 媒體協商; 加入Stream/Track; 網絡協商
1. 信令協議設計
采用json封裝格式
join:加入房間 resp--join:當join房間后發現房間已經存在另一個人時則返回另一個人的uid;如果只有自己則不返回 leave:離開房間,服務器收到leave信令則檢查同一房間是否有其他人,如果有其他人則通知他有人離開 new--peer:服務器通知客戶端有新人加入,收到new-peer則發起連接請求 peer--leave:服務器通知客戶端有人離開 offer:轉發offer sdp answer:轉發answer sdp candidate:轉發candidate sdp join:加入房間
var jsonMsg
= { 'cmd' : 'join' , 'roomId' : roomId
, 'uid' : localUserId
,
} ;
resp--join:當join房間后發現房間已經存在另一個人時則返回另一個人的uid;如果只有自己則不返回
jsonMsg
= { 'cmd' : 'resp‐join' , 'remoteUid' : remoteUid
} ;
leave:離開房間,服務器收到leave信令則檢查同一房間是否有其他人,如果有其他人則通知他有人離開
var jsonMsg
= { 'cmd' : 'leave' , 'roomId' : roomId
, 'uid' : localUserId
,
} ;
new--peer:服務器通知客戶端有新人加入,收到new-peer則發起連接請求
var jsonMsg
= { 'cmd' : 'new‐peer' , 'remoteUid' : uid
} ;
peer--leave:服務器通知客戶端有人離開
var jsonMsg
= { 'cmd' : 'peer‐leave' , 'remoteUid' : uid
} ;
offer:轉發offer sdp
var jsonMsg
= { 'cmd' : 'offer' , 'roomId' : roomId
, 'uid' : localUserId
, 'remoteUid' : remoteUserId
, 'msg' : JSON
. stringify ( sessionDescription
)
} ;
answer:轉發answer sdp
var jsonMsg
= { 'cmd' : 'answer' , 'roomId' : roomId
, 'uid' : localUserId
, 'remoteUid' : remoteUserId
, 'msg' : JSON
. stringify ( sessionDescription
)
} ;
candidate:轉發candidate sdp
var jsonMsg
= { 'cmd' : 'candidate' , 'roomId' : roomId
, 'uid' : localUserId
, 'remoteUid' : remoteUserId
, 'msg' : JSON
. stringify ( candidateJson
)
} ;
2 媒體協商
1. createOffer
基本格式 aPromise = myPeerConnection.createOffer([options])? [options]
var options
= { offerToReceiveAudio
: true , offerToReceiveVideo
: true , iceRestart
: false ,
} ;
iceRestart:只有在處于活躍的時候,iceRestart=false才有作用。 測試:https://webrtc.github.io/samples/src/content/peerconnection/restart-ice/
2. createAnswer
基本格式 aPromise = RTCPeerConnection .createAnswer([ options ])? 目前createAnswer的options是無效的。
3. setLocalDescription
基本格式 aPromise = RTCPeerConnection .setLocalDescription(sessionDescription);
4. setRemoteDescription
基本格式 aPromise = pc.setRemoteDescription(sessionDescription);
3. 加入Stream/Track
1. addTrack
基本格式 rtpSender = rtcPeerConnection .addTrack(track,stream …); track:添加到RTCPeerConnection中的媒體軌(音頻track/視頻track) stream:getUserMedia中拿到的流,指定track所在的stream
4. 網絡協商
1. addIceCandidate
基本格式: aPromise = pc.addIceCandidate(候選人); candidate
屬性說明 candidate 候選者描述信息 sdpMid 與候選者相關的媒體流的識別標簽 sdpMLineIndex 在SDP中 m=的索引值 usernameFragment 包括了遠端的唯一標識
var candidateJson
= { 'label' : event
. candidate
. sdpMLineIndex
, 'id' : event
. candidate
. sdpMid
, 'candidate' : event
. candidate
. candidate
} ;
注意Android和Web端的不同。
2. RTCPeerConnection
1. 構造函數:
語法:
pc
= new RTCPeerConnection(
[ configuration
] )
;
2. configuration可選
bundlePolicy 一般用max-bundle
banlanced:音頻與視頻軌使用各自的傳輸通道
max-compat:每個軌使用自己的傳輸通道
max-bundle:都綁定到同一個傳輸通道
iceTransportPolicy 一般用all
指定ICE的傳輸策略
relay:只使用中繼候選者
all:可以使用任何類型的候選者
iceServers 其由RTCIceServer組成,每個RTCIceServer都是一個ICE代理的服務器
屬性含義 credential 憑據,只有TURN服務使用 credentialType 憑據類型,可以password或oauth urls 用于連接服中的ur數組 username 用戶名,只有TURN服務使用
rtcpMuxPolicy 一般用require rtcp的復用策略,該選項在收集ICE候選者時使用
選項說明 negotiate 收集RTCP與RTP復用的ICE候選者,如果RTCP能復用就與RTP復用,如果不能復用,就將他們單獨使用 require 只能收集RTCP與RTP復用的ICE候選者,如果RTCP不能復用,則失敗
3. 重要事件
onicecandidate:收到候選者時觸發的事件 ontrack:獲取遠端流 onconnectionstatechange PeerConnection的連接狀態,參考:https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/connectionState
pc
. onconnectionstatechange
= function ( event
) { switch ( pc
. connectionState
) { case "connected" : break ; case "disconnected" : case "failed" : break ; case "closed" : break ; }
}
oniceconnectionstatechange ice連接事件 具體參考:https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/iceConnectionState
3. 實現WebRTC音視頻通話
開發步驟 客戶端顯示界面 打開攝像頭并顯示到頁面 websocket連接 join、new-peer、resp-join信令實現 leave、peer-leave信令實現 offer、answer、candidate信令實現 綜合調試和完善
1. 客戶端顯示界面
步驟:創建html頁面 主要是input、button、video控件的布局。
2. 打開攝像頭并顯示到頁面
3. websocket連接
4. join、new-peer、resp-join信令實現
思路: 點擊加入按鈕; 響應加入按鈕事件; 將join發送給服務器; 服務器根據當前房間的人數做處理,如果房間已經有人則通知房間里面的人有新人加入(new-peer),并通知自己房間里面是什么人(respjoin)
5. leave、peer-leave信令實現
思路: 點擊離開按鈕; 響應離開按鈕事件; 將leave發送給服務器; 服務器處理leave,將發送者刪除并通知房間(peer-leave)的其他人; 房間的其他人在客戶端響應peer-leave事件
6. offer、answer、candidate信令實現
思路: 收到new-peer (handleRemoteNewPeer處理),作為發起者創建RTCPeerConnection,綁定事件響應函數,加入本地流; 創建offer sdp,設置本地sdp,并將offer sdp發送到服務器; 服務器收到offer sdp 轉發給指定的remoteClient; 接收者收到offer,也創建RTCPeerConnection,綁定事件響應函數,加入本地流; 接收者設置遠程sdp,并創建answer sdp,然后設置本地sdp并將answer sdp發送到服務器; 服務器收到answer sdp 轉發給指定的remoteClient; 發起者收到answer sdp,則設置遠程sdp; 發起者和接收者都收到ontrack回調事件,獲取到對方碼流的對象句柄; 發起者和接收者都開始請求打洞,通過onIceCandidate獲取到打洞信息(candidate)并發送給對方 如果P2P能成功則進行P2P通話,如果P2P不成功則進行中繼轉發通話。
7. 綜合調試和完善
思路: 點擊離開時,要將RTCPeerConnection關閉(close); 點擊離開時,要將本地攝像頭和麥克風關閉; 檢測到客戶端退出時,服務器再次檢測該客戶端是否已經退出房間。 RTCPeerConnection時傳入ICE server的參數,以便當在公網環境下可以進行正常通話。 啟動coturn,安裝:ubantu安裝coturn穿透服務器
# nohup是重定向命令,輸出都將附加到當前目錄的 nohup
. out 文件中; 命令后加
& , 后臺執行起來后按
ctr
+ c
, 不會停止
sudo nohup turnserver ‐L
0.0 .0 .0 ‐a ‐u test
: test ‐v ‐f ‐r nort
. gov
&
# 前臺啟動
sudo turnserver ‐L
0.0 .0 .0 ‐a ‐u test
: test ‐v ‐f ‐r nort
. gov
#然后查看相應的端口號
3478 是否存在進程
sudo lsof ‐i
: 3478
設置configuration,先設置為relay中繼模式,只有relay中繼模式可用的時候,才能部署到公網去(部署到公網后也先測試relay)。
var defaultConfiguration
= { bundlePolicy
: "max-bundle" , rtcpMuxPolicy
: "require" , iceTransportPolicy
: "relay" , iceServers
: [ { "urls" : [ "turn:8.141.75.248:3478?transport=udp" , "turn:8.141.75.248:3478?transport=tcp" ] , "username" : "test" , "credential" : "test" } , { "urls" : [ "stun:8.141.75.248:3478" ] } ] } ; pc
= new RTCPeerConnection ( defaultConfiguration
) ;
relay中繼網絡狀況,命令:sudo sar -n DEV 1 局域網P2P
總結
以上是生活随笔 為你收集整理的webrtc一对一通话 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。