WebRTC による画面共有

先週お伝えしたとおり、最近、WebRTC についてたくさんの出来事が発生しています。

1 つ目の機能、WebRTC 画面共有。

Jake Archibald、Peter Beverloo、Paul Lewis、Sam Dutton が出演する WebRTC 画面共有拡張機能のスクリーンショット

スクリーンキャストは youtube.com/watch?v=tD0QtBUZsF4 です。

コードは github.com/samdutton/rtcshare です。

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

このプロトタイプは強力な appr.tc デモに大きく依存していますが、正直なところ、ちょっとしたハッキングです。しかし...これは概念実証であり、機能します。

方法は次のとおりです。

  1. ユーザーが拡張機能アイコン(アドレスバーの横にある記録ボタン)をクリックすると、拡張機能のバックグラウンド スクリプト background.js がそれ自体に iframe を追加します。その srcrtcshare.appspot.com になります。background.js では、tokenroom_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 は iframe から値(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 を別のパソコンや別の場所で開けることもあるでしょう。その場合は、何か便利なことのきっかけになるかもしれません。
chrome.tabs.create({url: room_link});

画面共有には興味深いユースケースが数多くありますが、この開発の初期段階ですら、プラグインなしでタブをキャプチャして共有するための応答性と安定性に感銘を受けています。

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

それでは、2013 年の成功を心よりお祈り申し上げます。