カメラ映像を分割してSkyWayで配信するアプリケーションを作ってみた
カメラ映像を分割してSkyWayで配信するアプリケーションを作ってみた:
この記事はSkyWay Advent Calendar 2018の9日目の記事です。
8日目はkolifeさんの「【爆速!】5分でビデオチャットを構築する」でした。
タイトルにある通り、Webカメラの映像を分割し、SkyWayを使ってP2Pで配信するWebアプリケーションを作りました。
イメージとしては「HTML5 JUMBOTRON」の逆のような感じです。
ソースコードはこちらで公開しています。
コミットログを見てわかるように、最初はVue.jsを使ってみようと思いましたが、よくわからずに挫折してしまいました。
SkyWay Advent Calendar 2018の4日目でn0bisukeさんが「Nuxt.jsとSkyWayで1時間でビデオチャットを作ってみる」という記事を書いてくださっているので、こちらを参考に再挑戦してみたいと思います。
皆さんおなじみ(?)の
解像度の指定は1280x720としています。
映像が取得できたら
その後、
記述としては、
こんな感じです。これで映像の1コマが
今回は2x2の4つのブロックに分割します。
まず、分割した画像を描画するために、4つの
あとは、それぞれの
例えば、左上の分割画像は、
こんな感じで指定します。
といった感じで指定することで、画像の分割ができます。
あとはこれを4つ分行い、1コマ取得と分割を定期的に行うことで、映像の分割ができます。
分割した映像を配信するためには
今回は、
こんな感じで分割した
あとは、
SkyWayで
配信側では、
クライアント側に配信する
クライアント側では、ページにアクセスするときにURLにクエリパラメータとして
映像を受信する際は、特に操作は不要で、ページにアクセスするだけで分割された映像が送られてきます。
このアプリケーションの使い道として、例えばベゼル幅が狭いFHDモニター4枚と4台のPCで疑似的に4K映像を表示する。といったことができます。
今回はP2Pで通信を行っているため、LAN内であればそれほど遅延は気になりません。
配信側のPCスペックに応じてコマ取得のレートを調節するなどすれば、よりスムーズに動くと思います。
SkyWayのライブラリは映像の取得を自分でコントロールできるため、今回のように加工したストリームを流すこともできます。
アイディア次第で面白いアプリケーションが作れるところもSkyWayの良いところだと感じています。
皆さんもSkyWayを使って、アプリケーションを作ってみてはいかがでしょうか?
はじめに
この記事はSkyWay Advent Calendar 2018の9日目の記事です。8日目はkolifeさんの「【爆速!】5分でビデオチャットを構築する」でした。
作ったもの
タイトルにある通り、Webカメラの映像を分割し、SkyWayを使ってP2Pで配信するWebアプリケーションを作りました。イメージとしては「HTML5 JUMBOTRON」の逆のような感じです。
ソースコードはこちらで公開しています。
コミットログを見てわかるように、最初はVue.jsを使ってみようと思いましたが、よくわからずに挫折してしまいました。
SkyWay Advent Calendar 2018の4日目でn0bisukeさんが「Nuxt.jsとSkyWayで1時間でビデオチャットを作ってみる」という記事を書いてくださっているので、こちらを参考に再挑戦してみたいと思います。
仕組み
映像取得
皆さんおなじみ(?)のnavigator.mediaDevices.getUserMediaです。今回は映像のみを扱うため、audioはfalseを指定しています。解像度の指定は1280x720としています。
映像が取得できたら
videoのsrcObjectに取得したストリームを指定し、映像を表示させます。その後、
videoからcanvasに映像の1コマを描画するようにしています。記述としては、
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
canvasに描画されます。
分割
canvasに描画した1コマの画像を分割していきます。今回は2x2の4つのブロックに分割します。
まず、分割した画像を描画するために、4つの
canvasを用意します。あとは、それぞれの
canvasに「元の画像のどの領域を描画するか」を指定して画像を描画します。例えば、左上の分割画像は、
ctxs[0].drawImage(video, 0, 0, canvas.width / 2, canvas.height / 2, 0, 0, canvas.width / 2, canvas.height / 2);
canvasのcontextをあらかじめ取得して配列に格納しているので、こんな感じで書くことができます。drawImageに関してはMDNのドキュメントが一番詳しいですが、要約すると、ctx.drawImage(元のデータ,切り取る領域の始点x,切り取る領域の始点y,切り取る領域の幅,切り取る領域の高さ,描画先の始点x,描画先の始点y,描画先の幅,描画先の高さ);
あとはこれを4つ分行い、1コマ取得と分割を定期的に行うことで、映像の分割ができます。
配信
分割した映像を配信するためにはMediaStreamを取得する必要があります。MediaStreamの取得にはcaptureStreamメソッドを使用します。引数はフレームレートです。今回は、
for (let i = 0; i < splitCanvases.length; i++) {
localStreams[i] = splitCanvases[i].captureStream(10);
}
cacnvas4つ分を取得しています。あとは、
localStreamsにMediaStreamが4つ分入った状態になるので、クライアントごとに、それぞれ送ってあげればOKです。SkyWayで
MediaStreamを配信する部分はp2p-broadcastのコードを参考にしました。配信側では、
clientscountという変数を準備しておき、クライアントが接続するたびに1増やすようにしています。クライアント側に配信する
MediaStreamは配列に入っているので、クライアントが接続するたびにまだ配信していない分を配信するようにしています。クライアント側では、ページにアクセスするときにURLにクエリパラメータとして
sid=xxxxという形式で、配信側のidを指定します。映像を受信する際は、特に操作は不要で、ページにアクセスするだけで分割された映像が送られてきます。
まとめ
このアプリケーションの使い道として、例えばベゼル幅が狭いFHDモニター4枚と4台のPCで疑似的に4K映像を表示する。といったことができます。今回はP2Pで通信を行っているため、LAN内であればそれほど遅延は気になりません。
配信側のPCスペックに応じてコマ取得のレートを調節するなどすれば、よりスムーズに動くと思います。
SkyWayのライブラリは映像の取得を自分でコントロールできるため、今回のように加工したストリームを流すこともできます。
アイディア次第で面白いアプリケーションが作れるところもSkyWayの良いところだと感じています。
皆さんもSkyWayを使って、アプリケーションを作ってみてはいかがでしょうか?
コメント
コメントを投稿