Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

こんにちは!
Fusic Advent Calendar 2017 21日目の記事です。
WebRTCを触ってみた話をさせていただきます。

WebRTCとは

WebRTC(Web Real-Time Communication)は、ウェブブラウザーの間で特定のプラグインがなくても通信できるAPIです。
W3Cで提示された草案であり、映像、音声、P2Pファイル共有などで活用できます。

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

①MediaStream

ユーザー端末機のビデオ、マイクにアクセスできます。
getUserMediaを使ってアクセスし、MedisStreamオブジェクトをPeerConnectionに渡して転送することになります。

②PeerConnection

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

③DataChannel

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

事前準備

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

カメラを触ってみよう

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

※ 2019.1.6 追記
Chrome68以降でURL.createObjectURLが使えなくなったらしいので、
srcObjectプロパティを使うように修正しました! (コード内にコメントを書いてますので、ご確認ください)

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;

      let video = document.getElementById('myVideo');
      let localStream = null;
      navigator.getUserMedia({video: true, audio: false}, 
        function(stream) { // for success case
          console.log(stream);
          /* video.src = window.URL.createObjectURL(stream); 
             Chrome68以降で URL.createObjectURL が使えなくなったらしいので、
             以下のsrcObjectプロパティを使うように修正 */
          video.srcObject = 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

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

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

こんな感じです!

最後に

何よりもFusic開発合宿で普段から自分が作りたかったものや
新しい技術を勉強できて、とても楽しめたと思います!

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

参考リンク

  • WebRTC入門2016 大変参考になりました!!
  • あと、SkyWayというサービスもありますので、参考までに・・
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした