見出し画像

WebRTC 入門

以下の記事を参考に書いてます。

Getting Started with WebRTC

1. プラグインなしのリアルタイム通信

電話、テレビ、コンピュータが共通のプラットフォームで通信できる世界を想像してみてください。ビデオチャット、P2PをWebアプリに簡単に追加できることを想像してみてください。それが「WebRTC」のビジョンです。

「WebRTC」は、デスクトップとモバイルの「Google Chrome」「Safari」「Firefox」「Opera」で利用できるようになりました。はじめに試してみるべきは、シンプルなビデオチャット「appr.tc」です。

(1) ブラウザで「appr.tc」を開く。
(2) 「Joinボタン」をクリックしてチャットルームに参加。
(3) Webカメラを有効化。
(3) ページ下部に表示されているURLを別のタブまたはPCで開く。

2. クイックスタート

この記事を読む時間がない、または単にコードが見たい人は、以下が参考になります。

(1) Google I/OプレゼンテーションのWebRTCの概要

(2) 「simpl.info/gum」を呼んで、getUserMedia()を確認。
(3) 「simpl.info/pc」を呼んで、「RTCPeerConnection API」を理解。
(4) 「appr.tc」のコードとコンソールログ。
(5) 「WebRTC JavaScript API」を実行するデモ
(6) トラブルシューティングページ「test.webrtc.org」。
(7) 「WebRTC codelab」を確認。

3. WebRTCの歴史

Webの最後の主要課題の1つは、音声とビデオを介した人間のコミュニケーション「RTC」(Real Time Communication)を可能にすることです。

歴史的に、「RTC」は複雑なものであり、高価なオーディオ・ビデオ技術を社内でライセンス供与または開発する必要があります。「RTC」を既存のコンテンツ、データ、サービスと統合することは、特にWeb上では困難で時間がかかります。

「Gmail Video Chat」は2008年に人気を博し、2011年にはGoogleが「Hangout」を導入しました。Googleは、コーデックやエコーキャンセレーションなど、「RTC」に必要な多くのコンポーネントを開発した会社である「GIPS」を購入しました。Googleは、「GIPS」の技術をオープンソース化し、IETFおよびW3Cの関連標準化団体と協力して、業界のコンセンサスを確保しました。2011年5月、エリクソンは「WebRTC」の最初の実装を構築しました。

「WebRTC」は、プラグインを使用しないリアルタイムのビデオ、オーディオ、データ通信のためのオープンスタンダードを実装しました。「WebRTC」の基本原則は、APIはオープンソースであり、無料で、標準化されており、Webブラウザに組み込まれ、既存のテクノロジーよりも効率的である必要があるということになります。

4. WebRTCの現在

「WebRTC」は、「WhatsApp」「Facebook Messenger」「appear.in」などのアプリや、「TokBox」などのプラットフォームで使用されています。「WebKitGTK+」「Qt」とも統合されています。

「WebRTC」は、次の3つのAPIを実装しています。

MediaStream (getUserMedia)
RTCPeerConnection
RTCDataChannel

APIは、次の2つの仕様で定義されています。

WebRTC
getUserMedia

3つのAPIはすべて、デスクトップとモバイルの「Chrome」「Safari」「Firefox」「Edge」「Opera」でサポートされています。

◎ getUserMedia
webrtc.github.io/samples」でデモとコードを確認するか、getUserMediaを使用するChris Wilsonのサンプルを確認してください。

◎ RTCPeerConnection
webrtc.github.io/samples」にシンプルなデモがあり、「appr.tc」に完全に機能するビデオチャットアプリがあります。このアプリは、JavaScriptシムである「adapter.js」を使用し、WebRTCコミュニティの助けを借りてGoogleが管理し、ブラウザの違いや仕様の変更を抽象化します。

◎ RTCDataChannel
webrtc.github.io/samples」にあるデータチャネルデモの1つを確認してください。

WebRTC codelab」では、3つのAPIを使用して、ビデオチャットとファイル共有のためのシンプルなアプリを構築する方法を示しています。

5. 初めてのWebRTC

「WebRTC」は、以下の処理を行う必要があります。

