イベント用にSkyWayを利用したサイネージを作った

この記事は [SkyWay Advent Calendar 2018](https://qiita.com/advent-calendar/2018/skyway) の18日目の記事です。


## はじめに

#####作った動機
自分が絡んでいるイベントの会場に、少しでもホスピタリティを高められる何かを作れないかと思い、SkyWayを利用したサイネージを企画・開発しました。とはいえ、たいしたモノではないです。

#####これを導入したイベントについて
山口県で行われている、Web・DTP・デザインなどのセッションが一堂に会する年1回レベルのセミナーイベント [CREATIVE HUNT（クリエイティブハント）](https://creative-hunt.org/) で導入しました。会場は山口大学で、セッションは4ライン（4部屋同時進行）制。今年は約160名の皆様に参加いただけました。



## 実際にイベントでの使用した時の様子

####配信側
![_MG_0866.png](https://qiita-image-store.s3.amazonaws.com/0/290475/2dd97e95-8161-9eda-4c74-22b988f175c1.png)
配信用のデバイスは、各教室の背面側の黒板に固定。今回はiPod touch（Wi-Fi接続）を4台使用しました。
音声も配信してしまうとサイネージがごちゃごちゃしてしまうので、配信は映像のみ。

この固定方法でアウトカメラを使うと、「どんな目的・アングルで何を撮っているのか」が解りにくくなってしまい、参加者さんに不安を与えてしまうため、映像はインカメラから取得。
副次的な効果として、設置するときのアングル決めが簡単でした。

安価に済ませたかったため、固定まわりは100均のソフトカードケースとマグネットクリップで自作。

「こん感じでカジュアルに配信してます！すごいシステムとか配線とか機器とか用意しなくてもできます！」感が参加者さんに伝わったとしたらラッキー。

####受信側（サイネージ本体）
![_MG_0955.png](https://qiita-image-store.s3.amazonaws.com/0/290475/c24cd47a-e83f-217c-6abf-e03569c139f1.png)
実際にサイネージとして設置したモノがこちらです。
総合受付の背後に自立式100インチスクリーンを設置し、そこに4会場のライブ映像やお知らせを表示するページをプロジェクターで投影しました。（青色枠のカメラがななめになっている）
このライブ配信サービス自体に「HUNT A CLUE」という名前をつけました。　


## 技術的なこと
SkyWay…というか、まだWebすら初心者レベルから抜け出せてないので、要所を抜粋して。

####配信側デバイス
まず、配信側デバイスをどうするか考えたとき、ネットワークは会場に設置したWi-Fiを利用すればいいやということで、iPod touchのみを使うことにしました。これにより、iPod touch（iOS Safari）のコトだけを考えれば良かったので、作るのがラクでした。

#####半固定peer idを付与
![スクリーンショット 2018-12-18 22.40.35.png](https://qiita-image-store.s3.amazonaws.com/0/290475/f30127e6-8bb7-cf19-7657-b31e5751b4f4.png)
iOSでアクセスするとこのような画面になり、配信担当の部屋（ステージ）を選択します。この操作によって、配信側に半固定peer idを付与しました。
半固定とは、「ランダムな接頭文字列+固定文字列」という意味です。

#####localStream取得
```javascript:localStreamを取得する
var constraints = {
    audio: false,
    video: {facingMode: "user"}
};
constraints.video.width = {
    min: 640,
    max: 640
};
constraints.video.height = {
    min: 480,
    max: 480
};
constraints.video.frameRate = {
    min: 10,
    max: 24
};
constraints.video.sampleRate = {
    min: 10,
    max: 24
};
navigator.mediaDevices.getUserMedia(constraints)
.then(function (stream) {
    $('#mycam').get(0).srcObject = stream;
    localStream = stream;
    if(existingCall){
        existingCall.replaceStream(stream);
    }
});
```
iPod touchは`audio`に対応していないらしい（[SkyWayサポート 参照](https://support.skyway.io/hc/ja/articles/115012750968-Safari%E3%81%B8%E3%81%AE%E5%AF%BE%E5%BF%9C%E7%8A%B6%E6%B3%81)）ので、
localStreamを取得する場合は、`audio: false,`とします。
もともと音声は配信しない予定だったので、ぴったり。

さらに、インカメラの映像を取得したいので、`video`の`facingMode`は`"user"`に。

フレームレートとかサイズは適当です。
ですが、全くの自由というわけでもなく、取得映像のサイズは、
1280×768か上記設定（640×480）くらいしか有効にならなかったです。


####受信側

#####受信モード
![スクリーンショット 2018-12-18 22.54.25.png](https://qiita-image-store.s3.amazonaws.com/0/290475/e72746aa-2ed7-bdbe-714e-c5e5d26f6280.png)
iOSデバイス以外でアクセスするとこのような画面になり、そもそも配信ができない（localStreamを取得しない）ような仕組みにしました。

ちなみに、投影先スクリーンの比率が16:9で、それにぴったり映したかったので、プロジェクタ投影比率を取得して16:9じゃなかった場合にこのように警告がでるようにしました。


#####受信特化のjoinRoom
```javascript:受信側のjoinRoom
const call = cpeer.joinRoom(roomkey, {
    mode: 'mesh',
    videoReceiveEnabled: true
});
```

Roomにjoinするとき、メッシュ接続のみ使用可能な、映像を受信のみで使う場合のフラグを立ててます。
localStreamは持ち込んでません。受信のみ。

SafariはRoom APIがMeshRoomにしか対応していないので、MeshRoomで。

#####受け取った映像は決め打ちで配置
配信側デバイスから`call.on 'stream'`された時、半固定peer idの固定文字列部分で判別し、受信した映像をしかるべき位置に配置されるようにしました。そうすることで色々悩まなくて済みました。配信側デバイス機器が不調になった場合、別のデバイスから配信を始めると、動画（配信映像）がオーバーライドされるし。

## 作ってみた感想
実際に参加者様のホスピタリティが向上したかどうかは別として、
SkyWayをちょっと勉強するだけで、Web初心者でもここまで作ることができたことに感動しました。

「SkyWay（WebRTC）での映像配信」といえば、どうしても「遠隔同士の利用」と考えがちですが、映像ケーブルが要らない簡易的な会場用生撮影（録画しない撮影＝配信）システムとして使えちゃうなと思いました。