WebRTCを簡単に利用するためのプラットフォームSkyWayをご存知ですか?本連載では、WebRTCを簡単に利用するためのプラットフォームSkyWayについて、基本的なチュートリアルから、各種ライブラリの紹介までしていきます。
連載第1回目である今回は、まず、WebRTCの基本的な説明をした後に、実際にSkyWayを使って、ビデオチャットの作成とデータチャンネルを使ったチャットの作成をしていきます。
WebRTCとは
WebRTCとは、ブラウザやアプリ間でビデオや音声、データのやり取りをP2P(Peer to Peer)で行うことを可能にする規格です。 従来のビデオチャットは互換性のない独自技術で実装されていましたが、WebRTCはオープン標準として仕様が作成・公開されており、相互接続が保証されています。
また、ブラウザで動作することから特別なアプリケーションをインストールする必要がありませんし、すでにあるウェブアプリケーションに埋め込むことで、シームレスにビデオチャットを動かすこともできます。さらに、オープンソースのコードを利用することで、ブラウザだけに限らず、ネイティブアプリにWebRTCを組み込むことも可能です。
WebRTCの仕組み
WebRTCはビデオ等のデータをP2Pでやり取りすることが出来ますが、実際にブラウザ間で直接接続をするためには、まず、互いに自分のIPアドレス/ポート番号等の情報を教え合わなければなりません。一般的に、この情報交換を行うためにシグナリングサーバというサーバを用意する必要があります。
また、お互いがNATの内側に存在する場合やFirewallの内側にいる場合、シグナリングサーバだけでは接続することができません。そのために利用するのが、STUN/TURNサーバです。ここでは具体的な説明は省略しますが、作成したアプリケーションをユーザに広く使ってもらうためには、これらのサーバも用意する必要があります。
(詳細を知りたい方は、がねこまさしさんが書かれたコチラの記事をお読みください: 壁を越えろ!WebRTCでNAT/Firewallを越えて通信しよう)
SkyWayとは
今までの説明を見てWebRTCは「大変そうだ」と思った方は多いと思います。実際、シグナリングサーバやSTUN/TURNサーバを用意するのは容易ではないです。
そこで登場するのがWebRTC開発者向けプラットフォーム「SkyWay」です。SkyWayは、以下の図で示す通り、複雑なシグナリング処理を担うAPI郡とJavascriptライブラリ/Android,iOSライブラリ、STUN/TURNサーバで構成されています。
このSkyWayを利用することで、シグナリングサーバやSTUN/TURNサーバを独自に用意する必要はなく、開発者はP2P通信部分のプログラミングにのみ集中することができます。
利用者登録が必要です
SkyWayは現在トライアルサービス中で、誰でも無料で使うことができます。さっそくウェブサイトから利用者登録をしてみましょう。
「登録を行う」ボタンをクリックして、開発者登録画面に向かいます。
必要事項を入力します。ここで入力するドメイン名は、セキュリティ向上を目的として行っているOriginチェックのために必要となっています。ここのドメイン名は開発者登録後に変更可能ですので、まずは「localhost」とだけ入力しておいてください。
登録が正常に完了したら、ログインページへ行き、ログインしてください。ログインが完了すると以下の画面のような開発者ダッシュボードが表示されます。
右に表示されいるのがAPIキーです(上図ではマスクしています)。こちらをJavaScriptやiOS/Androidのコード内に埋め込み、SkyWayのAPIにアクセスします。
ちなみに、設定変更ボタンをクリックすると、利用ドメインの編集やRestAPIの有効無効の切り替え、そしてAPIキーの削除が可能です。
これでSkyWayを利用するための準備が整いました。早速ビデオチャットを実装してみましょう。
簡易ビデオチャットの作成と実行
まず、ビデオチャットを実装するにあたり、以下の環境をご用意ください。
- Chorme, Firefox, Operaのいずれかのブラウザ
- カメラ/マイク (PCに接続可能なもの)
まずは以下の内容で、HTMLを書きます。適当なフォルダに「videochat.html」というファイル名でHTMLファイルを作成してください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<html> <head> <script type="text/javascript" src="https://code.jquery.com/jquery-1.11.3.min.js"></script> <script type="text/javascript" src="https://skyway.io/dist/v2/0.3/peer.js"></script> <script type="text/javascript" src="videochat.js"></script> </head> <body> <h1>Simple Video Chat</h1> <div> <video id="my-video" style="width: 300px;" autoplay></video> <video id="peer-video" style="width: 300px;" autoplay></video> </div> <div> <p>MyID: <span id="my-id">-</span></p> <p>PeerID: <span id="peer-id">-</span></p> </div> <div> <input type="text" placeholder="PeerID" id="peer-id-input"> <button id="call-start">Start Call</button> <button id="call-end">End Call</button> </div> </body> </html> |
HEADタグ内で、jQueryとSkyWayライブラリ、そして今回作成するビデオチャット用のJavaScriptを読み込んでいます。jQueryはボタンクリック時のイベントを設定するときに使用します。SkyWayライブラリは今まで説明してきたとおり、シグナリング部分の処理を全部行ってくれるライブラリです。
次にJavaScriptのコードを書きます。先ほどのHTMLと同じフォルダに、「videochat.js」というファイル名でJavaScriptのファイルを作成してください。ここで、APIキーは先ほど入手したものに置き変えて入力してください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
// カメラ/マイクにアクセスするためのメソッドを取得しておく navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia; var localStream; // 自分の映像ストリームを保存しておく変数 var connectedCall; // 接続したコールを保存しておく変数 // SkyWayのシグナリングサーバーへ接続する (APIキーを置き換える必要あり) var peer = new Peer({ key: 'YourApiKey', debug: 3}); // シグナリングサーバへの接続が確立したときに、このopenイベントが呼ばれる peer.on('open', function(){ // 自分のIDを表示する // - 自分のIDはpeerオブジェクトのidプロパティに存在する // - 相手はこのIDを指定することで、通話を開始することができる $('#my-id').text(peer.id); }); // 相手からビデオ通話がかかってきた場合、このcallイベントが呼ばれる // - 渡されるcallオブジェクトを操作することで、ビデオ映像を送受信できる peer.on('call', function(call){ // 切断時に利用するため、コールオブジェクトを保存しておく connectedCall = call; // 相手のIDを表示する // - 相手のIDはCallオブジェクトのpeerプロパティに存在する $("#peer-id").text(call.peer); // 自分の映像ストリームを相手に渡す // - getUserMediaで取得したストリームオブジェクトを指定する call.answer(localStream); // 相手のストリームが渡された場合、このstreamイベントが呼ばれる // - 渡されるstreamオブジェクトは相手の映像についてのストリームオブジェクト call.on('stream', function(stream){ // 映像ストリームオブジェクトをURLに変換する // - video要素に表示できる形にするため変換している var url = URL.createObjectURL(stream); // video要素のsrcに設定することで、映像を表示する $('#peer-video').prop('src', url); }); }); // DOM要素の構築が終わった場合に呼ばれるイベント // - DOM要素に結びつく設定はこの中で行なう $(function() { // カメラ/マイクのストリームを取得する // - 取得が完了したら、第二引数のFunctionが呼ばれる。呼び出し時の引数は自身の映像ストリーム // - 取得に失敗した場合、第三引数のFunctionが呼ばれる navigator.getUserMedia({audio: true, video: true}, function(stream){ // このストリームを通話がかかってき場合と、通話をかける場合に利用するため、保存しておく localStream = stream; // 映像ストリームオブジェクトをURLに変換する // - video要素に表示できる形にするため変換している var url = URL.createObjectURL(stream); // video要素のsrcに設定することで、映像を表示する $('#my-video').prop('src', url); }, function() { alert("Error!"); }); // Start Callボタンクリック時の動作 $('#call-start').click(function(){ // 接続先のIDをフォームから取得する var peer_id = $('#peer-id-input').val(); // 相手と通話を開始して、自分のストリームを渡す var call = peer.call(peer_id, localStream); // 相手のストリームが渡された場合、このstreamイベントが呼ばれる // - 渡されるstreamオブジェクトは相手の映像についてのストリームオブジェクト call.on('stream', function(stream){ // 相手のIDを表示する $("#peer-id").text(call.peer); // 映像ストリームオブジェクトをURLに変換する // - video要素に表示できる形にするため変換している var url = URL.createObjectURL(stream); // video要素のsrcに設定することで、映像を表示する $('#peer-video').prop('src', url); }); }); // End Callボタンクリック時の動作 $('#call-end').click(function(){ // ビデオ通話を終了する connectedCall.close(); }); }); |
これらはローカルのファイルとして開いても動作しません。ローカルPC上にサーバを立ててファイルをホスティングしてあげる必要があります。このためだけにローカルPCにApacheやNginxを入れるのもの大変なので、今回はPHP付属のビルトインサーバを利用します。 ターミナルを開いて次のコマンドを入力してください (要PHP5.4.0以上)
1 2 |
$ cd {HTML/Javascriptのあるフォルダ} $ php -S localhost:8888 |
これで準備が全て整いました。早速ブラウザで開いてみましょう。WebRTCは現在のところChrome, Firefox, Operaでしか動作しないため、それらのブラウザを利用する必要があります。また現在も開発が続けられている分野ですので、最新バージョンを利用するのが望ましいです。
今回は、ビデオ通話を開始する側と受ける側の両方を自分で試してみます。ですので、以下のURLを2つのウィンドウ(またはタブ)で開いてみてください。
http://localhost:8888/videochat.html
無事に表示されたでしょうか?
アクセス時に、カメラとマイクへのアクセスについて許可を求められるので、許可しておきましょう。許可すると、カメラ映像が画面左に表示されます。
それでは、早速通話を開始してみたいと思います。まず、接続相手のIDを渡す必要があります。ビデオ通話を受ける側のIDをコピーして、かける側のテキストボックスに貼り付けてください。相手のIDをちゃんと貼り付けることができたなら、隣の「Start Call」を押します。
2つの映像が表示されれば成功です。
以上が簡単なビデオチャットのチュートリアルでした。非同期処理が中心でかつ、通話を開始する側と受ける側の両方の処理を書く必要があるため、慣れるまでコードの理解が難しいですが、ここさえ乗り越えればスムーズにコードを書くことができますので、少しづつ理解してみてください。
データ通信を使った文字ベースチャット
続いてWebRTCを用いたデータ通信を使ったチャットアプリを作ってみたいと思います。既にビデオチャットを理解できていれば、全く難しいことはありません。
先ほどと同様に、以下の内容で、HTMLを書きます。適当なフォルダに「datachat.html」というファイル名でHTMLファイルを作成してください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
<html> <head> <script type="text/javascript" src="https://code.jquery.com/jquery-1.11.3.min.js"></script> <script type="text/javascript" src="https://skyway.io/dist/v2/0.3/peer.js"></script> <script type="text/javascript" src="datachat.js"></script> </head> <body> <h1>Chat</h1> <div> <input type="text" placeholder="PeerID" id="peer-id-input"> <button id="connect">Connect</button> <button id="close">Close</button> </div> <div> <p>MyID: <span id="my-id">-</span></p> <p>PeerID: <span id="peer-id">-</span></p> </div> <hr> <div> <input type="text" placeholder="Chat Message" id="message"> <button id="send">Send</button> </div> <div id="messages"></div> </body> </html> |
次はJavaScriptです。先ほどのHTMLと同じフォルダに「datachat.js」というファイル名でJavaScriptのファイルを作成してください。 APIキーについてもビデオ通話と同様に、先ほど入手したものに置き変えてください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
var conn; // データ通信用connectionオブジェクトの保存用変数 // SkyWayのシグナリングサーバーへ接続する (APIキーを置き換える必要あり) var peer = new Peer({ key: 'YourApiKey', debug: 3}); // シグナリングサーバへの接続が確立したときに、このopenイベントが呼ばれる peer.on('open', function(){ // 自分のIDを表示する // - 自分のIDはpeerオブジェクトのidプロパティに存在する // - 相手はこのIDを指定することで、通信を開始することが出来る $('#my-id').text(peer.id); }); // 相手からデータ通信の接続要求イベントが来た場合、このconnectionイベントが呼ばれる // - 渡されるconnectionオブジェクトを操作することで、データ通信が可能 peer.on('connection', function(connection){ // データ通信用に connectionオブジェクトを保存しておく conn = connection; // 接続が完了した場合のイベントの設定 conn.on("open", function() { // 相手のIDを表示する // - 相手のIDはconnectionオブジェクトのidプロパティに存在する $("#peer-id").text(conn.id); }); // メッセージ受信イベントの設定 conn.on("data", onRecvMessage); }); // メッセージ受信イベントの設定 function onRecvMessage(data) { // 画面に受信したメッセージを表示 $("#messages").append($("<p>").text(conn.id + ": " + data).css("font-weight", "bold")); } // DOM要素の構築が終わった場合に呼ばれるイベント // - DOM要素に結びつく設定はこの中で行なう $(function() { // Connectボタンクリック時の動作 $("#connect").click(function() { // 接続先のIDをフォームから取得する var peer_id = $('#peer-id-input').val(); // 相手への接続を開始する conn = peer.connect(peer_id); // 接続が完了した場合のイベントの設定 conn.on("open", function() { // 相手のIDを表示する // - 相手のIDはconnectionオブジェクトのidプロパティに存在する $("#peer-id").text(conn.id); }); // メッセージ受信イベントの設定 conn.on("data", onRecvMessage); }); // Sendボタンクリック時の動作 $("#send").click(function() { // 送信テキストの取得 var message = $("#message").val(); // 送信 conn.send(message); // 自分の画面に表示 $("#messages").append($("<p>").html(peer.id + ": " + message)); // 送信テキストボックスをクリア $("#message").val(""); }); // Closeボタンクリック時の動作 $("#close").click(function() { conn.close(); }); }); |
では、ローカルにHTTPサーバを立てて開いてみましょう。
1 2 |
$ cd {HTML/Javascriptのあるフォルダ} $ php -S localhost:8888 |
http://localhost:8888/datachat.html
先程と同様に、接続を開始する側と接続を受ける側の両方が必要なため、2つ開いてください。無事に表示されましたでしょうか?
それでは、データ通信を開始してみたいと思います。接続相手のIDをコピーして、接続を開始する側のテキストボックスに貼り付けて、Connectボタンを押してください。
相手のIDがお互いの画面に表示されれば接続できています。では、チャット欄に文字を入力してSendボタンを押してみましょう。 相手の画面と自分の画面、両方に表示されれば成功です。
以上が簡単なテキストチャットのチュートリアルでした。WebRTCを使えば、テキストだけじゃなく、JavaScriptのオブジェクトやファイル等も送ることが可能です。
おわりに
今回はSkyWayを使った、簡単なビデオチャット/文字ベースチャットのチュートリアルをお届けしました。WebRTCは便利で高機能な反面、自分で実装しようとすると大変ですが、SkyWayを使うことで手軽に利用可能です。
次回はSkyWayを使って、Android/iPhoneでWebRTCを簡単に使う方法をお伝えしたいと思います。