・ストリーミングオーディオ、ビデオ、またはその他のデータを取得する。
・IPアドレスやポートなどのネットワーク情報を取得し、これを他のWebRTCクライアント(ピア)と交換して、NATやファイアウォールを介しても接続できるようにする。
・エラーを報告し、セッションを開始または閉じるためのシグナリング通信を調整する。
・メディアやクライアントの機能(解像度やコーデックなど)に関する情報を交換する。

ストリーミングデータを取得して通信するために、「WebRTC」は次のAPIを実装しています。

MediaStream
ユーザーのカメラやマイクからのデータストリームへのアクセスを取得。

RTCPeerConnection
暗号化と帯域幅管理の機能を備えたオーディオまたはビデオ通話。

RTCDataChannel
一般的なデータのP2P通信。

6. MediaStream (getUserMedia)

MediaStream」は、メディア同期ストリームのAPIです。カメラとマイクの入力から取得したストリームは、ビデオとオーディオのトラックが同期します(MediaStreamTrack<track>と混同しないでください。まったく異なるものです)。

「MediaStream」を理解する最も簡単な方法は、実際に「MediaStream」を確認することです。

(1) ブラウザで、「webrtc.github.io/samples/src/content/getusermedia/gum」にあるデモを開く。
(2) コンソールを開く。
(3) streamグローバルスコープにある変数を調べる。

各「MediaStream」には、getUserMedia()によって生成される入力と、ビデオ要素または「RTCPeerConnection」に渡される出力があります。

getUserMedia()は「MediaStreamConstraints」を取り、「MediaStream」に解決される「Promise」を返します。

各「MediaStream」には、「Xk7EuLhsuHKbnjLWkW4yYGNJJ8ONsgwHBvLQ」などのラベルがあります。「MediaStreamTracks」の配列は、getAudioTracks()およびgetVideoTracks()によって返されます。

webrtc.github.io/samples/src/content/getusermedia/gum」の例では、stream.getAudioTracks()は空の配列を返します(オーディオがないので)。各「MediaStreamTrack」には、種類(「video」または「audio」)とラベル(「FaceTime HD Camera (built-in)」のようなもの)があり、オーディオまたはビデオのいずれかの 1 つ以上のチャンネルを表します。例えば、フロントカメラ、リアカメラ、マイクからのストリームを取得するチャットアプリケーションや、「スクリーン共有」アプリケーションなどです。

「MediaStream」は、srcObject属性を設定することでビデオ要素にアタッチできます。以前は、これはsrc属性をURL.createObjectURL()で作成されたオブジェクトURLに設定することで行われていましたが、これは廃止されました。

「MediaStreamTrack」はアクティブにカメラを使用しており、リソースを使用してカメラを開いたままにします(カメラのライトをオンにします)。
トラックを使用しなくなったら、カメラを閉じることができるようにtrack.stop()を呼び出してください。

getUserMediaは、「Web Audio API」の入力ノードとしても使用できます。

// ブラウザの違いの対処
let audioContext;
if (typeof AudioContext === 'function') {
    audioContext = new AudioContext();
} else if (typeof webkitAudioContext === 'function') {
    audioContext = new webkitAudioContext(); // eslint-disable-line new-cap
} else {
    console.log('Sorry! Web Audio not supported.');
}

// フィルターノードの生成
var filterNode = audioContext.createBiquadFilter();

// https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#BiquadFilterNode-section 参照
filterNode.type = 'highpass';

// カットオフ周波数:ハイパスの場合、オーディオはこの周波数以下で減衰される
filterNode.frequency.value = 10000;

// Gainノードの生成 (音量の変更)
var gainNode = audioContext.createGain();

// デフォルトは1(変更なし)
// 1未満の場合、音声は減衰され、その逆も同様
gainNode.gain.value = 0.5;

navigator.mediaDevices.getUserMedia({audio: true}, (stream) => {
    // ストリームからのオーディオノードの生成
    const mediaStreamSource =
        audioContext.createMediaStreamSource(stream);
    mediaStreamSource.connect(filterNode);
    filterNode.connect(gainNode);
 
    // Gainノードを宛先に接続(サウンドを再生)
    gainNode.connect(audioContext.destination);
});

Chromiumベースのアプリと拡張機能には、getUserMediaを組み込むこともできます。マニフェストにaudioCaptureおよびvideoCapture権限を追加すると、インストール時に一度だけ権限をリクエストして付与できます。その後、ユーザーはカメラまたはマイクへのアクセスの許可を求められません。

getUserMedia()のアクセス許可は1回だけ付与する必要があります。初めて、ブラウザの情報バーに「許可」ボタンが表示されます。getUserMedia()のHTTPアクセスは、強力な機能として分類されたため、2015年の終わりにChromeで廃止されました。

意図は、カメラやマイクだけでなく、あらゆるストリーミングデータソースに対して「MediaStream」を有効にすることです。これにより、ディスクから、またはセンサーやその他の入力などの任意のデータソースからのストリーミングが可能になります。

getUserMedia()は、他の「JavaScript API」や「ライブラリ」と組み合わせて実際に機能します。

・「Webcam Toy」は、WebGLを使用して、ローカルで共有または保存できる写真に奇妙で素晴らしい効果を追加するフォトブースアプリです。

・「FaceKat」は、「headtrackr.js」で構築された「顔追跡」ゲームです。

・「ASCII Camera」は、Canvas APIを使用してASCIIイメージを生成します。

画像1

7. Constraints

Constraints」を使用して、getUserMedia()のビデオ解像度の値を設定できます。これにより、applyConstraints()とともに、アスペクト比、正面モード(前面カメラまたは背面カメラ)、フレームレート、高さ、幅などを設定できます。

webrtc.github.io/samples/src/content/getusermedia/resolutionにサンプルがあります。

許可されていない「Constraints」を設定すると、「DOMException」または「OverconstrainedError」が発生します。この動作を確認するには、「webrtc.github.io/samples/src/content/getusermedia/resolution」にあるサンプルを試してください。

「Constraints」は、共有リソースの使用可能な構成に影響を与える可能性があります。たとえば、カメラが1つのタブによって640x480モードで開かれた場合、別のタブは1つのモードでしか開くことができないため、「Constraints」を使用して高解像度モードで開くことができません。これは実装の詳細であることに注意してください。2番目のタブで高解像度モードでカメラを再度開き、ビデオ処理を使用して最初のタブのビデオトラックを640x480にダウンスケールすることは可能ですが、これは実装されていません。

8. 画面とタブのキャプチャ

Chromeアプリでは、chrome.tabCaptureおよびchrome.desktopCapture APIを介して、単一のブラウザタブまたはデスクトップ全体のライブ「ビデオ」を共有することもできます。(HTML5 Rocksのアップデート記事にデモと詳しい情報があります。)

このデモのように、実験的なchromeMediaSource Constraintsを使用して、画面キャプチャをChromeのMediaStreamソースとして使用することもできます。画面のキャプチャにはHTTPSが必要であり、このDiscussion-webrtcの投稿で説明されているように、コマンドラインフラグで有効にするため、開発にのみ使用されるべきであることに注意してください。

9. シグナリング

「WebRTC」は「RTCPeerConnection」を使用してブラウザ(ピア)間でストリーミングデータを通信しますが、通信を調整して制御メッセージを送信するメカニズムも必要です。これを「シグナリング」と呼びます。シグナリング方法とプロトコルは「WebRTC」では指定されていません。

「シグナリング」は「RTCPeerConnection API」の一部ではありません。代わりに、WebRTCアプリの開発者は、「SIP」や「XMPP」などの任意のメッセージングプロトコルと、適切な双方向通信チャネルを選択できます。

appr.tc」の例では、シグナリングとして「XHR」および「Channel API」を使用しています。私たちが作った「codelab」は、Nodeサーバ上で動作する「Socket.io」を使用しています。

シグナリングは、3種類の情報を交換するために使用されます。

◎ Session control messages
通信を初期化またはクローズし、エラーを通知。

Network configuration
自分のコンピュータのIPアドレスとポート。

Media capabilities
自分のブラウザとそれが通信したいブラウザで処理できるコーデックと解像度。

