[Signagify 1] Chromecastでデジタルサイネージ

この記事はファーストサーバのAdvent Calenderの三日目として書きました。
http://qiita.com/advent-calendar/2015/firstserver

#はじめに
「みんなにお知らせしたいけど全社員にメール出す程でもないしうーむ」っていう情報を気軽に発信できるものないかということで社内用デジタルサイネージを導入しようということになりました。ちょうどその検討と同時期にChromecastがリリースされたので使ってみることにしました。簡単そうに思えたのですがいろいろあり、ようやくその道筋が見えてきたのでその過程をログログしてみます。

#chromecastとは
Chromecastを使うと、YouTube、Google Play、Chromeなどから、お気に入りの映画やテレビ番組、写真、ウェブサイトをテレビ画面で簡単に楽しむことができます。スマホのアプリから動画や画像などのコンテンツを選んで表示させたり、PCのChromeで開いているWEBサイトや画面全体をミラーリングさせたりすることができます。テレビのHDMI端子に刺してUSBで給電してWIFIで通信します。

![TV.png](https://qiita-image-store.s3.amazonaws.com/0/12406/fc714432-dbf6-b8ec-ccb0-164abc64dbac.png)

#サイネージ配信の仕組み
社内にはいわゆる憩いの場の「AJITO」というフリースペースがあり、そこや社内の通路に大型テレビを置いてChromecastを刺し、動画を再生することとしました。

![overview.png](https://qiita-image-store.s3.amazonaws.com/0/12406/88be26d9-a6d7-b420-db4b-10a73e80c58a.png)

サイネージに何かを投稿したい人にパワポでスライドを作ってもらい、それを動画で出力してサイネージ用動画を作ります。

配信専用の端末を用意して動画配信するだけでサイネージできちゃうんじゃね？ってことで、作り物いらなさそうだし手間もかからずスマートそうに思えたのでこのような仕組みで取り組み始めましたが。。。

###■罠1：あきらめが早い
まず最初は配信サーバでおもむろにChromeを起動し、Chromeのタブでサイネージの動画を開いてループ再生し、標準のcastアプリでタブの内容をミラーする形式で始めてみました。最初はうまくいっているように見えたのですが、しばらくならし運転してみるとミラーリングが終了してしまいます。タイミングがまちまちでエラーメッセージやログなどは出ないので原因がわかりません。

###■罠2：頑固「配信先は一つ」
また、配信先が一台の場合はこのままでもいいのですが、Chromeのcastアプリでは配信先を１つしか選択できないのでこのままだと配信先が増えると配信サーバも増やさねばなりません。

###■罠3：頑固「ループ再生はヤダ」
仕方がないのでYoutubeにアップしてYoutubeアプリで配信しようと思いましたが、ループ設定したのにもかかわらずなぜかChromecastに配信しようとすると設定が外れる仕様になっていました。3rd Partyのアプリで動画をループ再生しながらキャストするものもありましたが、どれも動作が安定しません。

###■罠4：気まま
もう仕方がないので独自でアプリを作って監視や自動化までやってしまおうと思い、ChromeとChromecastがお話している内容をいろいろ調べてみました。Chromeのタブをミラーしている時の通信内容はよくわかりませんでしたが、Youtubeアプリでは8008ポートに対してHTTPでポコポコGETだのPOSTだのしておるようで、Netflixが定義してるDIALとやらのプロトコルでお話していることがわかりました。
https://plus.google.com/u/0/+LeonNicholls/posts/Md6py81N2Ag

ふむふむ、REST APIか、よーし、パパ Hackして自動配信しちゃうぞー！と頑張っていた矢先に新しいSDKの発表がなされ、使っているプロトコルが変わってしまいました。
https://plus.google.com/+SebastianMauer/posts/83hTniKEDwN

###■罠5：秘密主義
新しいSDKはTLS上でナイショ話しているようで会話の内容が簡単にはわかりませんでした。

SDKはAndroid、iOS、Chromeアプリに対応していますが、Chromeアプリは複数キャストできないし、配信するためだけにスレート端末用意したりエミュレータ動かすとか考えるのアホらしいなあと、ChromecastをあきらめてLinuxのHDMIドングルやサイネージ用メディアプレーヤーを物色し始めました。そんなおり、thibautsさんがNode.jsでモジュールを公開しているのを発見しました！
https://github.com/thibauts/node-castv2

よ、読める！読めるぞぉ！私も古い秘密の（以下略

###■罠6：拝金主義
新しいSDKの仕様ではAppleのmDNSでネットワーク内のChromecastを探しだし、CASTV2とかいうオープンになっていないプロトコルでお話している様子。mDNSはオープンになっているのでなんとでも実装できましたが、CASTV2とやらはすべての仕様が網羅されているわけでもなく、「デフォルトのアプリだとこんな感じやでー」ってサラッと書いてある程度。SDKのドキュメントとにらめっこしながら「TYPEにこれセットしたらレスポンス帰ってこないかな。。。」と実機に手探りでメッセージをちぎっては投げちぎっては投げ、なんとかやりたいことはできるようになりました。

このように独自でアプリを開発するためにはGoogle様に$5奉納しなければなりませんでした。
![yokose.png](https://qiita-image-store.s3.amazonaws.com/0/12406/d2912f72-37f6-f7bc-8bc0-f0a066f7956a.png)

###■罠6：声が低い
しかし、とある時期からものすごく配信が不安定になりました。どうやら社内WiFiの2.4GHz帯が混雑しているようで、機嫌が悪い時は全くレスポンスを返してくれません。Chromecastは5GHz帯には対応しておらず、2.4GHzの低い周波数でしかお話をしてくれないのでした。2.4GHz帯は同じチャンネルを複数の端末が同時に利用すると干渉を起こして不安定になるのです。

#ようやく安定
そうこうしているうちにChromecast専用のethernetアダプターが発売されました。
最近日本でも発売されたのでこれを導入することでようやく配信が劇的に安定しました。
http://japanese.engadget.com/2015/07/08/google-chromecast-lan/

また、Chromecast2も登場しました。こちらは現在（2015/12/2）では日本で発売されていませんが、5GHz帯に対応しています。んで"Fast Play"とかいう次に再生される動画を前もってキャッシュしておく機能が実装されているようで、2016年には一般開発者にもそのSDKが公開されるんではなかろうかとのこと。

というわけで、今では社内共有ファイルサーバーの特定フォルダに置いてある画像、動画を順々にChromecastへ配信し、Chromecastの調子が悪くなったら再起動するなどサイネージの自動運用ができるようになりました。加えて、そのフォルダにテキストファイルがあった場合はその文字列をニコ生や新幹線の車内デジタルサイネージ風にMarqueeで文字を横に流しています。
https://github.com/vanx2/signagify

#これから
なんだかディスっているような書き方してますが、ぜんぜん好きですよChromecast。このサイネージの仕組みを軸にして、いろいろおもしろいことしようと思っています。

- Slackとの連携
    - リアクションが多い発言やボットにメンションした内容などを自動配信
- AJITOで一人寂しそうにうなだれているPepperくんとコラボ
    - 今の感情やPepperくんに話しかけた内容などを自動配信
- サイネージ用のChromecastを乗っ取ってテレビの前で気軽に会議
    - ミラーリング機能で資料をChromecastに飛ばす
    - ミラーリングが終わったら自動でサイネージに切り替わる

以上です。最初はChromecastアプリやmDNSとCastV2の内容について触れてみようと思ったけどあと数時間でAdvent calenderの公開時間なので今回はここまでとして次回書いてみようと思います。