發布日期:2013 年 11 月 4 日
WebRTC 可啟用對等互連通訊。這項技術需要伺服器,用戶端才能透過稱為「信號」的程序交換中繼資料及協調通訊。伺服器也能協助用戶端處理網路位址轉譯器 (NAT) 和防火牆。
在本課程中,您將瞭解如何建構信號服務,並使用 STUN 和 TURN 伺服器處理實際連線的特殊情況。您也會瞭解 WebRTC 應用程式如何處理多方通話,以及與 VoIP 和 PSTN (也稱為電話) 等服務互動。
什麼是信號?
信號交換是協調通訊的程序。如要讓 WebRTC 應用程式設定通話,用戶端必須交換下列資訊:
- 用於開啟或關閉通訊的工作階段控制訊息
- 錯誤訊息
- 媒體中繼資料,例如轉碼器、轉碼器設定、頻寬和媒體類型
- 用於建立安全連線的重要資料
- 網路資料,例如外界看到的主機 IP 位址和通訊埠
這個信號傳遞程序需要用戶端來回傳遞訊息。WebRTC API 並未實作該機制。您必須自行建構。
為什麼 WebRTC 未定義信號傳遞?
為避免重複並盡可能與既有技術相容,WebRTC 標準並未指定信號方法和通訊協定。JavaScript 工作階段建立通訊協定 (JSEP) 概述了這種方法:
JSEP 的架構也避免瀏覽器必須儲存狀態,也就是做為信號狀態機器。舉例來說,如果每次重新載入網頁時,信號資料都會遺失,就會造成問題。而是將信號狀態儲存在伺服器上。
JSEP 要求對等互連之間交換「offer」和「answer」,也就是媒體中繼資料。提議和應答會以工作階段描述通訊協定 (SDP) 格式傳送,如下所示:
v=0
o=- 7614219274584779017 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE audio video
a=msid-semantic: WMS
m=audio 1 RTP/SAVPF 111 103 104 0 8 107 106 105 13 126
c=IN IP4 0.0.0.0
a=rtcp:1 IN IP4 0.0.0.0
a=ice-ufrag:W2TGCZw2NZHuwlnf
a=ice-pwd:xdQEccP40E+P0L5qTyzDgfmW
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=mid:audio
a=rtcp-mux
a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:9c1AHz27dZ9xPI91YNfSlI67/EMkjHHIHORiClQe
a=rtpmap:111 opus/48000/2
...
想知道這些 SDP 術語的實際意義嗎?請參閱網際網路工程任務組 (IETF) 範例。
請注意,WebRTC 的設計可讓您在將提議或回覆設為本機或遠端說明之前,先編輯 SDP 文字中的值來調整提議或回覆。舉例來說,appr.tc 中的 preferAudioCodec() 函式可用於設定預設轉碼器和位元率。使用 JavaScript 操控 SDP 有點麻煩,目前有人討論 WebRTC 的未來版本是否應改用 JSON,但堅持使用 SDP 也有一些優點。
RTCPeerConnection API 和信號:提議、應答和候選
RTCPeerConnection 是 WebRTC 應用程式用來建立對等互連連線,以及傳輸音訊和影片的 API。
為初始化這項程序,RTCPeerConnection 有兩項工作:
- 確認本機媒體條件,例如解析度和轉碼器功能。這是用於提議和回答機制的中繼資料。
- 取得應用程式主機的潛在網路位址,稱為「候選位址」。
確認這項店面資料後,必須透過信號機制與遠端對等互連交換資料。
假設愛麗絲嘗試呼叫夏娃。以下是完整應答機制的詳細說明:
- Alice 建立
RTCPeerConnection物件。 - Alice 使用
RTCPeerConnectioncreateOffer()方法建立供應項目 (SDP 工作階段說明)。 - 愛麗絲致電
setLocalDescription(),提出報價。 - Alice 將提議字串化,並使用信號機制將提議傳送給 Eve。
- Eve 使用 Alice 的提議呼叫
setRemoteDescription(),讓她的RTCPeerConnection知道 Alice 的設定。 - Eve 呼叫
createAnswer(),並將本機工作階段說明 (Eve 的應答) 傳遞給成功回呼。 - Eve 呼叫
setLocalDescription(),將答案設為本機說明。 - Eve 接著使用信號機制,將字串化的答案傳送給 Alice。
- Alice 使用
setRemoteDescription()將 Eve 的答案設為遠端工作階段說明。
Alice 和 Eve 也需要交換網路資訊。「尋找候選項目」一詞是指使用 ICE 架構尋找網路介面和通訊埠的程序。
- 小愛使用
onicecandidate處理常式建立RTCPeerConnection物件。 - 當有可用的候選網路時,系統會呼叫處理常式。
- 在處理常式中,Alice 透過信號管道將字串化的候選資料傳送給 Eve。
- Eve 收到 Alice 的候選訊息後,會呼叫
addIceCandidate(),將候選訊息新增至遠端對等互連說明。
JSEP 支援 ICE 候選項目涓流,可讓來電者在初始提議後,逐步向被呼叫者提供候選項目,並讓被呼叫者開始處理通話並設定連線,而不必等待所有候選項目到達。
編寫 WebRTC 程式碼來傳送信號
下列程式碼片段是 W3C 程式碼範例,總結了完整的信號傳遞程序。程式碼假設存在某種信號機制 SignalingChannel。我們稍後會詳細說明信號。
// handles JSON.stringify/parse
const signaling = new SignalingChannel();
const constraints = {audio: true, video: true};
const configuration = {iceServers: [{urls: 'stun:stun.example.org'}]};
const pc = new RTCPeerConnection(configuration);
// Send any ice candidates to the other peer.
pc.onicecandidate = ({candidate}) => signaling.send({candidate});
// Let the "negotiationneeded" event trigger offer generation.
pc.onnegotiationneeded = async () => {
try {
await pc.setLocalDescription(await pc.createOffer());
// send the offer to the other peer
signaling.send({desc: pc.localDescription});
} catch (err) {
console.error(err);
}
};
// After remote track media arrives, show it in remote video element.
pc.ontrack = (event) => {
// Don't set srcObject again if it is already set.
if (remoteView.srcObject) return;
remoteView.srcObject = event.streams[0];
};
// Call start() to initiate.
async function start() {
try {
// Get local stream, show it in self-view, and add it to be sent.
const stream =
await navigator.mediaDevices.getUserMedia(constraints);
stream.getTracks().forEach((track) =>
pc.addTrack(track, stream));
selfView.srcObject = stream;
} catch (err) {
console.error(err);
}
}
signaling.onmessage = async ({desc, candidate}) => {
try {
if (desc) {
// If you get an offer, you need to reply with an answer.
if (desc.type === 'offer') {
await pc.setRemoteDescription(desc);
const stream =
await navigator.mediaDevices.getUserMedia(constraints);
stream.getTracks().forEach((track) =>
pc.addTrack(track, stream));
await pc.setLocalDescription(await pc.createAnswer());
signaling.send({desc: pc.localDescription});
} else if (desc.type === 'answer') {
await pc.setRemoteDescription(desc);
} else {
console.log('Unsupported SDP type.');
}
} else if (candidate) {
await pc.addIceCandidate(candidate);
}
} catch (err) {
console.error(err);
}
};
如要查看實際運作中的提議/應答和候選交換程序,請前往 simpl.info RTCPeerConnection,並查看單頁視訊通訊範例的主控台記錄。您可以從 Google Chrome 的 about://webrtc-internals 頁面或 Opera 的 opera://webrtc-internals 頁面,下載 WebRTC 信號和統計資料的完整轉儲。
探索對等點
這只是「如何找到人聊天?」的另一種說法。
撥打電話時,您會使用電話號碼和目錄。如要進行線上視訊通訊和傳送訊息,您需要身分和狀態管理系統,以及讓使用者發起工作階段的方法。WebRTC 應用程式需要一種方式,讓用戶端互相發出信號,表示要發起或加入通話。
WebRTC 未定義對等互連探索機制,因此我們不會在這裡討論相關選項。這個過程可能很簡單,例如透過電子郵件或訊息傳送網址。如果是 Talky、tawk.to 和 Browser Meeting 等視訊通訊應用程式,只要分享自訂連結,就能邀請他人加入通話。開發人員 Chris Ball 建構了有趣的 serverless-webrtc 實驗,讓 WebRTC 通話參與者能透過任何喜歡的訊息服務 (例如即時訊息、電子郵件或信鴿) 交換中繼資料。
如何建構信號服務?
再次強調,WebRTC 標準並未定義信號通訊協定和機制。無論選擇哪種方式,都需要中介伺服器,才能在用戶端之間交換信號訊息和應用程式資料。可惜的是,網頁應用程式無法在網際網路上大喊「幫我連線到朋友!」,
幸好,信號訊息很小,而且大多在通話開始時交換。在視訊通訊工作階段中使用 appr.tc 進行測試時,信號服務總共處理了約 30 到 45 則訊息,所有訊息的總大小約為 10 KB。
WebRTC 信號服務除了對頻寬的要求相對較低外,也不會消耗太多處理或記憶體資源,因為這類服務只需要轉送訊息,並保留少量的工作階段狀態資料,例如哪些用戶端已連線。
將訊息從伺服器推送至用戶端
信號訊息服務必須是雙向的:用戶端到伺服器和伺服器到用戶端。雙向通訊與 HTTP 用戶端/伺服器要求/回應模型不相容,但多年來,開發人員已開發出各種駭客技術 (例如長輪詢),將資料從網頁伺服器上執行的服務推送至瀏覽器中執行的網頁應用程式。
EventSource API 可啟用伺服器傳送事件,也就是透過 HTTP 從網路伺服器傳送至瀏覽器用戶端的資料。EventSource 專為單向訊息傳遞而設計,但可與 XHR 搭配使用,建構交換信號訊息的服務。信號服務會透過 XHR 要求傳遞來電者的訊息,並透過 EventSource 將訊息推送給被呼叫者。
WebSocket 專為全雙工用戶端與伺服器通訊而設計,也就是說,訊息可以同時雙向傳輸。使用純 WebSocket 或伺服器傳送事件 (EventSource) 建構信號服務的優點之一,是這些 API 的後端可以在各種網頁框架上實作,這些框架常見於大多數網頁代管套件,適用於 PHP、Python 和 Ruby 等語言。
所有支援 WebRTC 的瀏覽器也支援 WebSocket。所有連線都應使用 TLS,確保郵件不會在未加密的情況下遭到攔截,並減少 Proxy 遍歷問題。如要進一步瞭解 WebSocket 和 Proxy 遍歷,請參閱 Ilya Grigorik 的《High Performance Browser Networking》中的 WebRTC 章節。
您可以透過 Ajax 讓 WebRTC 用戶端重複輪詢訊息伺服器,藉此處理信號,但這會導致大量多餘的網路要求,對行動裝置來說尤其不便。即使工作階段已建立,對等互連仍需輪詢信號訊息,以防其他對等互連變更或終止工作階段。WebRTC Book 應用程式範例採用這個選項,並針對輪詢頻率進行一些最佳化。
資源調度信號
雖然信號服務在每個用戶端上耗用的頻寬和 CPU 相對較少,但熱門應用程式的信號伺服器可能需要處理來自不同位置的大量訊息,且並行程度很高。流量大的 WebRTC 應用程式需要能處理大量負載的信號伺服器。這裡不詳細說明,但有許多選項可提供大量、高效能的訊息,包括:
可延伸訊息和出席通訊協定 (XMPP) 是專為即時通訊開發的通訊協定,可用於信號傳遞。伺服器實作項目包括 ejabberd 和 Openfire。JavaScript 用戶端 (例如 Strophe.js) 會使用 BOSH 模擬雙向串流,但與 WebSocket 相比,BOSH 的效率可能較低,且擴充性較差。
開放原始碼程式庫,例如 ZeroMQ (TokBox 用於其 Rumour 服務) 和 OpenMQ (NullMQ 使用 WebSocket 上的 STOMP 通訊協定,將 ZeroMQ 概念套用至網路平台)。
商業 WebRTC 平台,例如 vLine
在 Node 上使用 Socket.io 建構信號服務
以下是網頁應用程式的程式碼,該應用程式使用在 Node 上以 Socket.io 建構的信號服務。Socket.io 的設計可讓您更輕鬆地建構交換訊息的服務,而且 Socket.io 內建聊天室概念,特別適合 WebRTC 訊號。這個範例適用於使用者人數相對較少的情況,而非正式環境。
Socket.io 使用 WebSocket 搭配備用方案:AJAX 長輪詢、AJAX 多部分串流、Forever Iframe 和 JSONP 輪詢。它已移植到各種後端,但最知名的可能是本範例中使用的 Node 版本。
這個範例中沒有 WebRTC。這個範例旨在示範如何將信號傳遞功能建構至網頁應用程式。您可以查看控制台記錄,瞭解用戶端加入聊天室並交換訊息時的情況。這份 WebRTC 程式碼實驗室提供逐步操作說明,說明如何將這項功能整合至完整的 WebRTC 視訊通訊應用程式。
以下是 index.html 用戶端:
<!DOCTYPE html>
<html>
<head>
<title>WebRTC client</title>
</head>
<body>
<script src='/socket.io/socket.io.js'></script>
<script src='js/main.js'></script>
</body>
</html>
以下是用戶端中參照的 JavaScript 檔案 main.js:
const isInitiator;
room = prompt('Enter room name:');
const socket = io.connect();
if (room !== '') {
console.log('Joining room ' + room);
socket.emit('create or join', room);
}
socket.on('full', (room) => {
console.log('Room ' + room + ' is full');
});
socket.on('empty', (room) => {
isInitiator = true;
console.log('Room ' + room + ' is empty');
});
socket.on('join', (room) => {
console.log('Making request to join room ' + room);
console.log('You are the initiator!');
});
socket.on('log', (array) => {
console.log.apply(console, array);
});
以下是完整的伺服器應用程式:
const static = require('node-static');
const http = require('http');
const file = new(static.Server)();
const app = http.createServer(function (req, res) {
file.serve(req, res);
}).listen(2013);
const io = require('socket.io').listen(app);
io.sockets.on('connection', (socket) => {
// Convenience function to log server messages to the client
function log(){
const array = ['>>> Message from server: '];
for (const i = 0; i < arguments.length; i++) {
array.push(arguments[i]);
}
socket.emit('log', array);
}
socket.on('message', (message) => {
log('Got message:', message);
// For a real app, would be room only (not broadcast)
socket.broadcast.emit('message', message);
});
socket.on('create or join', (room) => {
const numClients = io.sockets.clients(room).length;
log('Room ' + room + ' has ' + numClients + ' client(s)');
log('Request to create or join room ' + room);
if (numClients === 0){
socket.join(room);
socket.emit('created', room);
} else if (numClients === 1) {
io.sockets.in(room).emit('join', room);
socket.join(room);
socket.emit('joined', room);
} else { // max two clients
socket.emit('full', room);
}
socket.emit('emit(): client ' + socket.id +
' joined room ' + room);
socket.broadcast.emit('broadcast(): client ' + socket.id +
' joined room ' + room);
});
});
如要在 localhost 上執行這個應用程式,您需要 Node.js、Socket.IO 和 node-static。如要安裝 Socket.IO 和 node-static,請在應用程式目錄的終端機中執行 npm:
npm install socket.io
npm install node-static
如要啟動伺服器,請在應用程式目錄的終端機中執行下列指令:
node server.js
在瀏覽器中開啟 localhost:2013。在任何瀏覽器中開啟新分頁或視窗,然後再次開啟 localhost:2013。如要查看發生什麼事,請查看控制台。在 Chrome 和 Opera 中,您可以透過 Google Chrome 開發人員工具存取控制台,方法是按下 Ctrl+Shift+J (在 Mac 上則為 Command+Option+J)。
無論您選擇哪種信號傳遞方法,後端和用戶端應用程式都必須提供類似這個範例的服務。
信號注意事項
RTCPeerConnection在呼叫setLocalDescription()之前,不會開始收集候選項目。JSEP IETF 草案對此有強制規定。- 善用 Trickle ICE。候選廣告一到,就立即呼叫
addIceCandidate()。
現成的信號伺服器
如果不想自行建構,可以使用多個 WebRTC 信號伺服器,這些伺服器會像上一個範例一樣使用 Socket.IO,並與 WebRTC 用戶端 JavaScript 程式庫整合:
- webRTC.io 是 WebRTC 最早的抽象程式庫之一。
- Signalmaster 是專為搭配 SimpleWebRTC JavaScript 用戶端程式庫使用而建立的信號伺服器。
如果完全不想編寫任何程式碼,可以選擇 vLine、OpenTok 和 Asterisk 等公司提供的完整商用 WebRTC 平台。
附帶一提,Ericsson 在 WebRTC 早期,曾在 Apache 上使用 PHP 建構信號伺服器。雖然這項功能已過時,但如果您考慮採用類似做法,不妨參考這段程式碼。
訊號安全
所有 WebRTC 元件都必須加密。
不過,WebRTC 標準並未定義信號機制,因此您必須自行確保信號安全。如果攻擊者成功劫持信號,就能停止工作階段、重新導向連線,以及記錄、修改或插入內容。
保護信號傳輸最重要的因素是使用安全通訊協定:HTTPS 和 WSS,例如 TLS。這可確保郵件不會在未加密的情況下遭到攔截。此外,請務必小心,不要以其他呼叫端可透過相同信號伺服器存取的方式廣播信號訊息。
應對 NAT 和防火牆
WebRTC 應用程式會使用中介伺服器傳送中繼資料信號,但工作階段建立後,RTCPeerConnection 會嘗試直接或透過點對點方式連結用戶端,傳輸實際的媒體和資料串流。
在更簡單的世界中,每個 WebRTC 端點都會有專屬位址,可與其他對等互連交換,以便直接通訊。
實際上,大多數裝置都位於一或多層 NAT 後方,有些裝置則安裝了會封鎖特定通訊埠和通訊協定的防毒軟體,而且許多裝置都位於 Proxy 和企業防火牆後方。防火牆和 NAT 實際上可能由同一部裝置 (例如家用 Wi-Fi 路由器) 實作。
WebRTC 應用程式可以使用 ICE 架構,克服實際網路的複雜性。如要啟用這項功能,應用程式必須將 ICE 伺服器網址傳遞至 RTCPeerConnection。
ICE 會嘗試找出連線至對等互連的最佳路徑。它會同時嘗試所有可能性,並選擇最有效率的可行選項。ICE 會先嘗試使用從裝置作業系統和網路卡取得的主機位址建立連線。如果失敗 (NAT 後方的裝置會失敗),ICE 會使用 STUN 伺服器取得外部位址,如果失敗,流量會透過 TURN 中繼伺服器轉送。
換句話說,STUN 伺服器用於取得外部網路位址,而 TURN 伺服器則用於在直接 (點對點) 連線失敗時轉送流量。
每個 TURN 伺服器都支援 STUN。TURN 伺服器是內建額外轉送功能的 STUN 伺服器。ICE 也會處理 NAT 設定的複雜問題。實際上,NAT 打洞可能不只需要公開 IP:通訊埠位址。
STUN 和 TURN 伺服器的網址是由 WebRTC 應用程式在 iceServers 設定物件中指定 (選用),該物件是 RTCPeerConnection 建構函式的第一個引數。以 appr.tc 為例,該值如下所示:
{
'iceServers': [
{
'urls': 'stun:stun.l.google.com:19302'
},
{
'urls': 'turn:192.158.29.39:3478?transport=udp',
'credential': 'JZEOEt2V3Qb0y27GRntt2u2PAYA=',
'username': '28224511:1379330808'
},
{
'urls': 'turn:192.158.29.39:3478?transport=tcp',
'credential': 'JZEOEt2V3Qb0y27GRntt2u2PAYA=',
'username': '28224511:1379330808'
}
]
}
RTCPeerConnection 取得這項資訊後,就會自動執行 ICE。RTCPeerConnection 使用 ICE 架構找出對等互連之間的最佳路徑,並視需要與 STUN 和 TURN 伺服器搭配使用。
STUN
NAT 會為裝置提供 IP 位址,供裝置在私人區域網路內使用,但這個位址無法在外部使用。如果沒有公開位址,WebRTC 對等互連就無法通訊。為解決這個問題,WebRTC 會使用 STUN。
STUN 伺服器位於公開網際網路上,只有一項任務:檢查傳入要求 (來自在 NAT 後方執行的應用程式) 的 IP:通訊埠位址,並將該位址傳回做為回應。換句話說,應用程式會使用 STUN 伺服器,從公開角度探索其 IP:通訊埠。這項程序可讓 WebRTC 對等互連取得可公開存取的位址,然後透過信號機制將位址傳遞給另一個對等互連,以便設定直接連結。
STUN 伺服器不需要執行或記住太多工作,因此規格相對較低的 STUN 伺服器可以處理大量要求。
大多數 WebRTC 通話都能使用 STUN 成功建立連線,但如果對等互連端位於防火牆和複雜的 NAT 設定後方,則可能較少。
TURN
RTCPeerConnection 會嘗試透過 UDP 在對等互連之間建立直接通訊。如果失敗,RTCPeerConnection 會改用 TCP。如果失敗,則可使用 TURN 伺服器做為備用,在端點之間轉送資料。
再次強調,TURN 是用來在對等互連之間轉送音訊、影片和資料串流,而非信號資料!
TURN 伺服器具有公開位址,因此即使對等互連位於防火牆或 Proxy 後方,對等互連仍可與其聯絡。TURN 伺服器只有一項任務:轉發串流。與 STUN 伺服器不同,TURN 伺服器本身會消耗大量頻寬。
這張圖表顯示 TURN 的運作方式。純 STUN 未成功,因此每個對等互連都會改用 TURN 伺服器。
部署 STUN 和 TURN 伺服器
Google 執行公開 STUN 伺服器 stun.l.google.com:19302 (appr.tc 使用),用於測試。如要使用正式版 STUN/TURN 服務,請使用 rfc5766-turn-server。STUN 和 TURN 伺服器的原始碼可在 GitHub 取得,您也可以在該處找到多個伺服器安裝資訊來源的連結。您也可以使用 Amazon Web Services 的 VM 映像檔。
另一種 TURN 伺服器是 restund,可做為原始碼使用,也適用於 AWS。您可以在 Compute 上設定 restund:
- 視需要開啟防火牆,允許 tcp=443、udp/tcp=3478。
- 建立四個執行個體,每個公開 IP 各一個,使用標準 Ubuntu 12.06 映像檔。
- 設定本機防火牆 (允許任何來源的任何流量)。
- 安裝工具:
shell sudo apt-get install make sudo apt-get install gcc - 從 creytiv.com/re.html 安裝 libre。
- 從 creytiv.com/restund.html 擷取 restund 並解壓縮。
wgethancke.name/restund-auth.patch,並使用patch -p1 < restund-auth.patch套用。- 為 libre 和 restund 執行
make、sudo make install。 - 根據需求調整
restund.conf(替換 IP 位址,並確認其中包含相同的共用密鑰),然後複製到/etc。 - 將
restund/etc/restund複製到/etc/init.d/。 - 設定 restund:
- 設定
LD_LIBRARY_PATH。 - 將
restund.conf複製到/etc/restund.conf。 - 將
restund.conf設為使用右側 10。完全不需要外部 IP 位址
- 設定
- 執行 restund
- 使用遠端機器中的 stund 用戶端進行測試:
./client IP:port
多方 WebRTC
您也可以參考 Justin Uberti 針對存取 TURN 服務的 REST API 提出的 IETF 標準。
媒體串流有許多用途,不限於一對一通話。例如,一群同事之間的視訊會議,或是一場公開活動,其中有一位演講者和數百或數百萬名觀眾。
WebRTC 應用程式可以使用多個 RTCPeerConnection,讓每個端點在網狀設定中連線至其他端點。talky.io 等應用程式就是採用這種方法,而且在少數對等互連的情況下運作良好。超過這個值,處理和頻寬消耗就會過多,尤其是行動用戶端。
或者,WebRTC 應用程式可以選擇一個端點,以星狀設定將串流發布至所有其他端點。您也可以在伺服器上執行 WebRTC 端點,並建構自己的重新發布機制 (webrtc.org 提供用戶端應用程式範例)。
某個 RTCPeerConnection 的 MediaStream 可做為另一個
的輸入內容。這可讓網頁應用程式選擇要連線至哪個其他對等互連,進而處理通話轉接,因此可提供更具彈性的架構。如要查看實際運作情形,請參閱「WebRTC 範例:對接連線轉送」和「WebRTC 範例:多個對接連線」。
多點控制單元
如要處理大量端點,建議使用多點控制單元 (MCU)。這類伺服器可做為橋梁,在大量參與者之間發布媒體。MCU 可處理視訊會議中的不同解析度、轉碼器和影格率、轉碼、選擇性串流轉送,以及混合或錄製音訊和視訊。如果是多方通話,則需要考量多項問題,尤其是如何顯示多個視訊輸入,以及混合多個來源的音訊。vLine 等雲端平台也會嘗試最佳化流量轉送。
你可以購買完整的 MCU 硬體套件,也可以自行建構。
市面上有多種開放原始碼 MCU 軟體可供選擇。舉例來說,Licode (舊稱 Lynckia) 製作了 WebRTC 的開放原始碼 MCU。OpenTok 則有 Mantis。
瀏覽器以外:VoIP、電話和訊息
WebRTC 的標準化特性,讓瀏覽器中執行的 WebRTC 應用程式,能與其他通訊平台 (例如電話或視訊會議系統) 上執行的裝置或平台建立通訊。
SIP 是 VoIP 和視訊會議系統使用的信號通訊協定。如要啟用 WebRTC 網頁應用程式和 SIP 用戶端 (例如視訊會議系統) 之間的通訊,WebRTC 需要 Proxy 伺服器來調解信號。信號必須透過閘道傳送,但通訊建立後,SRTP 流量 (視訊和音訊) 就能透過點對點方式傳送。
公用交換電話網路 (PSTN) 是所有「傳統」類比電話的電路交換網路。如要在 WebRTC 網頁應用程式和電話之間通話,流量必須通過 PSTN 閘道。同樣地,WebRTC 網頁應用程式需要中介 XMPP 伺服器,才能與 Jingle 端點 (例如 IM 用戶端) 通訊。Jingle 是 Google 開發的 XMPP 擴充功能,可為訊息服務啟用語音和視訊功能。目前的 WebRTC 實作是以 C++ libjingle 程式庫為基礎,這是最初為 Talk 開發的 Jingle 實作。
許多應用程式、程式庫和平台都會利用 WebRTC 與外部世界通訊。例如:
瞭解詳情
- 閱讀 WebRTC API 說明文件。
- WebRTC 程式碼實驗室提供逐步操作說明,說明如何使用在 Node 上執行的 Socket.io 信號服務,建構影片和文字即時通訊應用程式。
- Chris Wilson 的 SFHTML5 簡報:WebRTC 應用程式簡介
這本 350 頁的書《WebRTC: APIs and RTCWEB Protocols of the HTML5 Real-Time Web》提供許多關於資料和信號路徑的詳細資訊,並包含多張詳細的網路拓撲圖。