P2Pストリーミングを開始するには、「シグナリング」を介した情報の交換が正常に完了している必要があります。

たとえば、AliceがBobと通信したいとします。以下に、「W3C WebRTC仕様」のシグナリングの動作を示すコードサンプルを示します。このコードは、createSignalingChannel()で作成されたいくつかのシグナリングメカニズムの存在を前提としています。また、ChromeとOperaでは、現在RTCPeerConnectionがプレフィックスとして付いていることに注意してください。

// JSON.stringify / parseを処理
const signaling = new SignalingChannel();
const constraints = {audio: true, video: true};
const configuration = {iceServers: [{urls: 'stuns:stun.example.org'}]};
const pc = new RTCPeerConnection(configuration);

// 候補を他の仲間に送る
pc.onicecandidate = ({candidate}) => signaling.send({candidate});

// negotiationneededイベントトリガーが生成を提供
pc.onnegotiationneeded = async () => {
    try {
        await pc.setLocalDescription(await pc.createOffer());

        // オファーを他のピアに送信
        signaling.send({desc: pc.localDescription});
    } catch (err) {
        console.error(err);
    }
};

// リモートトラックメディアが到着したら、リモートビデオ要素を表示
pc.ontrack = (event) => {
    // srcObjectが既に設定されている場合は、再度設定しない
    if (remoteView.srcObject) return;
    remoteView.srcObject = event.streams[0];
};

// start()を呼び出して開始
async function start() {
    try {
        // ローカルストリームを取得し、セルフビューで表示し、送信するように追加
        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 (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);
    }
};

まず、AliceとBobはネットワーク情報を交換します。(「候補を見つける」という表現は、ICEフレームワークを使用してネットワークインターフェイスとポートを見つけるプロセスを指します。)

(1) Aliceは、onicecandidateハンドラを使用してRTCPeerConnectionオブジェクトを作成。
(2) ハンドラは、ネットワーク候補が利用可能になると実行。
(3) Aliceは、シリアル化された候補データをBobに、使用しているシグナリングチャネル(WebSocketまたはその他のメカニズム)を介して送信。
(4) Bobは、Aliceから候補メッセージを受け取ると、addIceCandidateを呼び出して、候補をリモートピアの説明に追加。

WebRTCクライアント(ピア、別名AliceおよびBob)も、解像度やコーデック機能など、ローカルおよびリモートのオーディオおよびビデオメディア情報を確認して交換する必要があります。メディア構成情報を交換するための「シグナリング」は、セッション記述プロトコル(SDP)を使用してオファーとアンサーを交換することにより行われます。

(1) AliceはRTCPeerConnection createOffer()を実行します。 これからの戻りには、RTCSessionDescription(Aliceのローカルセッションの説明)が渡されます。

(2) コールバックでは、AliceはsetLocalDescription()を使用してローカルの説明を設定し、このセッションの説明をシグナリングチャネルを介してBobに送信します。 RTCPeerConnectionは、setLocalDescription()が呼び出されるまで候補の収集を開始しないことに注意してください。これは、「JSEP IETFドラフト」で体系化されています。

(3) Bobは、Aliceがリモートの説明としてsetRemoteDescription()を使用して送信した説明を設定します。

(4) BobはRTCPeerConnection createAnswer()を実行して、Aliceから取得したリモートの説明を渡し、彼女と互換性のあるローカルセッションを生成できます。 createAnswer()コールバックにはRTCSessionDescriptionが渡されます。Bobはそれをローカルの説明として設定し、それをAliceに送信します。

(5) AliceはBobのセッションの説明を取得すると、それをsetRemoteDescriptionを使用してリモートの説明として設定します。

(6) Ping!

「RTCPeerConnection」が不要になったら、close()を呼び出してガベージコレクションできるようにしてください。それ以外の場合、スレッドと接続は維持されます。 「WebRTC」で重いリソースをリークする可能性があります。

「RTCSessionDescription」は、「Session Description Protocol」(SDP)に準拠するblobです。

シリアル化されたSDPオブジェクトは次のようになります。

