iOSDC Japan 2022を主催した

去る2022年9月10日(土)〜9月12日(月)にiOS関連技術をコアのテーマとした草の根技術カンファレンスiOSDC Japan 2022を主催しました。

今回の開催は早稲田大学 理工学部キャンパス(オフライン)とニコニコ生放送(オンライン)のハイブリッド開催でした。iOSDC Japanは2020年, 2021年はオンライン開催だったので実に3年ぶりのオフラインを含む開催になりました。

続きを読む iOSDC Japan 2022を主催した

OBS Studioを操作するプログラムを書いてPHPerKaigi 2022のトーク動画をスケジュール配信した

4/9(土)〜4/11(月)にPHPをコアのテーマとした技術カンファレンス、PHPerKaigi 2022を主催しました。

今回は過去開催を通してスポンサー数、参加者数ともに最大になり、また久しぶりのオフライン会場でみなさんが楽しそうにしている様子を見られて主宰としてもとても嬉しい開催でした。

スポンサー、スピーカー、参加者、そしてスタッフのみなさま、ありがとうございました。

この記事では、今回初の試みとしてトーク配信の自動化に挑戦しましたので、その設計や実装についてご紹介します。

ネットワークの弱い環境でのオンラインイベント

PHPerKaigi 2022のメインコンテンツはPHPerたちによる技術トークです。今回の開催はオフライン会場(練馬区ココネリホール)とオンライン(ニコニコ生放送)のハイブリッド開催でしたが、企画段階では新型コロナウイルス感染症の感染拡大状況が読めず、場合によってはフルオンライン化の可能性もありました。

そのため、PHPerKaigi 2022はすべてのレギュラートーク(20分/40分)は事前収録して、オフライン会場では収録された動画を見る「パブリックビューイング」として開催しました。

iOSDC Japan 2020, 2021, PHPerKaigi 2021の3回、この形式でフルオンラインのカンファレンスを経験したので、事前収録と、事前収録した動画の配信には不安はありませんでした。

一方、オフライン+オンラインのハイブリッド形式は今回が初でした。さらに今回使用した会場には安定したネットワークが無く、フレッツ光などの固定回線を引き込むこともできないということで、動画の配信についてはリスクを下げる施策が必要でした。

今回はそのための施策としてAWSに立てたサーバから動画を配信するという方法を採用しました。

OBS Studioの使用

私の主催するカンファレンスでは2019年からOBS Studioを使っています。

OBS Studio (macOS版)

2019年〜2020年のオフライン開催では会場でOBS Studioを使ってスライドのHDMI画像とビデオカメラで撮影しているスピーカーの顔を合成して1つの動画にして、会場のスクリーンに投影したりYouTubeでのアーカイブ用に録画したりしていました。

また、2020年からのオンライン開催でもOBS Studioを使って事前収録された動画をニコニコ生放送に配信していました。(この録画・配信システムについては過去記事で紹介していますので興味ある方はご覧ください。)

そのため、OBS Studioの扱いには一定の経験値が蓄積されており、今回もコアはOBS Studioとしました。

どこでOBS Studioを動かすか

OBS Studioでは動画のリアルタイムレンダリングをするので基本的にはGPUが必要です1

私たちの録画・配信システムはOBS StudioをWindowsで使用していたので当初はどこかにWindowsインスタンスを立てて、と考えていたのですがGPU付きでWindowsを気軽に使えるサービスが見つけられず、またOBS StudioはWindows版, macOS版に加えてLinux版もあるということで、最終的にはAWSのEC2にLinuxのGPUインスタンス(g4dn.2xlarge)を立てて配信しました。

AWSのGPUインスタンスはNVIDIA T4 GPUを搭載したG4dnインスタンスとAMD Radeon Pro V520 GPUを搭載したG4adインスタンスがあります。今回はG4dnの中から、vCPUが8つ & メモリ32GBの g4dn.2xlarge というインスタンスを使用しました。

g4dn.2xlargeは東京リージョンでは$1.015/hourで使えます。開催1週間ほど前からリハーサルのために起動し、最終的には$350ほどの費用でした。

g4dn.2xlarge

