lighthouse.log

lighthouse.log

WebRTCでビデオチャットアプリを作ってみた!

2017-12-25

はじめに

こんにちは! Fusic Advent Calendar 2017 21 日目の記事です。 →Qiita の記事はこちら

WebRTCを触ってみた話をさせていただきます。

WebRTC とは

WebRTC(Web Real-Time Communication)は、ウェブブラウザーの間で特定のプラグインがなくても通信できる API です。

W3Cで提示された草案であり、

映像、音声、P2P ファイル共有などで活用できます。

WebRTC API

WebRTC で提供する API は以下の三つです!

1. MediaStream

ユーザー端末機のビデオ、マイクにアクセスできます。

getUserMediaを使ってアクセスし、MedisStream オブジェクトをPeerConnectionに渡して転送することになります。

2. PeerConnection

一番重要な API であり、ブラウザ間でビデオ、音声などのやりとりする API です!

3. DataChannel

ブラウザ間でのテキストやファイルなどをやりとりします。

事前準備

  • Web サーバー
  • Node.js
  • WebSocket

カメラを触ってみよう

Web サーバーに以下のサンプルコードを作成し、試してみましょう!

sample.html
<!doctype html>
<html>
  <head>
    <title>Self Camera</title>
  </head>
  <body>
    <video id="myVideo" width="400" height="300" autoplay="1" ></video>

    <script type="text/javascript">
      navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || window.navigator.mozGetUserMedia;
      window.URL = window.URL || window.webkitURL;

      var video = document.getElementById('myVideo');
      var localStream = null;
      navigator.getUserMedia({video: true, audio: false},
      function(stream) { // for success case
        console.log(stream);
        video.src = window.URL.createObjectURL(stream);
      },
      function(err) { // for error case
        console.log(err);
      }
      );
    </script>
  </body>
</html>

最初ブラウザーからアクセスすると、カメラにアクセスしてもいいかどうかの確認ダイアログが表示されるので、

OK ボタンを押して許可してください。

シグナリングサーバーを動かす

WebRTC の通信について

WebRTC では、映像や音声などリアルタイムに取得されたデータを、ブラウザ間で送受信することができます。 それを司るのが  RTCPeerConnection です。 RTCPeerConnection には 2 つの特徴があります。

  • Peer-to-Peer(P2P)の通信 → ブラウザとブラウザの間で直接通信する
  • UDP/IP を使用 → TCP/IP のようにパケットの到着は保障しないが、オーバーヘッドが少ない(らしい)

P2P 通信を行うために

ブラウザ間で P2P 通信を行うには、

  • 相手の IP アドレス
  • 動的に割り振られる UDP のポート番号

を知る必要があります。

そのために、WebRTC では以下の情報をやり取りしています。

SDP (Session Description Protocol)

  • セッションが含むメディアの種類(音声、映像)、
  • メディアの形式(コーデック)
  • IP アドレス、ポート番号 などなど

ICE (Interactive Connectivity Establishment)

  • P2P による直接通信
  • NAT を通過するための STUN サーバーから取得したポートマッピング → 最終的には P2P になる
  • Firefall を越えるための、TURN によるリレーサーバーを介した中継通信

ということでシグナリングサーバーを動かしてみよう!

P2P を始めるまでの情報のやり取りを「シグナリング」と言います。

シグナリングサーバーは、クライアントからメッセージを受け取ったら他のクライアントに送信する役割をします。

WebSocket をのインストール

npm install ws

シングルサーバーサンプルコードを作成

signaling.js
"use strict";

let WebSocketServer = require('ws').Server;
let port = 9000; //ポート番号は必要に応じて変更してください。
let wsServer = new WebSocketServer({ port: port });
console.log('websocket server start. port=' + port);

wsServer.on('connection', function(ws) {
  console.log('-- websocket connected --');
  ws.on('message', function(message) {
    wsServer.clients.forEach(function each(client) {
      if (isSame(ws, client)) {
        console.log('- skip sender -');
      }
      else {
        client.send(message);
      }
    });
  });
});

function isSame(ws1, ws2) {
  // -- compare object --
  return (ws1 === ws2);
}

シングルサーバーを起動

node signaling.js

シグナリングサーバーの動作はシンプルで、クライアントからメッセージを受け取ったら他のクライアントに送信するだけです。

実際に動かしてみよう!(結果)

ブラウザーからアクセスし、スクリプトを読み込むと

image 1

image 2

こんな感じです!

最後に

何よりもFusic 開発合宿で普段から自分が作りたかったものや

新しい技術を勉強できて、とても楽しめたと思います!

まだまだいけてないところや課題もたくさんあるんですが、引き続き勉強しつつ発展させていきたいと思います!!

参考

  • WebRTC 入門 2016 大変参考になりました!!
  • あと、SkyWayというサービスもありますので、参考までに・・