v=0
o=- 3883943731 1 IN IP4 127.0.0.1
s=
t=0 0
a=group:BUNDLE audio video
m=audio 1 RTP/SAVPF 103 104 0 8 106 105 13 126

// ...

a=ssrc:2223794119 label:H4fjnMzxy3dPIgQ7HxuCTLb4wLLLeRHnFxh810

ネットワークとメディア情報の取得と交換は同時に行うことができますが、
ピア間のオーディオとビデオのストリーミングを開始するには、両方のプロセスが完了している必要があります。

上記のオファー/アンサーアーキテクチャは、JSEP、JavaScript Session Establishment Protocolと呼ばれます(Ericssonの最初のWebRTC実装のデモビデオには、シグナリングとストリーミングのプロセスを説明する優れたアニメーションがあります。)。

画像2

シグナリングプロセスが正常に完了すると、データはP2Pで、呼び出し元と呼び出し先の間で直接ストリーミングできます。失敗した場合は、中継サーバーを介してストリーミングできます(詳細は下記を参照)。
ストリーミングは「RTCPeerConnection」の仕事です。

10. RTCPeerConnection

「RTCPeerConnection」は、ピア間のストリーミングデータの安定した効率的な通信を処理するWebRTCコンポーネントです。以下は、「RTCPeerConnection」の役割を示すWebRTCアーキテクチャ図です。 お気づきのように、緑色のパーツは複雑です。

画像3

JavaScriptの観点から、この図から理解すべき主なことは、「RTCPeerConnection」がWeb開発者をその下に潜む無数の複雑さから保護することです。WebRTCで使用されるコーデックとプロトコルは、信頼性の低いネットワーク上でもリアルタイム通信を可能にするために膨大な作業を行います。

・パケット損失隠蔽
・エコー・キャンセリング
・帯域幅の適応性
・動的ジッタバッファリング
・自動利得制御
・ノイズ低減と抑制
・画像クリーニング

上記のW3Cコードは、シグナリングの観点から見たWebRTCの簡単な例を示しています。以下は、2つの動作するWebRTCアプリケーションのウォークスルーです。最初の例は、「RTCPeerConnection」を示す簡単な例です。2つ目は、完全に機能するビデオチャットクライアントです。

11. サーバーなしのRTCPeerConnection

以下のコードは、「webrtc.github.io/samples/src/content/peerconnection/pc1」にある「単一ページ」のWebRTCデモから取得したもので、1つのWebページにローカルとリモートの「RTCPeerConnection」(およびローカルとリモートのビデオ)があります。これはそれほど有用なものではありません。呼び出し側と呼び出し先は同じページ上にありますが、「RTCPeerConnection API」の動作は少しわかりやすくなります。ページ上の「RTCPeerConnection」は、仲介を使用せずにデータとメッセージを直接交換できるためです。

この例では、pc1はローカルピア(呼び出し元)を表し、pc2はリモートピア(呼び出し先)を表します。

◎ Caller
(1) 新しいRTCPeerConnectionを作成し、getUserMedia()からストリームを追加します。

// サーバーはオプションの構成ファイル(下記のTURNおよびSTUNの説明を参照)
localStream.getTracks().forEach((track) => {
    pc1.addTrack(track, localStream);
});

(2) オファーを作成し、pc1のローカルの説明とpc2のリモートの説明として設定します。
これは、呼び出し元と呼び出し先の両方が同じページにあるため、シグナリングを使用せずにコードで直接実行できます。

pc1.setLocalDescription(desc).then(() => {
        onSetLocalSuccess(pc1);
    },
    onSetSessionDescriptionError
);
trace('pc2 setRemoteDescription start');
pc2.setRemoteDescription(desc).then(() => {
        onSetRemoteSuccess(pc2);
    },
    onSetSessionDescriptionError
);

◎ Callee
(1) pc2を作成し、pc1からのストリームが追加されたら、それをビデオ要素に表示します。

pc2 = new RTCPeerConnection(servers);
pc2.ontrack = gotRemoteStream;

function gotRemoteStream(e){
     vid2.srcObject = e.stream;
}

12. RTCPeerConnectionおよびサーバ

現実の世界では、WebRTCにはサーバが必要ですが、単純であるため、次のことが起こり得ます。