PHPerKaigi 2022の動画は1,920×1,080 30fpsを基本にしていますがg4dn.2xlargeインスタンスでドロップすることなく安定して配信できていました。

ただ、あまりインスタンス比較を真面目にやっておらず、同一vCPU数 & メモリ数では半額になる G4ad インスタンスや、同じ G4dn インスタンスでも1つサイズの小さい g4dn.xlarge でも配信できた可能性はあります。次回以降はチューニングを試してみようと思います。

OBS Studioをどの様にコントロールするか

OBS Studioにはobs-websocketというプラグインがあり、これを使うとOBS StudioをWebSocketでコントロールできます。

PHPerKaigi 2022のタイムテーブル(= トークの放映タイミング)は私が開発・運営しているforteeが持っているのでforteeからトークの放映タイミングを取得してそれに従ってWebSocketでOBS Studioをコントロールして決まった時間に決まった動画を再生できれば良いことになります。

これを実現するために「スケジュールを受け取るためのHTTP REST API」と「OBS StudioをコントロールするためのWebSocket」を話すプログラムをGoで書きました。

https://github.com/hasegawa-tomoki/obs-controller

obs-controller

今回EC2に作ったサーバではApache + Let’s Encryptでobs-controllerのlistenするhttpをリバースプロキシしてforteeとの通信はhttpsにし、obs-controlelrはsystemdで起動しています。

Goを初めて使ったのでプロセス間通信はじめ相応の苦労があり自分で見ても美しくないプログラムなのですが、イベント開催日という締切がある中でなんとか書き切れて安心しました2

Goの達人のみなさま「ここはこうするんだぜ!」というのがあればPRお待ちしています。

fortee側実装

OBS Studioを使った過去の開催の経験から、カンファレンス当日には以下の操作が必要なことがわかっていました。

  1. トーク開始前にトーク用シーンの動画ソースを次のトークのものに差し替える
  2. 指定時刻になったらシーンをトーク用のものに切り替える
  3. トークが終わったらシーンを幕間(トークとトークの間)用のものに切り替える
  4. 幕間は複数のシーンを順番にループして切り替える

今回は、forteeにトーク時刻とトーク動画を指定して放映スケジュールを作る機能と、シーンの遷移(シーンシーケンス)を定義する機能を作りました。

スケジュール機能
シーンシーケンス機能

この例だと以下の様な動作になります。

  • 11:35になる少し前3にトーク用シーンの動画ソースを「PHPでEventLoopを書いて〜」のものに差し替える
  • 11:35になったらシーンをトーク用のものに切り替える
  • 11:35から23分44秒後にシーンを「[幕間] 30sec Track-me」に切り替える
  • 30秒後にシーンを「[幕間] 15sec Track-another」に切り替える
  • シーンを順番に切り替え「[幕間] 10min41sec Information」が終わったら次は一番上に戻る
  • 12:10になる少し前にトーク用シーンの動画ソースを「大規模サービス〜」のものに切り替える
  • (以下同じ)

つまり基本は「特定時刻に特定シーンに切り替える」「シーン切替後、一定の時間が経ったら次のシーンに切り替える」と、「シーン切替前に準備をする」だけです4

テスト

このシステムは今回初稼動で設定時に現場で苦労しそうだな、ということでforteeの各所にテスト機能を付けていました。

例えば、スケジュール機能の個別のトークとか、各シーンシーケンスにテストボタンを付けていて、押すとOBS Studioが個別トークの再生を開始したり、シーンシーケンスが動きだしたりする様になっています。

また、作成したスケジュール全体のテスト(リハーサル)のために「いま設定されているスケジュールから〇〇分引き算して実行」みたいなことができる様にして、プログラム完成から当日までの間に2〜3周リハーサルを回しました。

スケジュールテスト

このリハーサルの間にWebSocketのメッセージを取りこぼすバグが見つかったり、トーク名にダブルクオートが入っていると再生できない(恥ずかしい)バグが見つかったりしたので「やってよかった」という工程でした。

使ってみてどうだったか

ということでギリギリに完成し最低限のリハーサルで本番投入されたシステムでしたが、蓋を開けてみれば大安定で、何の問題もなく2.5日の開催を走り切れました。

