時雨堂の自社製品の 2024 年を雑に振り返っていきます。2025 年にやりたいことについてはこちら。
WebRTC SFU Sora
WebRTC SFU Sora は時雨堂が開発しているパッケージソフトウェアです。2024 年は実現したかった大きめの機能を追加できました。
Raft ベースの分散システムへ
2024 年から Sora を Raft ベースの分散システムへの切り替えを始めました。一番の目的はスケールアウトです。WebRTC や MOQT (Media over QUIC Transport) は 1 チャネル(ルームと同じ概念)に大量のコネクションを張るとき、1 台のサーバーで頑張るのが現実的ではないという問題があります。
この問題を解決するため、多くの場合は多段構成(Origin -> Edge)を取るのですが、その場合は運用側への負担がとても大きくなります。Sora はパッケージソフトウェアと言うこともあり、運用側への負担を限り無く減らす必要があります。そこで選択したのが Raft ベースの分散システムです。
Sora を複数上げクラスターを構築し、どのノードに接続しても同じチャネルに参加できる、という仕組みがあればスケールアウトができるようになりました。
これにより WebRTC はスケールしないという問題を解決できるようになりました。
MP4 録画機能
Sora の強みの一つが無変換の録画機能です。再エンコード無しで録画ファイルを生成できます。ただし、今までは WebM 形式でのみの出力となっていました。これは MP4 が壊れやすいのと、WebRTC で利用する Opus や VP8 といった形式が MP4 には正式に対応していなかったというのがあります。
ただ、 Sora が H.265 に対応したことにより、H.265 の録画に対応する必要がありました。H.265 は WebM には対応しておらず、MP4 に対応する必要があります。
そんな中、MP4 が壊れやすいと言う問題に対して OBS が解決策をだしてきました。それが Hybrid MP4 です。これは簡単に言うと録画が正常に終了するまでは Fragmented MP4 として保存し、正常終了したタイミングで通常の MP4 ファイルとして保存するという仕組みです。これにより懸念だった MP4 の壊れやすさを解決できる事になりました。
もう一つの懸念であった Opus の MP4 対応は、ISOBMFF が 1.0.0 がぬるっと 6 年越しで出ていました。これにより懸念材料は VP8 だけになりましたが、どうやら MP4 で VP8 は無理矢理動かせそうなこともわかりました。
Sora は Erlang/OTP というマイナー言語で書かれているため、もちろん OSS で安定的にメンテされている MP4 ライブラリなんかありません。1 から ISO から資料を購入して開発し、無事 MP4 ファイルに対応することができました。
Sora Cloud
Sora Cloud は WebRTC SFU Sora のクラウド版として時雨堂が運用して提供しているサービスで、時間や転送量で課金されないサービスです。
グローバル LB サービスが突然停止する障害
2024 年は激動の 1 年でした。6 月に突然利用していたグローバル LB サービスに障害が発生し、完全に利用ができなくなりました。サービス提供事業者からは一切説明もなく、数週間止まったまま、まともな対応はありませんでした。障害当日にグローバル LB を利用するをしない構成に変更し、約 3 時間のサービスダウンで復旧しました。
これにより、このサービスを利用するのは継続的なサービス提供には無理と判断し、サービスの切り替えを進め始めました。
もともとこのグローバル LB サービスは WebSocket を突然切断してしまうと言う問題があり、サポート契約をしているにもかかわらず、半年以上放置された経験があり信頼がかなり薄らいでる中での障害でした。
DataPacket から Akamai Connected Cloud への切り替え
上記の問題と、Raft ベースになったことにより大きめのサーバーを利用する必要がない事もあり、DataPacket (ベアメタルクラウドサービス) から Akamai Connected Cloud への切り替えを決めました。
Akamai への切り替えは、セキュリティに強いこと、サポート対応がしっかりしていること、転送量価格が安いこと、ネットワークがしっかりしていること辺りが条件でした。既に仕事で大規模利用している友人にも相談したりしました。
実際 Akamai はサービスとしてとても安定しており、サーバー費用も 1/5 になりました。
6 月に移行を決めて、8 月に移行を完了し、それから 1 度も障害が起きていません。
Sora SDK
SDK は積極的なメンテナンスをするだけでもかなりリソースを使うのですが、なんとか一つ新しい SDK を提供する事ができました。
Sora JavaScript SDK を依存ライブラリ 0 へ
Sora のブラウザ向け JavaScript SDK は deflate を利用するために、外部ライブラリを利用していましたが、ブラウザ標準ライブラリとして提供している Compression Streams API を利用する事で、依存ライブラリを 0 を実現しました。
Sora C SDK の開発
時雨堂では WebRTC クライアントは全て Google が開発している libwebrtc を利用してきました。libwebrtc はあまりにも巨大過ぎるということで、WebRTC で新しいく、libwebrtc に未実装の機能を試したり、スペックの低いマシンで利用する事を想定したライブラリを開発することにしました。それが libdatachannel を利用した Sora C SDK です。
実際 Sora C SDK のでマルチコーデックサイマルキャストという、同時に複数のコーデックを利用し、複数の画質での映像を配信する仕様をかなり短期間で実装し検証する事ができました。
Sora ツール
Hisui を Rust 化
WebRTC SFU の課題である録画したファイルは必ずコネクション毎に分割されてしまうという問題を解決ツールとして Hisui という録画ファイルの合成ツールを提供しています。これをブラウザでの提供も見据えて、 C++ から Rust への切り替えをする事に決めました。
MP4 ファイルの取り扱いをしっかりやりたいということで、まずは Rust の MP4 ファイルを依存ライブラリ 0 で開発をすることにしました。
https://github.com/shiguredo/mp4-rust
ブラウザの WebCodecs との連携も想定しているため、WebAssembly を利用して、ブラウザで MP4 の構造を JSON として出力したり、ブラウザで WebCodecs を利用して MP4 をトランスコードするサンプルも開発しました。
その他
DuckDB / DuckDB-Wasm の導入
顧客から送られてくるログ解析をどうにか気軽にやる方法はないかと色々模索していて、決定版が DuckDB でした。複数の圧縮された JSON Lines のログを読むことができ、DuckDB さえインストールしておけば SQL を共有するだけで他のメンバーとの共有も簡単というものです。
これにより劇的に解析が楽になり、解析の幅も広がりました。今まで解析した内容を SQL として残しておけます。
また自社サービスの管理/顧客向けの可視化をを低コストで実現するという課題も、S3 互換オブジェクトストレージというコストパフォーマンスが良い製品と DuckDB-Wasm を組み合わせることで解決できました。