首頁 > web前端 > js教程 > 主體

WebRTC WHIP 和 WHEP 教學:建立即時串流應用程式

Susan Sarandon
發布: 2024-11-01 09:38:30
原創
138 人瀏覽過

本文最初發佈在計量部落格:WebRTC WHIP 和 WHEP 教學:建立即時串流應用程式

WHIP(WebRTC-HTTP 攝取協定)WHEP(WebRTC-HTTP 出口協定) 是旨在藉助標準 HTTP 方法簡化 WebRTC 中訊號傳送的協定

  • WHIP 的定義:WHIP 簡化了客戶端裝置將媒體串流傳送到伺服器的方式。

    • 它取代了簡單 HTTP GET 請求所需的複雜訊號機制,從而更容易將媒體攝取到伺服器
  • WHEP 的定義:WHEP 協定用於將媒體串流從伺服器傳送到客戶端。它使用 HTTP 協定來處理媒體消費的訊號,從而使客戶端設備無需複雜的設定即可接收媒體串流

簡化 WebRTC 訊號的作用

  • 易於實施: WHEP 和 WHIP 使用 HTTP 協議,因此這些協議降低了與

  • 相關的複雜性
  • 無狀態通訊:這是因為 HTTP 是無狀態協議,伺服器不需要維護請求之間持續的會話資訊。

  • 相容性提高:由於HTTP具有通用相容性,因此使用HTTP進行訊號是跨平台和裝置相容性的最佳選擇

  • 快速開發:開發人員可以更有效地實現 WebRTC 應用程序,因為他們不需要考慮傳統信號方法的複雜細節

WebRTC WHIP & WHEP Tutorial: Build a live Streaming App

WHIP 是如何運作的

WHIP 如何處理媒體串流攝取

WHIP 協定徹底改變如何使用 HTTP 訊號方法將媒體串流從客戶端裝置傳送到伺服器

傳統上,要設定 WebRTC,您需要使用 Web 套接字或其他協定來設定複雜的訊號機制。借助 WHIP,透過使用 HTTP 協定發送訊號並啟動 WebRTC 會話,此過程變得簡單

  • HTTP POST 請求: 此處,用戶端裝置將正文中包含 SDP 或會話描述協定的 HTTP POST 要求傳送至 WHIP 端點

  • 伺服器回應: 媒體伺服器然後處理 SDP Offer 並使用 200 狀態碼回應,包括請求正文中的 SDP 答案

  • ICE 候選交換: WHIP 協議支援 ICE 協議,允許客戶端在新的 ICE 候選可用時發送額外的 HTTP PATCH 請求

  • 連接建立: 一旦 SDP 交換完成,就會建立點對點連接,使客戶端能夠將媒體串流傳輸到伺服器

相對於傳統攝取方法的優勢

  • 簡單性: 透過使用 WHIP 方法,WHIP 減少了對持久連線和訊號伺服器的需求。

  • 易於實作: 開發者可以使用具有通用相容性的 HTTP 來加快開發流程

  • 可擴充性:無狀態 HTTP 請求允許伺服器同時處理多個連線請求,從而輕鬆管理大量連線。

  • 防火牆和代理友好: HTTP 是防火牆友好的,幾乎所有類型的防火牆都允許 HTTP 流量

  • 成本效益: 透過 HTTP 進行的簡化訊號降低了與新增訊號伺服器相關的成本

WebRTC WHIP & WHEP Tutorial: Build a live Streaming App

WHEP 是如何運作的

WHEP 協定簡化了將媒體從伺服器傳輸到客戶端裝置的過程。 

因此,WHEP 協定可讓您使用 HTTP 來設定從伺服器和用戶端裝置接收媒體的訊號。

