はじめに
こんにちは! 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 サーバーに以下のサンプルコードを作成し、試してみましょう!
<!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
シングルサーバーサンプルコードを作成
"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というサービスもありますので、参考までに・・