今年からの試みで、ICPC 横浜大会でスクリーンキャストを提供しました。 当日の中継動画を PC から見ると、カメラ切り替えで選手のマシンの様子が見られるようになっています。
経緯
実は 2016 年くらいからこれを計画していて、今年ようやく適当なものができました。まずスペックが右往左往しました。
- 選手の画面を外部に提供できると、観戦の際に楽しそう
- スクリーンショットを外部ページにアップロードすれば良さそう
- 60台の1080pのスクリーンショットを定期的に外に保存すると帯域を食い過ぎる。
- ユーザに提供する UI が大変なことになりそう。
- 実は動画で提供したほうが帯域は少なくて済む。
- とは言え 60台分送るのはやはり大変だし UI も大変。
- 動画を中継に差し込みたいが、選択 UI とか大変そう。
- 裏方でも見られるようにしたい。
- 外野にも見られるようにしたいが、60チャンネル YouTube Live するのは正気ではない。
上を経て、世界大会のビデオ を真似ることにしました。画面を4分割して、4チームのスクリーンが流れます。5秒ごとに1チームが切り替わるので、各チームは一度に20秒だけ放送されます。
どうなるか謎な UI は無視し、とりあえずチームを全自動ランダムに選んで動画を提供します。動画提供方法を確立することを目指し、それの活用は後回しにしました。
仕様を確立した後も、やることはうまく見通せず大変でした。 ストリーミングどころか動画データすらちゃんと扱った経験がないので、何をどう構成していいか全くわからず、調べるのにも苦労しました。
やることは以下のとおりです。
- 60台の選手マシンから動画を受け取る。
- ランダムに 4チーム選んで順次合成。
- 合成した動画を生放送サイトに送る。
つまり、動画ストリーミングを切り替えつつ一本にまとめる事になります。自動でできるソフトを探すかプログラムを書くかになります。何もわからず、ffmpeg streaming とか ffmpeg switch between streams とか ffmeg zmq crossfade とかで何度も検索しました。
すごく初期の実験の様子: ffmpeg x11grab しているだけ
ffmpegごっこ (ライブスクリーンキャストを表示するライブスクリーンキャストをしている) pic.twitter.com/lNs1pbP3ej
— Yu SUGAWARA (@gusmachine) June 21, 2016
最近の、 動画切り替えができるようになった頃の様子。
本番構成
本番では以下のシステムを使いました。結局、ストリーミングを切り替えるのを、単純に ストリーミングを送るマシンを動的にザクザク切り替える方法で対応しました。
- 「動画リレーサーバ」マシンを用意してコンテストネットワークとインターネットにつなぐ
- 動画リレーサーバは選手マシンに接続して、選手マシンで ffmpeg を起動して20秒だけ動画を動画リレーサーバに p2p で送る。
- 動画リレーサーバ上で OBS Studio を起動して動画を合成して Youtube Live に送る。
- 動画リレーサーバがいつどの選手マシンに接続するかはプログラムで指定。
動画の切り替えは前の動画の終了及び次の動画のスタートで行われる。OBSが勝手に合成してくれている。
- ここがうまく行くことを知るのがほとんど全てでした。zmq は使っていません。
これを作るために、 ssh 経由で ffmpeg を起動する Go のコードを 500 行くらい書き、 VirtualBox VM を録画用と選手2台の合計3台立てて実験を繰り返していました。正直結構面倒でした。いまはテスト手法が確立したので、はるかに楽に実験が出来ます。
改善アイデア
やることはいろいろあります。まずは実況システムとの連携です。上で捨てた「UIが怪しい」部分をなんとかしないといけません。 それから、当然順位や解答状況を載せるべきです。
あと、切り替えはおそらくもっとマシな方法があるのではないかと思っています。視覚効果も入れたいですが、 ffmpeg filters を見たところ外部から指定する任意のタイミングにfade in/out を入れるのは出来なそうです。