WHEP 在媒體串流中如何運作

  • HTTP GET 請求: 客戶端透過傳送 HTTP GET 請求至伺服器 WHEP 請求來要求媒體串流

  • SDP Exchange: 伺服器在 HTTP 回應中以 SDP Offer 回應,然後用戶端在後續 POST 請求中發回 SDP 回應

  • 媒體接收: 建立連線後,將透過已建立的 WebRTC 連線接收媒體串流。注意:很多時候您需要TURN 伺服器來建立 WebRTC 連線

  • 對 ICE 的支援: WHEP 允許透過額外的 HTTP 修補程式要求交換 ICE 候選者,從而實現更好的連接

客戶端串流的優勢

  • 簡化的客戶實現: 使用 HTTP 請求,從而減少複雜信號機制的需求 

  • 改進的兼容性: 對 HTTP 協定的普遍支援確保了改進的跨裝置相容性

  • 增強的可擴展性: 由於 HTTP 是無狀態協議,這提高了伺服器的可擴展性,並且使用少量資源即可擴展到大量用戶

  • 更好的網路遍歷: 因為您可以使用 HTTP 進行訊號傳輸,並且不需要 Web 套接字或其他機制,所以這可以改善連接的 NAT 遍歷。建立連線後,您確實需要WebRTC 的 TURN 伺服器

  • 減少延遲: 使用 HTTP 發送訊號可以實現更快的連接,從而增強用戶體驗。

WebRTC WHIP & WHEP Tutorial: Build a live Streaming App

WHIP 與 WHEP 之間的協同作用

結合兩種協定以實現高效率的端到端通訊:

透過結合 WHIP 和 WHEP,開發人員可以為 WebRTC 建立全面的訊號解決方案

這種組合簡化了媒體串流的攝取和交付,確保 WebRTC 的實施更加順利

  • 統一訊號方法: 使用 HTTP 進行攝取與交付,建立一致的訊號方法

  • 降低複雜性: 開發者只需處理 HTTP 協議,從而減少程式碼的學習曲線和維護

  • 增強的效能:使用單一訊號協定簡化程式碼,可以在傳輸媒體時縮短連線時間並降低延遲

展示效能改進的用例

  • 直播平台: 

  • 互動式應用程式

  • 可擴充架構

建立直播應用程式

在 WebRTC 應用程式中實作 WHIP 和 WHEP 非常簡單。在本節中,我們將設定一個 WHIP 伺服器並使用節點和 docker 等現代技術將其整合到您的應用程式中

這裡我們將使用 Metered.ca TURN 伺服器服務進行 NAT 穿越

設定 WHIP 伺服器

先決條件與環境設定:

  • Node.js 和 NPM: 確保您安裝了最新的 Node 和 nvm

  • Metered.ca 帳戶: 在 Metered TURN 伺服器

  • 上建立免費帳戶
  • 公用 IP 位址: 這是可透過網際網路存取伺服器所必需的。如果您的應用程式使用任何雲端供應商,您將獲得一個免費的公用 IP 位址

  • WebRTC 媒體伺服器: 我們需要一個支援 WHIP 的媒體伺服器,例如 GStreamer 或 Janus

使用 Node.Js 和 GStreamer 加強步驟設定

  1. 安裝支援 WHIP 的 GStreamer

  2. 使用 GStreamer 設定 WHIP 伺服器

    1. 建立一個 GStreamer 管道來監聽 WHIP 連接,如下所示
gst-launch-1.0 whipserversrc name=whip \
  ! queue ! videoconvert ! autovideosink
登入後複製
登入後複製

上述指令啟動一個 WHIP 伺服器,該伺服器接受傳入的媒體流並顯示它們

  1. 設定伺服器以使用Metered.ca TURN 伺服器

    1. 修改 GStreamer 管道以使用 TURN 伺服器。這很重要,因為 NAT 路由器和防火牆會阻止連接
gst-launch-1.0 whipserversrc name=whip ice-server="turn://YOUR_USERNAME:YOUR_CREDENTIAL@relay.metered.ca:80" \
  ! queue ! videoconvert ! autovideosink
登入後複製
登入後複製
  1. 使用 Node.JS 設定反向代理(可選):

    1. 如果您想管理 HTTP 端點或新增任何其他附加邏輯,您可以設定一個簡單的 Express js 伺服器
const express = require('express');
const httpProxy = require('http-proxy');
const app = express();
const proxy = httpProxy.createProxyServer();

app.post('/whip', (req, res) => {
  proxy.web(req, res, { target: 'http://localhost:PORT_WHERE_GSTREAMER_IS_RUNNING' });
});

app.listen(3000, () => {
  console.log('Proxy server running on port 3000');
});
登入後複製
登入後複製

在您的應用程式中實作 WHIP

整合 WHIP 的程式碼片段:

在用戶端,您可以藉助 RTCPeerConnection 擷取媒體串流,並使用 HTTP 請求來處理建立連線所需的訊號

  1. 捕捉媒體串流:

    1. 您可以捕捉媒體串流,例如
const mediaStream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
登入後複製
登入後複製
  1. 建立 RTCPeerConnection:

您可以在計量 TURN 伺服器的協助下建立 RTCPeerConnection

var myPeerConnection = new RTCPeerConnection({
  iceServers: [
      {
        urls: "stun:stun.relay.metered.ca:80",
      },
      {
        urls: "turn:global.relay.metered.ca:80",
        username: "your-username",
        credential: "your-credential",
      },
      {
        urls: "turn:global.relay.metered.ca:80?transport=tcp",
        username: "your-username",
        credential: "your-credential",
      },
      {
        urls: "turn:global.relay.metered.ca:443",
        username: "your-username",
        credential: "your-credential",
      },
      {
        urls: "turns:global.relay.metered.ca:443?transport=tcp",
        username: "your-username",
        credential: "your-credential",
      },
  ],
});
登入後複製
登入後複製
  1. 將媒體軌道加入連結:
mediaStream.getTracks().forEach((track) => {
  pc.addTrack(track, mediaStream);
});
登入後複製
登入後複製
  1. 建立 SDP 報價並將其發送到 WHIP 伺服器:
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);

const response = await fetch('http://YOUR_SERVER_IP:3000/whip', {
  method: 'POST',
  headers: { 'Content-Type': 'application/sdp' },
  body: pc.localDescription.sdp,
});

const sdpAnswer = await response.text();
await pc.setRemoteDescription({ type: 'answer', sdp: sdpAnswer });
登入後複製
登入後複製

處理訊號的 HTTP 請求和回應

  • 客戶端:

    • HTTP POST 請求: 

      • 網址:http://YOUR_SERVER_IP:3000/whip
      • 標頭:{ 'Content-Type': 'application/sdp' }
      • 正文:純文字形式的 SDP 報價
    • 期待回覆:

      • 狀態:201 已創建
      • 標題:帶有資源 URL 的位置標題
      • 正文:純文字形式的 SDP 答案
  • 伺服器端:

    • 接收 SDP 優惠:

      • 從 req.body 讀取 SDP
      • 建立WebRTC端點並設定遠端描述
    • 產生 SDP 答案

      • 來自伺服器 WebRTC 端點的 SDP 應答
      • 將 SDP 答案傳回 res.body
      • 使用 Metered.ca TURN 伺服器服務

WebRTC WHIP & WHEP Tutorial: Build a live Streaming App

使用 Metered.ca TURN 伺服器服務

TURN 伺服器的用途

當無法進行直接點對點連線時,促進媒體穿越 NAT 和防火牆

將 TURN 伺服器合併到 ICE 伺服器設定

這是 TURN 伺服器憑證和 ICE 伺服器

gst-launch-1.0 whipserversrc name=whip \
  ! queue ! videoconvert ! autovideosink
登入後複製
登入後複製

部署 WHEP 用戶端

擁有 WHIP 用戶端可讓您的應用程式使用 HTTP 訊號從伺服器接收媒體串流。

在客戶端整合 WHEP

  • 基本上了解 Javascript 中的 WebRTC API

  • 支援 WHEP GStreamer Janus 或任何其他

  • 的媒體伺服器
  • Metered.ca TURN 伺服器憑證