・ユーザーはお互いを発見し、名前などの「実世界」の詳細を交換する。
・WebRTCクライアントアプリケーション(ピア)はネットワーク情報を交換する。
・ピアは、ビデオ形式や解像度などのメディアに関するデータを交換する。
・WebRTCクライアントアプリケーションは、NATゲートウェイとファイアウォールを通過する。

つまり、WebRTCには4種類のサーバー側機能が必要です。

・ユーザーの発見とコミュニケーション。
・シグナリング。
・NAT /ファイアウォールトラバーサル。
・P2P通信が失敗した場合のサーバーのリレー。

NATトラバーサル、P2Pネットワーキング、およびユーザーの発見とシグナリングのためのサーバーアプリを構築するための要件は、この記事の範囲を超えています。「STUN」とその拡張「TURN」が「ICE」フレームワークによって使用され、「RTCPeerConnection」がNATトラバーサルやその他のネットワークの変化に対応できるようになると言うだけで十分です。

「ICE」は、2つのビデオチャットクライアントなど、ピアを接続するためのフレームワークです。最初に、「ICE」は、UDPを介して、可能な限り低いレイテンシでピアを直接接続しようとします。このプロセスでは、STUNサーバーには単一のタスクがあります。NATの背後にあるピアがそのパブリックアドレスとポートを見つけられるようにすることです(STUNとTURNの詳細については、HTML5 Rocksの記事を参照)。

画像4

UDPが失敗した場合、ICEはTCPを試行します。特にエンタープライズNATトラバーサルとファイアウォールが原因で直接接続が失敗した場合、ICEは中間(リレー)TURNサーバーを使用します。言い換えると、ICEは最初にUDPでSTUNを使用してピアを直接接続し、それが失敗した場合、TURNリレーサーバーにフォールバックします。「候補を見つける」という表現は、ネットワークインターフェイスとポートを見つけるプロセスを指します。

画像5

WebRTCエンジニアのJustin Ubertiが、2013年のGoogle I/O WebRTCプレゼンテーションでICE、STUN、およびTURNに関する詳細情報を提供しています(プレゼンテーションスライドは、TURNおよびSTUNサーバーの実装例を示しています)。

13. シンプルなビデオチャットクライアント

STUNサーバーを使用したシグナリングとNAT /ファイアウォールトラバーサルを完備したWebRTCを試すのに適した場所は、「appr.tc」のビデオチャットデモです。このアプリは、シムの「adapter.js」を使用して、仕様の変更やプレフィックスの違いからアプリを隔離します。相互運用の詳細については、「webrtc.org/web-apis/interop」を参照してください。

コードは意図的にログが冗長になっています。コンソールをチェックして、イベントの順序を理解してください。以下に、コードの詳細なウォークスルーを示します。

これをやや不可解に感じる場合は、私たちの「WebRTC codelab」を好むかもしれません。このステップバイステップガイドでは、ノードサーバ上で動作するシンプルなシグナリングサーバを含む、完全なビデオチャットアプリケーションを構築する方法を説明します。

14. ネットワークトポロジー

現在実装されているWebRTCは1対1の通信しかサポートしていませんが、より複雑なネットワークシナリオで使用することもできます。例えば、複数のピアが直接、P2Pで通信したり、マルチポイントコントロールユニット(MCU)を介して、多数の参加者を処理し、選択的なストリーム転送や、オーディオやビデオのミキシングや録画を行うことができるサーバーなどです。

画像6


多くの既存のWebRTCアプリはWebブラウザ間の通信のみを示していますが、ゲートウェイサーバは、ブラウザで実行されているWebRTCアプリがtelephons(別名PSTN)などのデバイスやVOIPシステムとやり取りできるようにします。2012年5月、Doubango TelecomはWebRTCとWebSocketを使用して構築されたsipml5 SIP clientをオープンソースしました。これにより、(他の潜在的な用途の中で)ブラウザとiOSまたはAndroidで実行されているアプリ間のビデオ通話が可能になります。Google I/OでTethrとTropoは、OpenBTSセルを使用してWebRTCを介してフィーチャーフォンとコンピューター間の通信を可能にする、「ブリーフケース内」での災害通信のフレームワークを示しました。 キャリアなしの電話通信です。

