ホームページ > 記事 > ウェブフロントエンド > WebRTC WHIP および WHEP チュートリアル: ライブ ストリーミング アプリを構築する
この記事はもともと Metered Blog で公開されたものです: WebRTC WHIP & WHEP チュートリアル: ライブ ストリーミング アプリの構築
WHIP (WebRTC-HTTP Ingestion Protocol) および WHEP (WebRTC-HTTP Egress Protocol) は、標準の HTTP メソッドを使用して WebRTC でのシグナリングを合理化するように設計されたプロトコルです
WHIP の定義: WHIP は、クライアント デバイスがメディア ストリームをサーバーに送信する方法を簡素化します。
WHEP の定義: WHEP プロトコルは、サーバーからクライアントにメディア ストリームを配信するために使用されます。 HTTP プロトコルを使用してメディア消費のシグナリングを処理するため、クライアント デバイスは複雑なセットアップなしでメディア ストリームを受信できます
WebRTC シグナリングの簡素化における役割
実装の容易さ: WHEP と WHIP は HTTP プロトコルを使用するため、これらのプロトコルは
ステートレス通信: これは、HTTP がステートレス プロトコルであるため、サーバーはリクエスト間で進行中のセッション情報を維持する必要がありません。
互換性の向上: HTTP には普遍的な互換性があるため、シグナリングに HTTP を使用することが、プラットフォームやデバイス間の互換性にとって最適です
迅速な開発: 従来のシグナリング手法の複雑な詳細を考慮する必要がないため、開発者は WebRTC アプリをより効率的に実装できます
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 を介した簡素化されたシグナリングにより、シグナリング サーバーの追加に関連するコストが削減されます
WHEP プロトコルは、サーバーからクライアント デバイスにメディアを配信するプロセスを簡素化します。
このように、WHEP プロトコルを使用すると、HTTP を使用して、サーバーからクライアント デバイスへメディアを受信するためのシグナリングをセットアップできます。
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 を使用したシグナリングにより接続が高速化され、ユーザー エクスペリエンスが向上します。
WHIP と WHEP を組み合わせることで、開発者は WebRTC 用の包括的なシグナリング ソリューションを作成できます
この組み合わせにより、メディア ストリームの取り込みと配信が簡素化され、WebRTC のよりスムーズな実装が保証されます
統合シグナリング アプローチ: 取り込みと配信の両方に HTTP を使用することで、一貫したシグナリング方法論が作成されます
複雑さの軽減: 開発者は HTTP プロトコルのみを扱う必要があるため、学習曲線とコードのメンテナンスが軽減されます
パフォーマンスの向上: シグナリング用の単一プロトコルを使用してコードを合理化することで、メディア送信時の接続時間が短縮され、レイテンシーが短縮されます
ライブ ストリーミング プラットフォーム:
対話型アプリケーション
スケーラブルなアーキテクチャ
WebRTC アプリに WHIP と WHEP を実装するのは非常に簡単です。このセクションでは、WHIP サーバーをセットアップし、ノードや Docker などの最新テクノロジーを使用してアプリケーションに統合します
ここでは、NAT トラバーサルに Metered.ca TURN サーバー サービスを使用します
前提条件と環境セットアップ:
Node.js と NPM: 最新の Node と nvm がインストールされていることを確認してください
Metered.ca アカウント:従量制 TURN サーバー
パブリック IP アドレス: これは、サーバーがインターネット上でアクセスできるようにするために必要です。アプリケーションにクラウド プロバイダーを使用している場合は、そのプロバイダーで無料のパブリック IP アドレスを取得できます
WebRTC メディア サーバー: WHIP をサポートする GStreamer や Janus などのメディア サーバーが必要です
WHIP サポートを使用して GStreamer をインストールします
GStreamer を使用して WHIP サーバーをセットアップする
gst-launch-1.0 whipserversrc name=whip \ ! queue ! videoconvert ! autovideosink
上記のコマンドは、受信メディア ストリームを受け入れて表示する WHIP サーバーを起動します
Metered.ca TURN サーバー
を使用するようにサーバーを設定するgst-launch-1.0 whipserversrc name=whip ice-server="turn://YOUR_USERNAME:YOUR_CREDENTIAL@relay.metered.ca:80" \ ! queue ! videoconvert ! autovideosink
Node.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 を統合するためのコード スニペット:
クライアント側では、RTCPeerConnection を利用してメディア ストリームをキャプチャし、HTTP リクエストを使用して接続の確立に必要なシグナリングを処理できます。
メディア ストリームのキャプチャ:
const mediaStream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
従量制課金 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", }, ], });
mediaStream.getTracks().forEach((track) => { pc.addTrack(track, mediaStream); });
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 POST リクエスト:
期待される応答:
サーバー側:
SDP オファーを受け取る:
SDP 回答を生成
直接ピアツーピア接続が不可能な場合に、NAT およびファイアウォールを介したメディア トラバーサルを容易にします
TURN サーバーの認証情報と ICE サーバーは次のとおりです
gst-launch-1.0 whipserversrc name=whip \ ! queue ! videoconvert ! autovideosink
WHIP クライアントがあると、アプリは HTTP シグナリングを使用してサーバーからメディア ストリームを受信できます。
JavaScript における WebRTC API の基本的な理解
WHEP GStreamer Janus またはその他をサポートするメディア サーバー
Metered.ca TURN サーバー認証情報
RTCPeerConnection を初期化します
gst-launch-1.0 whipserversrc name=whip ice-server="turn://YOUR_USERNAME:YOUR_CREDENTIAL@relay.metered.ca:80" \ ! queue ! videoconvert ! autovideosink
サーバーからリモート トラックを復活させるためにイベント リスナーをセットアップします
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'); });
サーバーに GET リクエストを送信します
const mediaStream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
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", }, ], });
SDP 回答を作成し、HTTP POST リクエストを通じてサーバーに送信します
mediaStream.getTracks().forEach((track) => { pc.addTrack(track, mediaStream); });
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 });
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", }, ], });
トラックイベントが発生すると、受信したストリームをビデオ要素に添付します
メディア ストリーム イベントの処理
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; });
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();
従量制 TURN サーバー
API: 強力な API でサーバー管理を実現します。 API を介して認証情報の追加/削除、API を介してユーザーごとの認証情報とユーザー指標を取得、API を介して認証情報を有効/無効にする、API を介して日付ごとの使用状況データを取得するなどの操作を行うことができます。
グローバル地理位置ターゲティング: トラフィックを最も近いサーバーに自動的に送信し、遅延を最小限に抑え、最高品質のパフォーマンスを実現します。世界中のどこでも遅延が 50 ミリ秒未満
世界のすべての地域のサーバー: トロント、マイアミ、サンフランシスコ、アムステルダム、ロンドン、フランクフルト、バンガロール、シンガポール、シドニー、ソウル、ダラス、ニューヨーク
低遅延: 世界中のどこでも遅延が 50 ミリ秒未満です。
費用対効果の高い: 帯域幅とボリュームの割引が可能な従量課金制の料金設定です。
簡単な管理: 使用状況ログ、アカウントがしきい値制限に達したときのメール、請求記録、メールと電話のサポートを取得します。
準拠規格: UDP、TCP、TLS、および DTLS で RFC 5389、5769、5780、5766、6062、6156、5245、5768、6336、6544、5928 に準拠します。
マルチテナント: 複数の認証情報を作成し、顧客ごとまたは異なるアプリごとに使用を分離します。使用状況ログ、請求記録、およびしきい値アラートを取得します。
エンタープライズの信頼性: SLA による 99.999% の稼働時間。
エンタープライズ規模: 同時トラフィックまたは合計トラフィックに制限はありません。従量制の TURN サーバーはエンタープライズ スケーラビリティを提供します
5 GB/月 無料: 無料プランでは毎月 5 GB の TURN サーバーを無料で利用できます
ポート 80 および 443 で実行
ディープ パケット インスペクション ファイアウォールを介した接続を許可する TURNS SSL をサポートします。
TCP と UDP の両方をサポート
無料無制限スタン
他の記事も参考にしてください:
WebRTC データ チャネル: ガイド
簡単なピア チュートリアル: ビデオ、DataChannel 用の TURN サーバーの追加
従量制の WebRTC TURN サーバーをセットアップするガイド
WebRTC と HLS: どちらが最適ですか?
以上がWebRTC WHIP および WHEP チュートリアル: ライブ ストリーミング アプリを構築するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。