ハロー Chrome, こちら Firefox です!

原文: Hello Chrome, it’s Firefox calling! on February 4, 2013 by Maire Reavy and Robert Nyman [Editor]

Mozilla は WebRTC の開発において大きなマイルストーンに到達したことに興奮しています。Firefox と Chrome 間での RTCPeerConnection の相互運用に成功したのです。この取り組みが成し遂げられたのは、オープン Web コミュニティと Mozilla, Google の密な協調の成果です。

RTCPeerConnection (PeerConnection や PC と略されます) の相互運用性の確保により、サードパーティ製プラグインをインストールすることなく、Firefox の WebRTC アプリケーションと Chrome の WebRTC アプリケーション間で、音声・ビデオ発信が直接行えます。この機能がブラウザに搭載されたことにより、ユーザーは初めてのプラグインインストールに戸惑ったり、バグに悩まされることがありません。また開発者も自身のアプリを簡単に、そして幅広い対象に公開できます。

この大きなマイルストーン到達を祝うにあたり 、私たちは Google の友人と WebRTC で会話すると楽しいのではないかと考えました。次のビデオは、Mozilla の Chief Innovation Officer である Todd Simpson と、Google の Director of Product Management である Hugh Finnan による、Firefox―Chrome 間のデモンストレーションコールです。

Google もこの大きなニュースについて彼らのブログで取り上げています。そちらもご覧ください。

このマイルストーンは、昨年末に紹介した WebRTC と Social API のデモの上にできています。昨年末のポストでは、DetaChannel という WebRTC の強力なコンポーネントを業界初で実装したことを報告しました。DataChannel と音声/ビデオチャットを組み合わせることで、ユーザーは自分のコンピューターもしくはデバイス上のほとんどすべてを共有できます。旅行の写真、メモリアルなビデオ、ニュースのリンクなどをビデオチャットのウインドウ上にドラッグ&ドロップするだけで相手に送れるのです。

WebRTC は W3C と IETF という2つの標準化団体が共同で策定中のオープン標準で、すべてのデバイスに音声/ビデオのリアルタイム通信を行う共通プラットフォームを提供することを目的としています。これは相互運用性と、Web で真にオープンなリアルタイム通信の実現への第一歩です。

Posted by:
Serge Lachapelle, Chrome Product Manager and Maire Reavy, Firefox Media Product Lead

Firefox で RTCPeerConnection を使う

まだ RTCPeerConnection を Firefox で試していない JavaScript 開発者の方は、最新の Firefox Nightly で media.peerconnection.enabled の設定を “true” にすることで RTCPeerConnection を利用できます (pref の設定は about:config にアクセスして検索してください)。以下は Firefox で RTCPeerConnection を利用し、WebRTC コールの開始、受け取り、終了を行うサンプルアプリのコードです。

function initiateCall(user) {
  document.getElementById("main").style.display = "none";
  document.getElementById("call").style.display = "block";

  // Here's where you ask user permission to access the camera and microphone streams
  navigator.mozGetUserMedia({video:true, audio:true}, function(stream) {
    document.getElementById("localvideo").mozSrcObject = stream;
    document.getElementById("localvideo").play();
    document.getElementById("localvideo").muted = true;

    // Here's where you set up a Firefox PeerConnection
    var pc = new mozRTCPeerConnection();
    pc.addStream(stream);

    pc.onaddstream = function(obj) {
      log("Got onaddstream of type " + obj.type);
      document.getElementById("remotevideo").mozSrcObject = obj.stream;
      document.getElementById("remotevideo").play();
      document.getElementById("dialing").style.display = "none";
      document.getElementById("hangup").style.display = "block";
    };

    pc.createOffer(function(offer) {
      log("Created offer" + JSON.stringify(offer));
      pc.setLocalDescription(offer, function() {
        // Send offer to remote end.
        log("setLocalDescription, sending to remote");
        peerc = pc;
        jQuery.post(
          "offer", {
            to: user,
            from: document.getElementById("user").innerHTML,
            offer: JSON.stringify(offer)
          },
          function() { console.log("Offer sent!"); }
        ).error(error);
      }, error);
    }, error);
  }, error);
}

function acceptCall(offer) {
  log("Incoming call with offer " + offer);
  document.getElementById("main").style.display = "none";
  document.getElementById("call").style.display = "block";

  // Here's where you ask user permission to access the camera and microphone streams
  navigator.mozGetUserMedia({video:true, audio:true}, function(stream) {
    document.getElementById("localvideo").mozSrcObject = stream;
    document.getElementById("localvideo").play();
    document.getElementById("localvideo").muted = true;

    // Here's where you set up a Firefox PeerConnection
    var pc = new mozRTCPeerConnection();
    pc.addStream(stream);

    pc.onaddstream = function(obj) {
      document.getElementById("remotevideo").mozSrcObject = obj.stream;
      document.getElementById("remotevideo").play();
      document.getElementById("dialing").style.display = "none";
      document.getElementById("hangup").style.display = "block";
    };

    pc.setRemoteDescription(JSON.parse(offer.offer), function() {
      log("setRemoteDescription, creating answer");
      pc.createAnswer(function(answer) {
        pc.setLocalDescription(answer, function() {
          // Send answer to remote end.
          log("created Answer and setLocalDescription " + JSON.stringify(answer));
          peerc = pc;
          jQuery.post(
            "answer", {
              to: offer.from,
              from: offer.to,
              answer: JSON.stringify(answer)
            },
            function() { console.log("Answer sent!"); }
          ).error(error);
        }, error);
      }, error);
    }, error);
  }, error);
}

function endCall() {
  log("Ending call");
  document.getElementById("call").style.display = "none";
  document.getElementById("main").style.display = "block";

  document.getElementById("localvideo").mozSrcObject.stop();
  document.getElementById("localvideo").mozSrcObject = null;
  document.getElementById("remotevideo").mozSrcObject = null;

  peerc.close();
  peerc = null;
}

標準化団体がまだ策定を終えていないため、Firefox ではまだ RTCPeerConnection API を mozRTCPeerConnection と接頭辞をつけコールしています。Chrome も webkitRTCPeerConnection と接頭辞をつけています。標準化が終了したら、接頭辞を省き同じ API を利用できますが、それまでの間は Firefox, Chrome どちらでも動くことのできるよう、どちらの接頭辞もサポートしてください。

試してみよう

Firefox―Chrome 間の通信を試したい方は、試す手順を記したページをご覧ください。

Firefox と Chrome 間の PeerConnection の相互運用性はまだ初期段階です。初期段階のリリースにはバグがつきものですし、まだすべてのネットワーク環境での相互運用性が担保されていません。しかし、この新しい Web の機能、そして Web そのものにとって、今回の出来事は大きな一歩なのです。私たちは標準化団体ならびに WebRTC コミュニティの貢献者すべてに感謝します。まだまだやる事はたくさんありますが、Web がもっと素晴らしいものになることに皆さんが同意してくれると期待しています。