逐步將 WHEP 整合到您的應用程式中。

  1. 初始化 RTCPeerConnection

    1. 使用具有metered.ca轉伺服器的ICE伺服器建立一個RTCPeerConnection實例
gst-launch-1.0 whipserversrc name=whip ice-server="turn://YOUR_USERNAME:YOUR_CREDENTIAL@relay.metered.ca:80" \
  ! queue ! videoconvert ! autovideosink
登入後複製
登入後複製
  1. 處理傳入的媒體軌道

設定事件偵聽器以從伺服器恢復遠端軌道

const express = require('express');
const httpProxy = require('http-proxy');
const app = express();
const proxy = httpProxy.createProxyServer();

app.post('/whip', (req, res) => {
  proxy.web(req, res, { target: 'http://localhost:PORT_WHERE_GSTREAMER_IS_RUNNING' });
});

app.listen(3000, () => {
  console.log('Proxy server running on port 3000');
});
登入後複製
登入後複製
  1. 傳送 HTTP GET 伺服器到 WHEP 伺服器:

向伺服器發送 GET 請求

const mediaStream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
登入後複製
登入後複製
  1. 收到的 SDP 報價的遠端描述
var myPeerConnection = new RTCPeerConnection({
  iceServers: [
      {
        urls: "stun:stun.relay.metered.ca:80",
      },
      {
        urls: "turn:global.relay.metered.ca:80",
        username: "your-username",
        credential: "your-credential",
      },
      {
        urls: "turn:global.relay.metered.ca:80?transport=tcp",
        username: "your-username",
        credential: "your-credential",
      },
      {
        urls: "turn:global.relay.metered.ca:443",
        username: "your-username",
        credential: "your-credential",
      },
      {
        urls: "turns:global.relay.metered.ca:443?transport=tcp",
        username: "your-username",
        credential: "your-credential",
      },
  ],
});
登入後複製
登入後複製
  1. 建立並發送 SDP 答案

建立 SDP 應答並透過 HTTP POST 請求將其傳送至伺服器

mediaStream.getTracks().forEach((track) => {
  pc.addTrack(track, mediaStream);
});
登入後複製
登入後複製
  1. 處理 ICE 候選人交換(可選):

如果您需要單獨發送 ICE 候選人,請處理icecandidate 事件

const offer = await pc.createOffer();
await pc.setLocalDescription(offer);

const response = await fetch('http://YOUR_SERVER_IP:3000/whip', {
  method: 'POST',
  headers: { 'Content-Type': 'application/sdp' },
  body: pc.localDescription.sdp,
});

const sdpAnswer = await response.text();
await pc.setRemoteDescription({ type: 'answer', sdp: sdpAnswer });
登入後複製
登入後複製

在前端處理媒體串流

  1. 在 HTML 中建立影片元素
var myPeerConnection = new RTCPeerConnection({
  iceServers: [
      {
        urls: "stun:stun.relay.metered.ca:80",
      },
      {
        urls: "turn:global.relay.metered.ca:80",
        username: "e13b9bsdfdsfsdfb0676cc5b6",
        credential: "dedewdewfer+gq5iT",
      },
      {
        urls: "turn:global.relay.metered.ca:80?transport=tcp",
        username: "e13bdfdsfds6b0676cc5b6",
        credential: "dewfrefre+gq5iT",
      },
      {
        urls: "turn:global.relay.metered.ca:443",
        username: "e13b9fsdfdsfsd86b0676cc5b6",
        credential: "csdfwefeer+gq5iT",
      },
      {
        urls: "turns:global.relay.metered.ca:443?transport=tcp",
        username: "e13b9dsfsdfe6b0676cc5b6",
        credential: "sdfewtrererer+gq5iT",
      },
  ],
});
登入後複製
登入後複製
  1. 將遠端串流附加到視訊元素

當觸發追蹤事件時,將收到的串流附加到視訊元素

  1. 處理媒體串流事件

    1. 連線狀態改變
