WebRTC WHIP および WHEP チュートリアル: ライブ ストリーミング アプリを構築する

Susan Sarandon
リリース: 2024-11-01 09:38:30
オリジナル
139 人が閲覧しました

この記事はもともと Metered Blog で公開されたものです: WebRTC WHIP & WHEP チュートリアル: ライブ ストリーミング アプリの構築

WHIP (WebRTC-HTTP Ingestion Protocol) および WHEP (WebRTC-HTTP Egress Protocol) は、標準の 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 では、WebRTC セッションのシグナリングと開始に HTTP プロトコルを使用することで、このプロセスが簡単になります

  • HTTP POST リクエスト: ここで、クライアント デバイスは、本文に SDP またはセッション記述プロトコル オファーを含む HTTP POST リクエストを WHIP エンドポイントに送信します

  • サーバーの応答:メディア サーバーは SDP オファーを処理し、リクエスト本文に SDP アンサーを含む 200 ステータス コードで応答します

  • ICE 候補交換: WHIP プロトコルは、新しい ICE 候補が利用可能になるたびにクライアントが追加の HTTP PATCH リクエストを送信できるようにすることで、ICE プロトコルをサポートします

  • 接続の確立: 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 交換: サーバーは HTTP 応答で SDP オファーを返し、クライアントは後続の POST リクエストで SDP 回答を送り返します

  • メディア受信: 接続が確立されると、確立された WebRTC 接続を介してメディア ストリームが受信されます。注: 多くの場合、WebRTC 接続を確立するにはTURN サーバー

  • が必要になります。
  • 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 などの最新テクノロジーを使用してアプリケーションに統合します

ここでは、NAT トラバーサルに Metered.ca TURN サーバー サービスを使用します

WHIP サーバーのセットアップ

前提条件と環境セットアップ:

  • Node.js と NPM: 最新の Node と nvm がインストールされていることを確認してください

  • Metered.ca アカウント:従量制 TURN サーバー

  • で無料アカウントを作成します
  • パブリック IP アドレス: これは、サーバーがインターネット上でアクセスできるようにするために必要です。アプリケーションにクラウド プロバイダーを使用している場合は、そのプロバイダーで無料のパブリック IP アドレスを取得できます

  • WebRTC メディア サーバー: WHIP をサポートする GStreamer や Janus などのメディア サーバーが必要です

Node.Js と GStreamer を使用したステップアップ構成

  1. WHIP サポートを使用して GStreamer をインストールします

  2. GStreamer を使用して WHIP サーバーをセットアップする

    1. 次のように WHIP 接続をリッスンする GStreamer パイプラインを作成します
gst-launch-1.0 whipserversrc name=whip \
  ! queue ! videoconvert ! autovideosink
ログイン後にコピー
ログイン後にコピー

上記のコマンドは、受信メディア ストリームを受け入れて表示する WHIP サーバーを起動します

  1. Metered.ca TURN サーバー

    を使用するようにサーバーを設定する
    1. TURN サーバーを使用するように GStreamer パイプラインを変更します。 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 リクエスト:

      • URL: 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 およびファイアウォールを介したメディア トラバーサルを容易にします

ICE サーバー構成に TURN サーバーを組み込む

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. WHEP サーバーに HTTP GET リクエストを送信します:

サーバーに 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 でサーバー管理を実現します。 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、6544、5928 に準拠します。

  8. マルチテナント: 複数の認証情報を作成し、顧客ごとまたは異なるアプリごとに使用を分離します。使用状況ログ、請求記録、およびしきい値アラートを取得します。

  9. エンタープライズの信頼性: SLA による 99.999% の稼働時間。

  10. エンタープライズ規模: 同時トラフィックまたは合計トラフィックに制限はありません。従量制の TURN サーバーはエンタープライズ スケーラビリティを提供します

  11. 5 GB/月 無料: 無料プランでは毎月 5 GB の TURN サーバーを無料で利用できます

  12. ポート 80 および 443 で実行

  13. ディープ パケット インスペクション ファイアウォールを介した接続を許可する TURNS SSL をサポートします。

  14. TCP と UDP の両方をサポート

  15. 無料無制限スタン


他の記事も参考にしてください:

  1. WebRTC データ チャネル: ガイド

  2. 簡単なピア チュートリアル: ビデオ、DataChannel 用の TURN サーバーの追加

  3. 従量制の WebRTC TURN サーバーをセットアップするガイド

  4. WebRTC と HLS: どちらが最適ですか?

以上がWebRTC WHIP および WHEP チュートリアル: ライブ ストリーミング アプリを構築するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!