## 概要
自社用の新規ビジネスとして、RTMPストリーミングサーバー、およびそのGUIフロントエンドや周辺ツールをC++を使ってフルスクラッチで開発しました。Linux,Mac,Windowsのマルチプラットフォーム対応。
## 背景
当時は、まだ動画のライブストリーミングサービスの黎明期で、存在自体が、いまほどには認知されていませんでした。Flash技術を通じてブラウザで簡単にライブ配信できる環境には可能性がありました。
RTMPの仕様自体が公開されていなかった(後程公開)ため、コミュニティーで行われていたプロトコルの解析結果や、その結果として実装されたOSSを参考にして実装しました。主要なOSSとしてはJavaで実装されたRed5などがありましたが、C++で実装することでより軽量かつハイパフォーマンスで、機能を限定するかわりにシンプルな設計とし、複雑な設定が不要な製品を目指しました。
## 技術的なチャレンジ
仕様非公開のプロトコルであり、対向のクライアントであるFlashプレイヤー自体も、スクリプティング可能な環境とは言え、内部的な動作はブラックボックスであったため、まず接続して最初に動画が再生されるまでが苦労しました。接続に成功している既存のOSSにログなどを仕込みつつ動作の流れを追ったり、Wiresharkを使って、接続時や再生時に実際にどのようなパケットが流れているのかを確認、あるいはメーリングリストでのコミュニティーの議論などを追いながら、ひとつひとつ問題を潰していきました。
Flashプレイヤーの更新によって、新しい動画フォーマット(H264)に対応するために、専用のハンドシェイク方法への対応が必要になるなど、プレイヤーの仕様変更への追随なども必要になりました。自分でプロトコルをしたわけではありませんが、これもやはり仕様が明示されているわけではないので試行錯誤が必要でした。
また、このエンジンを利用して、当時としてはめずらしい、Peer to Peer(配信者と視聴者の直接接続)での動画配信プロダクトの開発も行いました。Peer to Peerで配信する再にネックになるのはNATで、どうNAG越えを実現するかが課題でした。STUNTというTCPでNAT越えをする技術に着目しましたが、多くのルーター(全部ではない)が持っている明示されていない特性を利用する技術で、実装難易度が高そうなわりには、カバーできる範囲が100%になるわけでもないため、これは一端あきらめました。多くの家庭用ルーターが対応しているUPnP(UDPでルーター設定の変更などをできるプロトコル)を利用して、ルーター設定をアプリから変更することで対応しました。
エンジン自体はC++で実装していましたが、アプリ向けに柔軟な機能拡張ができるようにPythonインタプリタをエンジンに組込みました。上記のUPnP対応などもPythonスクリプトで実現しました。
サーバーは、メモリ消費を抑えたままでの同時接続性を実現するために、libevent(libevの前身)を使用して、非ブロッキングソケットを用いたイベントモデルを採用しました。ただし、イベントモデル(=単一スレッド)だとCPUコアを十分に活用できないため、マルチスレッド+イベントモデルという形でより高いパフォーマンスを発揮できるサーバーを目指しました。マルチスレッドにしたときに、スレッド間の通信手段が必要になりますが、こにはパイプを使うことにより、非ブロッキングイベントモデルのレースコンディションを気にしなくて良いという特性を活かしたままスレッド間通信を実現できました。
ただ、結果的にマルチスレッド化したことによりコードベースは複雑化してしまい、今思うとオーバーエンジニアリングだったように思います。今であれば、よりクリーンな実装が可能な単一スレッドのイベントモデルで実装します。配信サーバーは長寿命のプロセスになるため、数週間起動していると、いつの間にか落ちているということもままあり、安定化にはかなり苦労しました。