リアルタイム通信して複数デバイス上で音声を再生する(Node.js + Socket.IO + Web Audio API) (Japanese)
双方向(リアルタイム)通信して、複数デバイス上で音声を再生するサンプルを作り、Herokuにデプロイしました。 実現するための方法を解説していきます。
※ドラム音源を再生するサンプルに、リアルタイム通信機能を追加したものです。
サンプル(Heroku)
https://nodejs-socketio-webaudio.herokuapp.com/
※ドラムを叩いて複数デバイスでリアルタイム通信して音声を再生。
ソースコード
https://github.com/front-core/nodejs-socketio-webaudio-sample
対応ブラウザ
IE11以下,Android(Android Browser)を除くモダンブラウザ。
ただしAndroidでも、Chrome for Android40以降は対応。
※全端末で検証した訳ではない為、動作の保証はありません。
使用した技術
今回のサンプルは、下記を使って実現しました。
Node.js(express)
JavaScriptでサーバサイドのプログラムを実行出来るプラットフォームです。
非同期I/Oを扱う事が出来るのがメリットで、1台のサーバで数万〜数十万の接続も可能となります。
また今回、Node.jsで最も利用されているフレームワークexpressを利用しました。
expressは、URLのルーティング機能などWebサイトを構築する基本機能が備わっています。
Socket.IO
Node.js上で動作し、リアルタイム通信機能を提供しているフレームワークです。
ブラウザの対応状況をチェックして、最適な通信方法を選択してくれるのが特徴です。
スマートフォンもiOS,Androidに対応しています。
Socket.IOが対応している通信方式は次の6つとなります。
- WebSocket
- Ajaxポーリング
- Ajaxマルチパートストリーミング
- IFrame
- JSONPポーリング
- Flashのソケット通信
上記のように、広い通信方式に対応しているので、
基本的に、主要ブラウザを含めIE5.5といった古いブラウザでも利用可能となります。
また通信方式を特定して接続させることも可能です。
特にWebSocketは、サーバーとの接続が軽減されより高速な動作が可能となります。
以下がWebSocketに対応しているブラウザです。
IE9以前、Android4.3以前を除く、多くの現行ブラウザがWebSocketに対応しています。(2015/2/7現在)
PC | ||||
Chrome16+ | Firefox11+ | Safari7+ | Opera12.1+ | IE10+ |
スマートフォン | ||
iOS Safari6.1+ | Android Browser4.4+ | Chrome for Android40+ |
Web Audio API
音声を再生、処理する為のJavaScript APIです。
音声の再生、ボリューム調整などに加えて、合成やフィルターなど複雑なエフェクトが可能となります。
以下がWebAudioAPIに対応しているブラウザです。
IE、Android Browserを除く、多くのブラウザがWebAudioAPIに対応しています。(2015/2/7現在)
PC | ||||
Chrome10+ | Firefox25+ | Safari6+ | Opera15+ | IE 未サポート (開発中) |
スマートフォン | ||
iOS Safari6.1+ | Android Broser 未サポート | Chrome for Android40+ |
Heroku
アプリケーションを稼働させるためのプラットフォームです。
Node.js,Java,Ruby,PHP,Pythonなど様々な言語をサポートしていて、
基本的な機能を使っている限り無料でWebサイトを公開する事ができます。
ソースの解説
web.js(Node.js + Socket.IO)[サーバ側]
HTTPサーバを作りルーティング、Socket.IOを設定
web.jsでは、Node.js(express)でHTTPサーバを作り、静的ファイルの保管場所(css,js,音声ファイルなど誰でも閲覧可能なPublicな場所)を指定して、ルートにアクセスがあったらindex.htmlを表示するルーティングを設定しています。
またSocket.IOでは、クライアントから”from_client”がくるのを監視し、接続があったら”from_server”を返答する設定をしています。
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 |
|
index.html(Web Audio API + Socke.IO)[クライアント側]
Socket.IOの読み込みと接続
index.htmlでは、まずSocket.IOを使えるようにsocket.io.jsを読み込みます。
自動で生成されるファイルなので準備する必要はありません。
指定したURLで、Socket.IOに接続させます。
1 2 3 4 5 6 7 |
|
スプラッシュ画像を押して再生したい音声データをセット
iPhone/Androidでは、最初の音声ロードだけはユーザーアクション(クリックなど)が必要な制約がある為、
最初にスプラッシュ画像を準備し、タップされた時に音声データを再生可能な状態にセットします。
※PCでは、この制約はありません。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
ボタンが押された時にサーバ側に通知
ボタンが押されたらサーバに”from_client”を送信し、押したボタンidを送ります。
※どのボタンが押されたかを全クライアントに通知させる為。
1 2 |
|
サーバ側からの返答をチェックし、音声を再生
サーバに”from_client”を送信すると、”from_server”を返答してもらうようにサーバ側で設定しているので、
“from_server”がくるのを監視し、返答があったら受け取ったボタンidの音声を再生します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
Herokuにデプロイ
Node.jsで作ったアプリケーションを、Herokuにデプロイする際は、こちらが参考になりました。
またHeroku上でNode.jsを実行する際は、package.jsonに下記の記述をします。
※もしくはProcfileを準備。
1 2 3 |
|
ハマったところ
モバイル端末で音がならなかった
PC上では音がなったが、なぜかiPhone上で音声再生ができなくハマりました..
解決方法
使っていたNode.js,Socket.IOのバージョンが古く対応してなかったようです。 package.json記載のバージョンを下記にしたところ問題なく再生する事ができました。
1 2 |
|
Herokuをよく理解していなかった
HerokuでWebアプリを公開出来る事は知っていましたが、実際に試したりしていなかったので、その使い方でハマりました..
解決方法
サイトを参考にサンプルサイトを公開していく事でだいぶ理解出来ました。
参考になった記事
課題
複数デバイス間での音の完全な一致が難しい
ローカルで試している時はほぼ一致させる事が出来ても、Web公開した環境だと少し遅れて再生されてしまっていました。
完全な一致が難しいまでも、出来るだけ一致する状態にしたいのですが、打ち手がよくわかっていません。
まとめ
リアルタイム通信して複数デバイス上で音声を再生する方法を解説していきました。
オンラインゲームや音楽アプリ、チャットなど様々な用途が考えられます。
非常に少ないコードで実現出来た反面、複数デバイス間で音を完全に一致させる事など、課題もまだまだあります。
その辺りの課題が解決したら、また紹介させて頂きます。
Comments