var myPeerConnection = new RTCPeerConnection({
  iceServers: [
      {
        urls: "stun:stun.relay.metered.ca:80",
      },
      {
        urls: "turn:global.relay.metered.ca:80",
        username: "e13b9bsdfdsfsdfb0676cc5b6",
        credential: "dedewdewfer+gq5iT",
      },
      {
        urls: "turn:global.relay.metered.ca:80?transport=tcp",
        username: "e13bdfdsfds6b0676cc5b6",
        credential: "dewfrefre+gq5iT",
      },
      {
        urls: "turn:global.relay.metered.ca:443",
        username: "e13b9fsdfdsfsd86b0676cc5b6",
        credential: "csdfwefeer+gq5iT",
      },
      {
        urls: "turns:global.relay.metered.ca:443?transport=tcp",
        username: "e13b9dsfsdfe6b0676cc5b6",
        credential: "sdfewtrererer+gq5iT",
      },
  ],
});
登入後複製
登入後複製

b.需要協商

pc.addEventListener('track', (event) => {
  const [remoteStream] = event.streams;
  // Attach the remote stream to a video element
  const remoteVideo = document.getElementById('remoteVideo');
  remoteVideo.srcObject = remoteStream;
});
登入後複製
  1. 完整範例程式碼
const whepServerEndpoint = 'http://YOUR_SERVER_IP:3000/whep'; // Replace with your server's WHEP endpoint

const response = await fetch(whepEndpoint, {
  method: 'GET',
  headers: {
    Accept: 'application/sdp',
  },
});

const sdpOffer = await response.text();
登入後複製

WebRTC WHIP & WHEP Tutorial: Build a live Streaming App

計量 TURN 伺服器

  1. API: 使用強大的 API 進行 TURN 伺服器管理。您可以執行以下操作:透過 API 新增/刪除憑證、透過 API 檢索每個使用者/憑證和使用者指標、透過 API 啟用/停用憑證、透過 API 按日期檢索使用資料。

  2. 全球地理位置定位:自動將流量定向到最近的伺服器,以實現盡可能低的延遲和最高的品質效能。全球任何地方的延遲均低於 50 毫秒

  3. 全球所有地區的伺服器:多倫多、邁阿密、舊金山、阿姆斯特丹、倫敦、法蘭克福、班加羅爾、新加坡、雪梨、首爾、達拉斯、紐約

  4. 低延遲: 低於 50 毫秒的延遲,在世界任何地方。

  5. 經濟高效:即用即付定價,並提供頻寬和批量折扣。

  6. 輕鬆管理: 取得使用日誌、帳戶達到門檻限制時的電子郵件、帳單記錄以及電子郵件和電話支援。

  7. 符合標準: 符合 UDP、TCP、TLS 和 DTLS 的 RFC 5389、5769、5780、5766、6062、6156、5245、5768、6336、925336、92536、92536、92536。

  8. 多租用戶: 建立多個憑證並依客戶或不同應用程式分開使用。取得使用日誌、計費記錄和閾值警報。

  9. 企業可靠性: SLA 正​​常運作時間達 99.999%。

  10. 企業規模: 不限制併發流量或總流量。計量 TURN 伺服器提供企業可擴充性

  11. 每月 5 GB 免費: 透過免費方案每月獲得 5 GB 免費 TURN 伺服器使用量

  12. 在連接埠 80 和 443 上運作

  13. 支援 TURNS SSL 以允許透過深度封包偵測防火牆進行連線。

  14. 同時支援 TCP 和 UDP

  15. 免費無限制 STUN


您可以考慮我們的其他一些文章:

  1. WebRTC 資料通道:指引

  2. 簡單對等教學:為影片、DataChannel 新增 TURN 伺服器

  3. 使用計量設定 WebRTC TURN 伺服器的指南

  4. WebRTC 與 HLS:哪個最適合您?

以上是WebRTC WHIP 和 WHEP 教學:建立即時串流應用程式的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:dev.to
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!