前面寫的一系列總結都是講webrtc如何下載,編譯,開發的,有些人可能有點雲裏霧裏了,WEBRTC不是用來搞跨瀏覽器開發的嗎,怎麼我講的這些跟瀏覽器扯不上任何關係,其實看看下面這個架構圖,你就明白了,轉載請說明出處(博客園RTC.Blacker)web
我前面講的這些內容都封裝在browser裏面了,如音視頻的採集,編碼,傳輸,回聲消除,丟包重傳.因此若是你想將這些功能集成到你的產品裏面就必須理解這些東西.瀏覽器
若是你只想作基於瀏覽器的視頻通話功能,上面這些你能夠不理解,更不須要去下載編譯WEBRTC代碼,由於實現這些功能所須要的JS接口瀏覽器已經幫你實現了,你只須要簡單調用便可,咱們先看看實現下面這樣一個功能主要涉及哪些步驟?websocket
1,信令交互:開始視頻通話前發起端和接收端須要一些交互,如通知對方開始視頻,接收視頻,視頻參數協商(SDP信息),NAT地址交換,這個過程咱們稱之爲信令交互,WEBRTC沒有定義標準信令格式,既能夠使用SIP也能夠使用XMPP,還能夠使用自定義的信令格式,最簡單的方式就是使用websocket或XMLHttpRequest,自定義格式完成信令交互過程.架構
2,獲取本地視頻流:navigator.getUserMedia(constraints, successCallback, errorCallback);app
navigator.getUserMedia = navigator.getUserMedia ||
navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
// Callback to be called in case of success...
function successCallback(gotStream) {
video.src = window.URL.createObjectURL(stream);
// Start playing video
video.play();
}
// Callback to be called in case of failure...
function errorCallback(error){ console.log("navigator.getUserMedia error: ", error);
}
// Constraints object for low resolution video
var qvgaConstraints = { video: {
mandatory: {
maxWidth: 320,
maxHeight: 240
} }
};
// Constraints object for standard resolution video
var vgaConstraints = { video: {
mandatory: {
maxWidth: 640,
maxHeight: 480
} }
};
// Constraints object for high resolution video
var hdConstraints = { video: {
mandatory: {
minWidth: 1280,
minHeight: 960
} }
};
function getMedia(constraints){
if (!!stream) { video.src = null; stream.stop();
}
navigator.getUserMedia(constraints, successCallback, errorCallback);
}
3,SDP協商:createOffer,createAnswer.socket
1 localPeerConnection.createOffer(gotLocalDescription, onSignalingError); 2 3 // Handler to be called when the 'local' SDP becomes available 4 function gotLocalDescription(description){ 5 // Add the local description to the local PeerConnection
localPeerConnection.setLocalDescription(description);
log("Offer from localPeerConnection: \n" + description.sdp); 6 // ...do the same with the 'pseudoremote' PeerConnection 7 // Note: this is the part that will have to be changed if you want // the communicating peers to become remote 8 // (which calls for the setup of a proper signaling channel) remotePeerConnection.setRemoteDescription(description); 9 // Create the Answer to the received Offer based on the 'local' description 10 remotePeerConnection.createAnswer(gotRemoteDescription, onSignalingError); 11 } 12 // Handler to be called when the remote SDP becomes available 13 function gotRemoteDescription(description){ 14 // Set the remote description as the local description of the 15 // remote PeerConnection.
remotePeerConnection.setLocalDescription(description); 16 log("Answer from remotePeerConnection: \n" + description.sdp); 17 // Conversely, set the remote description as the remote description of the // local PeerConnection
localPeerConnection.setRemoteDescription(description); 18 }
4,ICE協商:ide
1 // Add a handler associated with ICE protocol events 2 localPeerConnection.onicecandidate = gotLocalIceCandidate; 3 4 remotePeerConnection.onicecandidate = gotRemoteIceCandidate; 5 6 // Handler to be called whenever a new local ICE candidate becomes available 7 function gotLocalIceCandidate(event){ if (event.candidate) { 8 // Add candidate to the remote PeerConnection 9 remotePeerConnection.addIceCandidate(new RTCIceCandidate(event.candidate)); 10 log("Local ICE candidate: \n" + event.candidate.candidate); 11 } 12 } 13 14 // Handler to be called whenever a new remote ICE candidate becomes available 15 function gotRemoteIceCandidate(event){ if (event.candidate) { 16 // Add candidate to the local PeerConnection 17 localPeerConnection.addIceCandidate(new RTCIceCandidate(event.candidate)); 18 log("Remote ICE candidate: \n " + event.candidate.candidate); 19 } 20 }
5,使用RTCPeerConnection對象在瀏覽器之間交換媒體流數據.this
1 function call() { 2 log("Starting call"); 3 4 // Note well: getVideoTracks() and getAudioTracks() are not currently supported in Firefox... 5 // ...just use them with Chrome 6 if (navigator.webkitGetUserMedia) { 7 // Log info about video and audio device in use 8 if (localStream.getVideoTracks().length > 0) { 9 log('Using video device: ' + localStream.getVideoTracks()[0].label); 10 } 11 if (localStream.getAudioTracks().length > 0) { 12 log('Using audio device: ' + localStream.getAudioTracks()[0].label); 13 } 14 } 15 16 // Chrome 17 if (navigator.webkitGetUserMedia) { 18 RTCPeerConnection = webkitRTCPeerConnection; 19 // Firefox 20 }else if(navigator.mozGetUserMedia){ 21 RTCPeerConnection = mozRTCPeerConnection; 22 RTCSessionDescription = mozRTCSessionDescription; 23 RTCIceCandidate = mozRTCIceCandidate; 24 } 25 log("RTCPeerConnection object: " + RTCPeerConnection); 26 27 // This is an optional configuration string, associated with NAT traversal setup 28 var servers = null; 29 30 // Create the local PeerConnection object 31 localPeerConnection = new RTCPeerConnection(servers); 32 log("Created local peer connection object localPeerConnection"); 33 // Add a handler associated with ICE protocol events 34 localPeerConnection.onicecandidate = gotLocalIceCandidate; 35 36 // Create the remote PeerConnection object 37 remotePeerConnection = new RTCPeerConnection(servers); 38 log("Created remote peer connection object remotePeerConnection"); 39 // Add a handler associated with ICE protocol events... 40 remotePeerConnection.onicecandidate = gotRemoteIceCandidate; 41 // ...and a second handler to be activated as soon as the remote stream becomes available 42 remotePeerConnection.onaddstream = gotRemoteStream; 43 44 // Add the local stream (as returned by getUserMedia() to the local PeerConnection 45 localPeerConnection.addStream(localStream); 46 log("Added localStream to localPeerConnection"); 47 48 // We're all set! Create an Offer to be 'sent' to the callee as soon as the local SDP is ready 49 localPeerConnection.createOffer(gotLocalDescription, onSignalingError); 50 } 51 52 function onSignalingError(error) { 53 console.log('Failed to create signaling message : ' + error.name); 54 } 55 56 // Handler to be called when the 'local' SDP becomes available 57 function gotLocalDescription(description){ 58 // Add the local description to the local PeerConnection 59 localPeerConnection.setLocalDescription(description); 60 log("Offer from localPeerConnection: \n" + description.sdp); 61 62 // ...do the same with the 'pseudo-remote' PeerConnection 63 // Note well: this is the part that will have to be changed if you want the communicating peers to become 64 // remote (which calls for the setup of a proper signaling channel) 65 remotePeerConnection.setRemoteDescription(description); 66 67 // Create the Answer to the received Offer based on the 'local' description 68 remotePeerConnection.createAnswer(gotRemoteDescription, onSignalingError); 69 } 70 71 // Handler to be called when the 'remote' SDP becomes available 72 function gotRemoteDescription(description){ 73 // Set the 'remote' description as the local description of the remote PeerConnection 74 remotePeerConnection.setLocalDescription(description); 75 log("Answer from remotePeerConnection: \n" + description.sdp); 76 // Conversely, set the 'remote' description as the remote description of the local PeerConnection 77 localPeerConnection.setRemoteDescription(description); 78 } 79 80 // Handler to be called as soon as the remote stream becomes available 81 function gotRemoteStream(event){ 82 // Associate the remote video element with the retrieved stream 83 if (window.URL) { 84 // Chrome 85 remoteVideo.src = window.URL.createObjectURL(event.stream); 86 } else { 87 // Firefox 88 remoteVideo.src = event.stream; 89 } 90 log("Received remote stream"); 91 } 92 93 // Handler to be called whenever a new local ICE candidate becomes available 94 function gotLocalIceCandidate(event){ 95 if (event.candidate) { 96 // Add candidate to the remote PeerConnection 97 remotePeerConnection.addIceCandidate(new RTCIceCandidate(event.candidate)); 98 log("Local ICE candidate: \n" + event.candidate.candidate); 99 } 100 } 101 102 // Handler to be called whenever a new 'remote' ICE candidate becomes available 103 function gotRemoteIceCandidate(event){ 104 if (event.candidate) { 105 // Add candidate to the local PeerConnection 106 localPeerConnection.addIceCandidate(new RTCIceCandidate(event.candidate)); 107 log("Remote ICE candidate: \n " + event.candidate.candidate); 108 }
上面基本上就是瀏覽器上視頻通話涉及的主要對象.編碼
對應到手機端就是webrtc編譯成功後的appRTCDemo.apk.spa