Goのプログラムはひたすらイベントループを回ってる様な感じなので、よくもまあこんな長時間動き続けるものだと感心しました5

今回の開催ではまだ手動でタイムテーブルに従って設定変更していく様な箇所が残っていたのですがその箇所も自動化することはできるはずなので「事前収録したトークをタイムテーブルに従って放映する」「トークとトークの間は一定のパターンで動画を流す」という運営であれば全自動で実施できる様になるはずです。

「事前収録のオンラインカンファレンス」という形態がいつまで続くかはわかりませんが、ここ数年進めている「コードを書くことでカンファレンス運営にかかる工数を削減する」という試みは今年も成功できたな、と思っています。

と言う訳で…

ネットワークの弱い会場を使ってオフライン・オンラインのハイブリッド開催をしたよ、というレポートでした。

ややヒヤヒヤしたけどGoを初めて書いて動くモノが作れたし、作ったものが有効に動いてカンファレンス運営がとてもラクに安定したのでだいぶ満足度の高い開発でした。

obs-controllerのソースコードは公開していますが「誰でも簡単に使える機能」という感じではないのでfortee側では今回のOBS配信機能は(Zoomを使った事前収録システム同様に)特別に設定したカンファレンスでのみ使える様にしています。私がサポートスタッフとして入れば使うことも可能と思いますので興味がある方はTwitterででもお声がけください。

iOSDC Japan 2021を主催した

去る2021年9月17日(金)〜19日(日)の日程でiOSDC Japan 2021を主催しました。

iOSDC Japanとしては6回目の開催、2020年に引き続いてのオンライン開催となりました。フォーマットとしては「LT以外は事前収録」「LTはZoomでライブ」という形で、2020年と同じ形でした。

iOSDC Japanではだいたい毎年何かしら新しい試みをしているのですがiOSDC Japan 2021では事前収録したトークの呼び込み(タイトルとスピーカー名の読み上げ)動画のナレーションを立木文彦さんにお願いしました。

このナレーションはニコ生でのライブ配信と1ヶ月間のアーカイブでしか聞けなかったのですが、立木文彦さんの声が呼び込みにとてもマッチしていて、編集動画の確認をしている時から「早くこれを参加者のみなさんに聞いて欲しい」とそわそわしていました。

当日の盛り上がりも予想どおりで、お願いしてよかった、またお願いしたい、と思えるものでした。

この呼び込み動画は例によって長谷川が開発運営している fortee の一機能、オンラインカンファレンス向け事前収録システムへの機能追加として実装しました1

実装としてはシンプルで、以下の様な手順で作っています。
1)ナレーション音声ファイルの長さを調べる
2)トークタイトルやスピーカー名が表示されたカバー画像を作成する
3)カバー画像から、ナレーション音声の長さ + 3秒程度のカバー動画を作成する
4)カバー動画にナレーション音声を合成する

これはすべて ffmpeg コマンドで実現可能で、PHPからシェル経由でffmpegコマンドを実行して実現しています。「シェルからffmpeg」という芸はたいへん高機能かつ柔軟で重宝しています。高機能が故にコマンドラインオプションがプログラムみたいになってたいへんですけど!

という訳で、最高のナレーションでスピーカーのみなさまをご紹介できた、というiOSDC Japan 2021の開催報告でした。

電動キックボード ZERO9 を買って100kmほど走った

日本国内で公道を走行できる電動キックボード、ZERO9を買って100kmほど走ったのでそのインプレッションなどを。

購入の経緯

新型コロナウィルス感染症の影響でライフスタイルが変わり、徒歩10分前後の距離を週数回往復する生活が始まりました。

徒歩10分なんだから歩けば良いのですが、その道がすごいつまらない道なのでラクをしたい。移動のラクと言えば自転車ですが個人的に自転車がすごく嫌いなんですよね。乗ろうとするたびにタイヤの空気抜けてて1

そんな時ふとTwitterのタイムラインで電動キックボード買った話を見まして、ほほ〜なるほどそれはアリだな、ということで国内販売で公道を走れる電動キックボードを何種類か比較して、ZERO9を購入しました。

ZERO9
https://zero9.hop-on.jp

続きを読む 電動キックボード ZERO9 を買って100kmほど走った