1. 程式人生 > >120行程式碼實現 瀏覽器WebRTC視訊聊天

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 TURN

ICE (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標準定義,所以是否使用安全的協議就取決於你自己了。

6 WebRTC 參考資料