120行程式碼實現 瀏覽器WebRTC視訊聊天
本例子是參考webrtc-tutorial-simple-video-chat做的。
這個教程應該主要是去宣傳ScaleDrone的sdk, 他們的服務是收費的,但是免費的也可以用,就是有些次數限制。
1 準備
- 使用最新版谷歌瀏覽器(62版)
- 視訊聊天中 一個是windows, 一個是mac
- stun伺服器使用谷歌的,trun使用ScaleDrone的sdk,這樣我就不用管服務端了。
2 先上效果圖
3 再上線上例子點選此處
4 原始碼分析
// 產生隨機數
if (!location.hash) {
location.hash = Math.floor(Math.random() * 0xFFFFFF ).toString(16);
}
// 獲取房間號
var roomHash = location.hash.substring(1);
// 放置你自己的頻道id, 這是我註冊了ScaleDrone 官網後,建立的channel
// 你也可以自己建立
var drone = new ScaleDrone('87fYv4ncOoa0Cjne');
// 房間名必須以 'observable-'開頭
var roomName = 'observable-' + roomHash;
var configuration = {
iceServers: [{
urls: 'stun:stun.l.google.com:19302' // 使用谷歌的stun服務
}]
};
var room;
var pc;
function onSuccess() {}
function onError(error) {
console.error(error);
}
drone.on('open', function(error){
if (error) { return console.error(error);}
room = drone.subscribe(roomName);
room.on('open', function(error){
if (error) {onError(error);}
});
// 已經連結到房間後,就會收到一個 members 陣列,代表房間裡的成員
// 這時候信令服務已經就緒
room.on('members', function(members){
console.log('MEMBERS', members);
// 如果你是第二個連結到房間的人,就會建立offer
var isOfferer = members.length === 2;
startWebRTC(isOfferer);
});
});
// 通過Scaledrone傳送信令訊息
function sendMessage(message) {
drone.publish({
room: roomName,
message
});
}
function startWebRTC(isOfferer) {
pc = new RTCPeerConnection(configuration);
// 當本地ICE Agent需要通過訊號伺服器傳送資訊到其他端時
// 會觸發icecandidate事件回撥
pc.onicecandidate = function(event){
if (event.candidate) {
sendMessage({ 'candidate': event.candidate });
}
};
// 如果使用者是第二個進入的人,就在negotiationneeded 事件後建立sdp
if (isOfferer) {
// onnegotiationneeded 在要求sesssion協商時發生
pc.onnegotiationneeded = function() {
// 建立本地sdp描述 SDP (Session Description Protocol) session描述協議
pc.createOffer().then(localDescCreated).catch(onError);
};
}
// 當遠端資料流到達時,將資料流裝載到video中
pc.onaddstream = function(event){
remoteVideo.srcObject = event.stream;
};
// 獲取本地媒體流
navigator.mediaDevices.getUserMedia({
audio: true,
video: true,
}).then( function(stream) {
// 將本地捕獲的視訊流裝載到本地video中
localVideo.srcObject = stream;
// 將本地流加入RTCPeerConnection 例項中 傳送到其他端
pc.addStream(stream);
}, onError);
// 從Scaledrone監聽信令資料
room.on('data', function(message, client){
// 訊息是我自己傳送的,則不處理
if (client.id === drone.clientId) {
return;
}
if (message.sdp) {
// 設定遠端sdp, 在offer 或者 answer後
pc.setRemoteDescription(new RTCSessionDescription(message.sdp), function(){
// 當收到offer 後就接聽
if (pc.remoteDescription.type === 'offer') {
pc.createAnswer().then(localDescCreated).catch(onError);
}
}, onError);
}
else if (message.candidate) {
// 增加新的 ICE canidatet 到本地的連結中
pc.addIceCandidate(
new RTCIceCandidate(message.candidate), onSuccess, onError
);
}
});
}
function localDescCreated(desc) {
pc.setLocalDescription(desc, function(){
sendMessage({ 'sdp': pc.localDescription });
},onError);
}
5 WebRTC簡介
5.1 介紹
WebRTC 是一個開源專案,用於Web瀏覽器之間進行實時音訊視訊通訊,資料傳遞。
WebRTC有幾個JavaScript APIS。 點選連結去檢視demo。
- [getUserMedia(): 捕獲音訊視訊]()
- [MediaRecorder: 記錄音訊視訊]()
- [RTCPeerConnection: 在使用者之間傳遞音訊流和視訊流]()
- [RTCDataChannel: 在使用者之間傳遞檔案流]()
5.2 在哪裡使用WebRTC?
- Chrome
- FireFox
- Opera
- Android
- iOS
5.3 什麼是信令
WebRTC使用RTCPeerConnection
在瀏覽器之間傳遞流資料, 但是也需要一種機制去協調收發控制資訊,這就是信令。信令的方法和協議並不是在WebRTC中明文規定的。
在codelad中用的是Node,也有許多其他的方法。
5.4 什麼是STUN和TURN和ICE?
STUN(Session Traversal Utilities for NAT,NAT會話穿越應用程式)是一種網路協議,它允許位於NAT(或多重NAT)後的客戶端找出自己的公網地址,查出自己位於哪種型別的NAT之後以及NAT為某一個本地埠所繫結的Internet端埠。這些資訊被用來在兩個同時處於NAT路由器之後的主機之間建立UDP通訊。該協議由RFC 5389定義。 wikipedia STUN
TURN(全名Traversal Using Relay NAT, NAT中繼穿透),是一種資料傳輸協議(data-transfer protocol)。允許在TCP或UDP的連線上跨越NAT或防火牆。
TURN是一個client-server協議。TURN的NAT穿透方法與STUN類似,都是通過取得應用層中的公有地址達到NAT穿透。但實現TURN client的終端必須在通訊開始前與TURN server進行互動,並要求TURN server產生"relay port",也就是relayed-transport-address。這時TURN server會建立peer,即遠端端點(remote endpoints),開始進行中繼(relay)的動作,TURN client利用relay port將資料傳送至peer,再由peer轉傳到另一方的TURN client。wikipedia TURNICE (Interactive Connectivity Establishment,互動式連線建立 ),一種綜合性的NAT穿越的技術。
互動式連線建立是由IETF的MMUSIC工作組開發出來的一種framework,可整合各種NAT穿透技術,如STUN、TURN(Traversal Using Relay NAT,中繼NAT實現的穿透)、RSIP(Realm Specific IP,特定域IP)等。該framework可以讓SIP的客戶端利用各種NAT穿透方式打穿遠端的防火牆。wikipedia ICE
WebRTC被設計用於點對點之間工作,因此使用者可以通過最直接的途徑連線。然而,WebRTC的構建是為了應付現實中的網路: 客戶端應用程式需要穿越NAT閘道器和防火牆,並且對等網路需要在直接連線失敗的情況下進行回撥。
作為這個過程的一部分,WebRTC
api使用STUN伺服器來獲取計算機的IP地址,並將伺服器作為中繼伺服器執行,以防止對等通訊失敗。(現實世界中的WebRTC更詳細地解釋了這一點。)
5.5 WebRTC是否安全?
WebRTC元件是強制要求加密的,並且它的JavaScript APIS只能在安全的域下使用(HTTPS 或者 localhost)。信令機制並沒有被WebRTC標準定義,所以是否使用安全的協議就取決於你自己了。