WebRTC WHIP および WHEP チュートリアル: ライブ ストリーミング アプリを構築する
この記事はもともと 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 アプリをより効率的に実装できます
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 を介した簡素化されたシグナリングにより、シグナリング サーバーの追加に関連するコストが削減されます
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 を使用したシグナリングにより接続が高速化され、ユーザー エクスペリエンスが向上します。
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 を使用したステップアップ構成
WHIP サポートを使用して GStreamer をインストールします
-
GStreamer を使用して WHIP サーバーをセットアップする
- 次のように WHIP 接続をリッスンする GStreamer パイプラインを作成します
gst-launch-1.0 whipserversrc name=whip \ ! queue ! videoconvert ! autovideosink
上記のコマンドは、受信メディア ストリームを受け入れて表示する WHIP サーバーを起動します
-
Metered.ca TURN サーバー
を使用するようにサーバーを設定する- TURN サーバーを使用するように GStreamer パイプラインを変更します。 NAT ルーターとファイアウォールが接続をブロックするため、これは重要です。
gst-launch-1.0 whipserversrc name=whip ice-server="turn://YOUR_USERNAME:YOUR_CREDENTIAL@relay.metered.ca:80" \ ! queue ! videoconvert ! autovideosink
-
Node.JS を使用してリバース プロキシを設定する (オプション):
- 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 リクエストを使用して接続の確立に必要なシグナリングを処理できます。
-
メディア ストリームのキャプチャ:
- 次のようなメディア ストリームをキャプチャできます。
const mediaStream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
- 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", }, ], });
- メディア トラックを接続に追加します:
mediaStream.getTracks().forEach((track) => { pc.addTrack(track, mediaStream); });
- 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 サーバー サービスの使用
-
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 統合。
-
RTCPeerConnection を初期化します
- 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
- 受信メディア トラックを処理します
サーバーからリモート トラックを復活させるためにイベント リスナーをセットアップします
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'); });
- WHEP サーバーに HTTP GET リクエストを送信します:
サーバーに GET リクエストを送信します
const mediaStream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
- 受信した 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", }, ], });
- SDP 回答を作成して送信します
SDP 回答を作成し、HTTP POST リクエストを通じてサーバーに送信します
mediaStream.getTracks().forEach((track) => { pc.addTrack(track, mediaStream); });
- 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 });
フロントエンドでメディア ストリームを処理します
- 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", }, ], });
- ビデオ要素にリモート ストリームを添付します
トラックイベントが発生すると、受信したストリームをビデオ要素に添付します
-
メディア ストリーム イベントの処理
- 接続状態の変更
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 サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック











Pythonは、スムーズな学習曲線と簡潔な構文を備えた初心者により適しています。 JavaScriptは、急な学習曲線と柔軟な構文を備えたフロントエンド開発に適しています。 1。Python構文は直感的で、データサイエンスやバックエンド開発に適しています。 2。JavaScriptは柔軟で、フロントエンドおよびサーバー側のプログラミングで広く使用されています。

Web開発におけるJavaScriptの主な用途には、クライアントの相互作用、フォーム検証、非同期通信が含まれます。 1)DOM操作による動的なコンテンツの更新とユーザーインタラクション。 2)ユーザーエクスペリエンスを改善するためにデータを提出する前に、クライアントの検証が実行されます。 3)サーバーとのリフレッシュレス通信は、AJAXテクノロジーを通じて達成されます。

現実世界でのJavaScriptのアプリケーションには、フロントエンドとバックエンドの開発が含まれます。 1)DOM操作とイベント処理を含むTODOリストアプリケーションを構築して、フロントエンドアプリケーションを表示します。 2)node.jsを介してRestfulapiを構築し、バックエンドアプリケーションをデモンストレーションします。

JavaScriptエンジンが内部的にどのように機能するかを理解することは、開発者にとってより効率的なコードの作成とパフォーマンスのボトルネックと最適化戦略の理解に役立つためです。 1)エンジンのワークフローには、3つの段階が含まれます。解析、コンパイル、実行。 2)実行プロセス中、エンジンはインラインキャッシュや非表示クラスなどの動的最適化を実行します。 3)ベストプラクティスには、グローバル変数の避け、ループの最適化、constとletsの使用、閉鎖の過度の使用の回避が含まれます。

開発環境におけるPythonとJavaScriptの両方の選択が重要です。 1)Pythonの開発環境には、Pycharm、Jupyternotebook、Anacondaが含まれます。これらは、データサイエンスと迅速なプロトタイピングに適しています。 2)JavaScriptの開発環境には、フロントエンドおよびバックエンド開発に適したnode.js、vscode、およびwebpackが含まれます。プロジェクトのニーズに応じて適切なツールを選択すると、開発効率とプロジェクトの成功率が向上する可能性があります。

CとCは、主に通訳者とJITコンパイラを実装するために使用されるJavaScriptエンジンで重要な役割を果たします。 1)cは、JavaScriptソースコードを解析し、抽象的な構文ツリーを生成するために使用されます。 2)Cは、Bytecodeの生成と実行を担当します。 3)Cは、JITコンパイラを実装し、実行時にホットスポットコードを最適化およびコンパイルし、JavaScriptの実行効率を大幅に改善します。

Pythonはデータサイエンスと自動化により適していますが、JavaScriptはフロントエンドとフルスタックの開発により適しています。 1. Pythonは、データ処理とモデリングのためにNumpyやPandasなどのライブラリを使用して、データサイエンスと機械学習でうまく機能します。 2。Pythonは、自動化とスクリプトにおいて簡潔で効率的です。 3. JavaScriptはフロントエンド開発に不可欠であり、動的なWebページと単一ページアプリケーションの構築に使用されます。 4. JavaScriptは、node.jsを通じてバックエンド開発において役割を果たし、フルスタック開発をサポートします。

JavaScriptは、Webサイト、モバイルアプリケーション、デスクトップアプリケーション、サーバー側のプログラミングで広く使用されています。 1)Webサイト開発では、JavaScriptはHTMLおよびCSSと一緒にDOMを運用して、JQueryやReactなどのフレームワークをサポートします。 2)ReactNativeおよびIonicを通じて、JavaScriptはクロスプラットフォームモバイルアプリケーションを開発するために使用されます。 3)電子フレームワークにより、JavaScriptはデスクトップアプリケーションを構築できます。 4)node.jsを使用すると、JavaScriptがサーバー側で実行され、高い並行リクエストをサポートします。