画像7

15. RTCDataChannel

オーディオとビデオだけでなく、「WebRTC」は他のタイプのデータのリアルタイム通信をサポートしています。

「RTCDataChannel API」は、低レイテンシと高スループットで、任意のデータのP2P交換を可能にします。
webrtc.github.io/samples/#datachannel」にいくつかの単純な「単一ページ」のデモがあり、「WebRTC codelab」では、単純なファイル転送アプリケーションを構築する方法を示しています。

APIには、次のような多くの使用例があります。

・ゲーム
・リモートデスクトップアプリケーション
・リアルタイムのテキストチャット
・ファイル転送
・分散型ネットワーク

APIには、RTCPeerConnectionを最大限に活用し、強力で柔軟なP2P通信を可能にするいくつかの機能があります。

・RTCPeerConnectionセッションセットアップの活用。
・優先順位付けされた複数の同時チャネル。
・信頼性と信頼性のない配信セマンティクス。
・組み込みのセキュリティ(DTLS)と輻輳制御。
・オーディオまたはビデオの有無にかかわらず使用する機能。

構文は故意にWebSocketに似ており、send()とメッセージイベントを備えています。

const localConnection = new RTCPeerConnection(servers);
const remoteConnection = new RTCPeerConnection(servers);
const sendChannel = localConnection.createDataChannel('sendDataChannel');

// ...

remoteConnection.ondatachannel = (event) => {
    receiveChannel = event.channel;
    receiveChannel.onmessage = onReceiveMessage;
    receiveChannel.onopen = onReceiveChannelStateChange;
    receiveChannel.onclose = onReceiveChannelStateChange;
};

function onReceiveMessage(event) {
    document.querySelector("textarea#send").value = event.data;
}

document.querySelector("button#send").onclick = () => {
    var data = document.querySelector("textarea#send").value;
    sendChannel.send(data);
};

ブラウザ間で直接通信が行われるため、ファイアウォールやNATに対応するための「ホールパンチング」が失敗したときにリレー(TURN)サーバーが必要な場合でも、RTCDataChannelはWebSocketよりもはるかに高速です。

「RTCDataChannel」は「Chrome」「Safari」「Firefox」「Opera」「Samsung Internet」で利用できます。「Cube Slam」は、APIを使用してゲームの状態を伝えます。友達と遊ぶか、クマと遊ぶかです。 革新的なプラットフォームである「Sharefest」はRTCDataChannelを介したファイル共有を可能にし、「peerCDN」はWebRTCがP2Pのコンテンツ配信をどのように可能にするかを垣間見せました。

「RTCDataChannel」の詳細については、IETFのドラフトプロトコル仕様を参照してください。

16. セキュリティ

リアルタイム通信アプリケーションまたはプラグインがセキュリティを危うくするいくつかの方法があります。

・暗号化されていないメディアまたはデータは、ブラウザ間、またはブラウザとサーバーの間で途中で傍受される可能性がある。
・アプリは、ユーザーが知らないうちにビデオまたはオーディオを記録して配信する場合がある。
・マルウェアまたはウイルスは、明らかに無害なプラグインまたはアプリと一緒にインストールされる可能性がある。

「WebRTC」には、これらの問題を回避するためのいくつかの機能があります。

・WebRTC実装は、DTLSSRTPなどの安全なプロトコルを使用。
・暗号化は、シグナリングメカニズムを含むすべてのWebRTCコンポーネントに必須。
・WebRTCはプラグインではない。
そのコンポーネントはブラウザーサンドボックスで実行され、個別のプロセスでは実行されない。
コンポーネントは個別にインストールする必要がなく、ブラウザーが更新されるたびに更新される。
・カメラとマイクへのアクセスは明示的に許可する必要があり、カメラまたはマイクが実行されている場合、これはユーザーインターフェイスによって明確に示される。

ストリーミングメディアのセキュリティに関する完全な議論は、この記事の範囲外です。詳細については、IETFによって提案されたWebRTCセキュリティアーキテクチャを参照してください。

