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

カメラ映像を分割してSkyWayで配信するアプリケーションを作ってみた

More than 1 year has passed since last update.

はじめに

この記事は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です。今回は映像のみを扱うため、audiofalseを指定しています。
解像度の指定は1280x720としています。
映像が取得できたらvideosrcObjectに取得したストリームを指定し、映像を表示させます。
その後、videoからcanvasに映像の1コマを描画するようにしています。
記述としては、

ctx.drawImage(video, 0, 0, canvas.width, canvas.height);

こんな感じです。これで映像の1コマが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);

こんな感じで指定します。
canvascontextをあらかじめ取得して配列に格納しているので、こんな感じで書くことができます。
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つ分を取得しています。
あとは、localStreamsMediaStreamが4つ分入った状態になるので、クライアントごとに、それぞれ送ってあげればOKです。
SkyWayでMediaStreamを配信する部分はp2p-broadcastのコードを参考にしました。
配信側では、clientscountという変数を準備しておき、クライアントが接続するたびに1増やすようにしています。
クライアント側に配信するMediaStreamは配列に入っているので、クライアントが接続するたびにまだ配信していない分を配信するようにしています。
クライアント側では、ページにアクセスするときにURLにクエリパラメータとしてsid=xxxxという形式で、配信側のidを指定します。
映像を受信する際は、特に操作は不要で、ページにアクセスするだけで分割された映像が送られてきます。

まとめ

このアプリケーションの使い道として、例えばベゼル幅が狭いFHDモニター4枚と4台のPCで疑似的に4K映像を表示する。といったことができます。
今回はP2Pで通信を行っているため、LAN内であればそれほど遅延は気になりません。
配信側のPCスペックに応じてコマ取得のレートを調節するなどすれば、よりスムーズに動くと思います。

SkyWayのライブラリは映像の取得を自分でコントロールできるため、今回のように加工したストリームを流すこともできます。
アイディア次第で面白いアプリケーションが作れるところもSkyWayの良いところだと感じています。
皆さんもSkyWayを使って、アプリケーションを作ってみてはいかがでしょうか?

sublimer
諸事情により、記事は全てはてなブログに移行しました。 All articles has moved to hatena blog due to various reasons.
https://sublimer.hatenablog.com
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
ユーザーは見つかりませんでした