WebRTC による画面共有

先週報告したように、最近、長年の友である WebRTC に多くの動きがありました。

さて、WebRTC 画面共有も初めての機能です。

WebRTC 画面共有拡張機能のスクリーンショット。Jake Archibald、Peter Beverloo、Paul Lewis、Sam Dutton が映っている

スクリーンキャスト: youtube.com/watch?v=tD0QtBUZsF4

コードはこちら: github.com/samdutton/rtcshare

基本的には、RTCPeerConnection と chrome.tabCapture を使用してブラウザタブのライブ「動画」を共有する試験運用版の Chrome 拡張機能を作成しました。この機能を試すには、Chrome Canary が必要です。また、about:flags ページで試験運用版の拡張機能 API を有効にする必要があります。

このプロトタイプは、強力な appr.tc デモに大きく依存しており、率直に言って、少しハックです。ただし、これは概念実証であり、機能します。

その方法をご紹介します。

  1. ユーザーが拡張機能アイコン(アドレスバーの横にある「録画ボタン」)をクリックすると、拡張機能のバックグラウンド スクリプト background.js が、src が rtcshare.appspot.com である iframe を自身に追加します。background.js では、token や room_key などの値を取得するためにのみ使用されます。これはハックです :^}! これは apprtc.appspot.com の短縮版です。apprtc の例と同様に、rtcshare.appspot.com もリモート クライアントに使用されます。
chrome.browserAction.onClicked.addListener(function(tab) {
    var currentMode = localStorage["capturing"];
    var newMode = currentMode === "on" ? "off" : "on";

    if (newMode === "on"){ // start capture
        appendIframe();
    } else { // stop capture
        chrome.tabs.getSelected(null, function(tab){
            localStream.stop();
            onRemoteHangup();
        });
        // set icon, localStorage, etc.
    }
}
  1. iframe が読み込まれると、background.js がそこから値を取得し(rtcshare.appspot.com アプリによって生成)、chrome.tabCapture.capture() を呼び出して現在のタブのライブ配信のキャプチャを開始します。
function appendIframe(){
    iframe = document.createElement("iframe");
    iframe.src="https://rtcshare.appspot.com";
    document.body.appendChild(iframe);
    iframe.onload = function(){
        iframe.contentWindow.postMessage("sendConfig", "*");
    };
}

// serialised config object messaged by iframe when it loads

window.addEventListener("message", function(event) {
    if (event.origin !== "https://rtcshare.appspot.com"){
        return;
    }
    var config = JSON.parse(event.data);
    room_link = config.room_link; // the remote peer URL
    token = config.token; // for messaging via Channel API
    // more parameter set from config
);

function startCapture(){
    chrome.tabs.getSelected(null, function(tab) {
        var selectedTabId = tab.id;
        chrome.tabCapture.capture({audio:true, video:true}, handleCapture); // bingo!
    });
}
  1. ライブ ストリームが利用可能になると(つまり、現在のタブのライブ「動画」)、background.js がピア接続プロセスを開始し、シグナリングは XHR と Google の Channel API を使用して rtcshare.appspot.com 経由で行われます。全体として、apprtc デモと同様に動作しますが、リモート ピアに送信される動画ストリームは getUserMedia() ではなく chrome.tabCapture からです。
function handleCapture(stream){
    localStream = stream; // used by RTCPeerConnection addStream();
    initialize(); // start signalling and peer connection process
}
  1. デモ用に、このプロトタイプ拡張機能は rtcshare.appspot.com から提供された URL を含む新しいタブを開きます。この URL には「ルーム番号」のクエリ文字列が追加されています。もちろん、この URL は別のパソコンや別の場所で開くこともできます。それが、有用な何かの始まりになるかもしれません。
chrome.tabs.create({url: room_link});

画面共有には多くの興味深いユースケースが想定されます。開発の初期段階ではありますが、プラグインなしのタブのキャプチャと共有が、これほどレスポンスがよく安定していることに驚いています。

この拡張機能や WebRTC API 全般について、ご意見をお待ちしております。WebRTC について詳しくは、HTML5 Rocks の記事またはクイック スタートガイドをご覧ください。

HTML5R と WebRTC のメンバー一同、皆様の 2013 年のご活躍をお祈り申し上げます。