17. おわりに

WebRTCのAPIと標準は、テレフォニー、ゲーム、ビデオ制作、音楽制作、ニュース収集、および他の多くのアプリケーション向けのコンテンツ作成およびコミュニケーションツールを民主化および分散化できます。

テクノロジーはこれよりもはるかに破壊的ではありません。

JavaScriptの開発者がWebRTCを広く実装するようになると、それがWebRTCでどのようになるかを期待しています。ブロガーのフィル・エドホルムが言ったように、「WebRTCとHTML5は、元のブラウザが情報のために行ったのと同じように、リアルタイム通信の変革を可能にする可能性があります。」

18. 開発者ツール

・進行中のセッションのWebRTC統計は、次の場所にあります。

・chrome://webrtc-internals (Chrome)
・opera://webrtc-internals (Opera)
・about:webrtc (Firefox)

画像8

・クロスブラウザのinterop notes
adapter.jsはWebRTCのJavaScriptシムであり、WebRTCコミュニティの助けを借りてGoogleによって維持されており、ベンダープレフィックス、ブラウザの違い、仕様の変更を抽象化している。
・WebRTCシグナリングプロセスの詳細については、コンソールへのappr.tcログ出力を確認
・それが多すぎる場合は、WebRTCフレームワークまたは完全なWebRTCサービスを使用することをお勧めする
・バグレポートと機能のリクエストは常に高く評価されている。

19. もっと詳しく知る

Google I/O 2013でのWebRTCプレゼンテーション(スライドはこちら
Justin UbertiのGoogle I/O 2012でのWebRTCセッション
・Alan B. JohnstonとDaniel C. Burnettは、WebRTCブックを維持しています。現在は、第3版が印刷物および電子ブック形式(webrtcbook.com)で提供されている。
webrtc.orgには、WebRTCのすべてが含まれている(デモ、ドキュメント、ディスカッション)。
webrtc.orgデモページ:デモへのリンク
Discussion-webrtc:技術的なWebRTCディスカッションのためのGoogleグループ
+webrtc
@webrtc
GoogleデベロッパーのGoogleトークのドキュメント。NATトラバーサル、STUN、リレーサーバー、候補者収集に関する詳細情報が記載されています。
GitHubのWebRTC
Stack Overflowは、WebRTCに関する回答を探したり質問したりするのに適した場所です

20. 規格とプロトコル

The WebRTC W3C Editor's Draft
W3C Editor's Draft: Media Capture and Streams (aka getUserMedia)
IETF Working Group Charter
IETF WebRTC Data Channel Protocol Draft
IETF JSEP Draft
IETF proposed standard for ICE
・IETF RTCWEB Working Group Internet-Draft: Web Real-Time Communication Use-cases and Requirements

21. WebRTCサポートサマリー

◎ MediaStream and getUserMedia
・Chrome desktop 18.0.1008+; Chrome for Android 29+
・Opera 18+; Opera for Android 20+
・Opera 12, Opera Mobile 12 (based on the Presto engine)
・Firefox 17+
・Microsoft Edge 16+
・Safari 11.2+ on iOS; 11.1+ on Mac
・UC 11.8+ on Android
・Samsung Internet 4+

◎ RTCPeerConnection
・Chrome desktop 20+; Chrome for Android 29+ (flagless)
・Opera 18+ (on by default); Opera for Android 20+ (on by default)
・Firefox 22+ (on by default)
・Microsoft Edge 16+
・Safari 11.2+ on iOS; 11.1+ on Mac
・Samsung Internet 4+

◎ RTCDataChannel
・Experimental version in Chrome 25, more stable (and with Firefox interoperability) in Chrome 26+; Chrome for Android 29+
・Stable version (and with Firefox interoperability) in Opera 18+; Opera for Android 20+
・Firefox 22+ (on by default)

getUserMediaやRTCPeerConnectionなどのAPIのクロスプラットフォームサポートの詳細については、caniuse.comおよびchromestatus.comを参照してください。RTCPeerConnectionのネイティブAPIも利用可能です:webrtc.orgのドキュメント


この記事が気に入ったらサポートをしてみませんか?