昨今のコロナ渦の影響もあり、もちろん普通に文化祭など開催できるはずがなく、うちの学校では代替イベントを立て、その中で映像コンペを行うという形になりました。当日は映像コンペに提出された映像作品を各クラスに一斉配信し、動画が終わったら生放送に切り替え動画の感想を言ったり参加団体にインタビューをするといったことをやったのですが、実際に当日を迎えるまでにかなり苦労したので、何が起きて何をしたのか綴っていこうと思います。
見えないところにある「罠」
ことの発端は夏休みにあったイベントの司会の会議。自分はイベント当日の司会として出演する予定だったのでこの会議に出席したのですが、ふと気になって生徒会顧問に当日の映像配信方法はどうなっているのかと尋ねてみると全く定まっていない様子。
幸いにも、自分の学校には1教室単位でYouTubeの視聴が可能な設備が整っているので、ならOBS使ってソース切り替えながらYouTubeライブすれば良いかなとその時は思っていたのですが、ここでYouTubeのContent IDが登場してきます。
映像コンペということですから、当然ダンス動画等の著作物を使用した動画を製作する団体が出てきます。つまり、これだとContent IDに引っかかってしまうわけです。
YouTubeライブの最中に、Content IDに引っかかるような状況が続くと、ライブストリーミングが強制的に終了されますのでこれでは当日困ってしまいます。
ということで、OBSでソースを切り替えながらYouTubeライブを行う以外の方法を考える必要が出てきました。
もうここらへんで、生徒会でも何でも無い一般生徒の自分が、イベント当日の映像配信のインフラ整備係になるような空気になっていましたw
自分で配信システムを作るしか無いじゃん
「だったら各教室でそれぞれ手動で動画ファイルを開けばいいじゃん」というご指摘がありそうですが、まずそれは普通に手間だというのと、操作方法が操作するはずの人に把握されていないことがある等、確実とは言えません。それに、当日のスケジュール的に無人の教室も出てきますので一括で動画の切り替え(進行)はしていきたいところです。
しかし、OBSを使ってYouTubeライブの波に動画ファイルを乗せることはContent IDの仕様上困難。他のライブストリーミングサービスを使う手も考えてみましたが、実用的というか、現実的な選択肢は他にありませんでした。
なら自分で作るしか無いかと。
流石に、ライブストリーミングサービス自体を短期間で開発するのは困難を極めるので、「指定されたURLの動画ファイルを再生しろ」という命令を一括で送信して、それを受け取ったクライアントが実際に動画ファイルの再生をするというサービスを作ってみることにしました。クライアントがChromebookなのでWebベースのサービスであることは必須条件です。
やはり、この手の用途だとWebSocketを使うのが一番最適だと思ったので、Socket.IOを使うことにしました。あとは、HTML5の動画プレイヤーのAPIなんかと組み合わせて、1時間ぐらいでプロトタイプができました。
UIはガン無視でとりあえずテキストボックスとボタンだけ配置しました。テキストボックスにファイル名(例えばExample.mp4だったら「Example」)を入力し、Showボタンを押すとイベントが発火し、サーバーサイドのSocket.IOからクライアントに向けてファイル名がemitされます。それを受け取ったクライアントが、予め指定してあるディレクトリの中にあるExample.mp4を再生するという感じです。
厳しすぎた制限
先程Socket.IOを使うと申し上げましたが、その都合上、このサービスを実行するには2つのサーバーが必要になります。WebサーバーとSocket.IOのサーバー(Node.js)です。Webサーバーは動画とHTMLファイル等を入れておく用で、Socket.IOのサーバーはその名の通りです。2つのサーバーが必要とは書きましたが、ネットワークにはポートという概念がありますから、同一のPCを使っていたとしてもそれぞれのプロセスでポート番号が重複しないようにすればサーバーを2台用意する必要なんてありません。2台用意する必要なんてないはずだった。
はいここで学校の厳しいネットワーク制限の出番です。Webサーバーを100番、Socket.IOのサーバーを3000番のポートで起動し、学校の回線に接続されたクライアント(Chromebook)からサービスにアクセスしようとしても、できない。
なぜだろうと思い、Webサーバーのポート番号を80番にしてみる。するとページは表示されるけどSocket.IOの接続は確立されない状態。察しが付きましたね。なんと、学校のネットワークは80番以外のポートへのアクセスを許可していないらしいです。(443は未検証)
なんとか80番以外のどこか抜け穴がないかと探してみましたが、無理でした。
ということで、ナンセンスではありますがサーバーを2つ用意して、それぞれのプロセスで80番のポートを使うことに()
WebサーバーはStarServerを契約して、Socket.IOの方はGCE上に建てました。
うまくいくはずだった…?
これで、サーバーの問題も解決したし、と、そこそこ先が見えてきた矢先、その希望を打ち砕かれる事案が発生しました。なんと、学校の回線が貧弱すぎてクライアント2台で同時に1080pの動画ファイルを再生するだけで動画がバッファリングのために頻繁に止まるのです。これでは当日使い物になりません。
実際に学校で実証実験したとき(さっきのサーバー問題も含めて)は、先のプロトタイプを作ってから日数も少し経っていましたから、サービスもアップデートさせていて、「Quartz」というサービス名が付いたり、YouTubeの埋め込みプレイヤーAPIなどに対応させていたので、動画ファイルをそのまま再生するのではなく、YouTubeに上がっている動画を再生させたら同じようにバッファリングで止まるのか試してみました。すると特に止まることもなく動画が再生される。
ここでYouTubeの凄さを再認識させられました。ただ動画ファイルを垂れ流しているのとは訳が違いますからね。
実際にYouTubeの動画をQuartzを使って再生している動画です。
別日に、台数増やして再生できるかチェックしているところです。
この頃にはQuartzのコントロール画面のUIもだいぶ変えました。
やることはまだある
これでYouTubeの動画再生を一括でコントロールすることは可能になりました。予め提出された映像作品をYouTubeに限定公開でアップロードしておけば準備は完了です。確かにContent IDには引っかかりますが、同じアップロード先のYouTubeアカウントにログインすれば、視聴制限がかかってようが再生できるので問題ありません。
冒頭でも述べましたが、当日は予め製作された動画を再生するだけでなく、再生が終了したところで生放送を挟み、司会による感想やインタビューが入ります。実は今回この生放送が今回一番骨が折れたところです。
動画と生放送の切り替えはQuartzを使ってコマンドを打てば一括で切り替わるので問題ありません。本当の問題はもっと根本的なところにあります。
まず、もちろん生放送にはYouTubeライブを使うのですが、生放送なので配信する側のPCは比較的安定したネットワークに接続する必要があります。
なので学校に引いてある固定回線にPCを接続したいところですが、保安上の理由からそれは禁止されています。なので無理です。
こればっかりはどうしようもないので、当日はポケットWi-Fiを使用して配信を行うことになりました。
はい、皆さんお察しの通りポケットWi-Fiは固定回線ではないので結構不安定です。でも方法はこれしかないので素直に諦めます。
回線が不安定ということで、1080pの60FPSはまず無理でした。色々検証したところ、720pの30FPSが限界です。確かに決して高画質とは言えませんが、それほど悪くもないのでここは妥協します。
大体の生放送の仕様が定まってきました。
スペック不足問題
当初、生徒会の備品のMacBook AirにOBSを入れて生放送する予定だったのですが、ビデオカメラが接続されているキャプチャーボードに来てる映像が実際にOBS側に出てくるまでラグがある、だけど音声はラグがない、ということで音ズレ問題が発生するようになりました。まあ確かに、音ズレだけなら設定から修正できますが、Macが熱を持つにつれてOBSで動画ファイルを流すだけでもカクつくようになってきたのでスペック不足と判断しました。
ちょうど生徒会が最近(?)、デスクトップPCを購入したということで生放送に使うPCはそれに変更。CPUが第9か10世代(忘れた)のi5でメモリが8GB、GPUはオンボードと若干不安が残りますが、それでも校内で一番スペックが高いPCなのでありがたく使わせていただくことに。
一難去ってまた一難
とここまでなんとか生放送ができる環境を構築してきて、リハーサルということになったのですが、なんとここで今まで使ってたキャプチャーボードがいきなりぶっ壊れるという災難。この時点で当日の前日なので、非常にまずいです。ということで生徒会顧問が学校近辺の電気屋までダッシュして買ってきたのが、
「AVerMedia Live Gamer Portable 2 PLUS」です。今まで中華の怪レいキャプチャーボードを使っていたのですが、安定感が全く違います。
とここで、AVerMedia Live Gamer Portable 2 PLUSがHDMIのパススルーに対応していることに目をつけた、その場に居た写真屋さん。
なんで写真屋さんがこの場にいるんだって思うかもしれませんが、学校行事の撮影とかよくあるじゃないですか。あれです。
「なら、カメラに写ってる人が大きい画面で自分の写り具合確認できたほうが良いですよね!ディスプレイ貸しますよ!」とカメラ屋さん。せっかくなのでお借りすることに。
とここでまた問題が発生します。HDMIパススルーのアウトにディスプレイを接続したことによって、カメラから来るマイク音声が今接続したディスプレイ側に行ってしまうように。途中にあるPCでマイク音声を拾えないのでこれでは困ります。
とここでまた写真屋さんがマイクとミキサーを持ってきてくださったので、カメラから来るマイク音声は使わずに、そのマイクとミキサーから来る音を使うことに。
文章ではわっかりづらいと思うので今の配線図を大まかな図に表しました。
はい、意外と複雑なことになりましたがこれで生放送の「ソース」の部分は完璧です。
遅延問題
先程から何度も申し上げてる通り、生放送の配信側のPCのネット接続はポケットWi-Fiです。接続が結構不安定なので、ある程度バッファが必要です。
すると、YouTubeの遅延オプションは必然的に「通常の遅延」を選択することになります。大体、この「通常の遅延」を選択すると、20~30秒ぐらいの遅延が発生します。
さてここでまた問題が発生します。確かに普通なら、通常の遅延を選んだとしても20~30秒の遅延が発生するだけ。これ以上何もありません。
ただ今回は、YouTubeに予めアップロードされた動画とYouTubeライブを1回1回切り替えます。
切り替えにはもちろんQuartzを使いますが、これはSocket.IOを使用しているので切り替えはほぼリアルタイムで行なえます。
ただ、YouTubeライブはどうでしょう。20秒~30秒ほど遅延があります。ですので、例えば普通の動画再生から生放送に切り替える時、動画再生が終了してからQuartzを使い生放送に切り替え、その後司会の進行が始まっては、クライアント側では、動画が生放送に切り替わってから20秒~30秒程度の空白が生まれてしまいます。これは流石に見るに堪えません。
ではどうするか。動画の再生が終了する20~30秒前(実際には余裕を持たせるために15~20秒前)に生放送の進行を始めてしまうのです。で、動画の再生が終わったらQuartzを使い生放送に切り替えます。すると、空白の時間は5秒程度で済みます。なので、当日はこういった、面倒&神経を使うことを1回1回行いました。
で、実際当日どうだったのか
ここまでの壮絶な?w検証もあり、万全を期した状態で当日を迎えました。それが一番最初の画像です。
ちなみにカメラ側はこんな感じ。ぼかしかけてますが、正面のディスプレイでカメラで撮ってる動画のモニタリングができます。
はい、で当日は、昼時のポケットWi-Fi回線混雑に多少巻き込まれましたが、なんとか特に重大な問題もなく進行することができました。
OBSのシーンのプリセットも作ってあったので、生放送の演出も上々、遅延問題による切り替えタイミングの時間計算などもミス無くこなせ、ほぼぶっつけ本番でやったにしてはかなりうまく行ったと思います。
総括
まず、生放送もアーカイブありでやったし、そもそも映像コンペだしで、行事の全てが動画に残るわけです。という意味では、思い出として残しやすい行事になったのでこれはこれで良いなと思いました。
そして、このレベルのクオリティの動画配信を他の学校のイベントで行うのはまず不可能だと思います。うちの学校でさえ、自分がもう来年は居ないので、来年はできないと思います。生徒会顧問がこういうテクノロジーに理解があったっていうのも大きいと思うし。今回は奇跡が起きたからできただけです。ネットワーク環境も学校によって千差万別。そもそも1教室単位で動画視聴ができる環境がない学校だって沢山あるはずです。今回の一件を通してつくづく感じるのは、日本の教育施設におけるIT設備というものがめちゃくちゃ未成熟ということです。確かにメインは教育なんだから、ガチガチにIT設備を整備しろとは言いません。でももう少しなんとかなるはずの部分も多いと思った今回の一件でした。
コメント
高校生で、こんな風に学校のイベントに携わって、自ら動いて配信準備するなんてすごいです。
出来ることから初めて、問題が起きたらつぶしていく。それだけのことがものすごく大変なのに、ちゃんと当日に成功させて、本当にすばらしいです。
ありがとうございます