ストリーム永続化及び静的ファイルのライブストリーム化に関する考察


ストリーム永続化に関するメモ書きが結構溜まってきたのでまとめておく。うまくまとまる保証はござらんよ。

ストリーム永続化でプレイリスト読み込みする場合、ファイル読み込みによるストリーミングも実装しておきたい。
なので、静的ファイルをいかにしてストリーム化するか、を考察してみる。
即ち、動画プレイヤーをキャプチャしてストリーム化するのを内部的にやってしまおうという魂胆だが、さてどうすればいいか。

先に永続化処理をを完成させてしまうのが前提。MMSレベルでの同一フォーマットデータストリームの完全交換を行う。
ベースストリームを常時流しておく、という点は良いだろう。
切り替え手順を、Xストリーム完了→Bストリームに変更→Yストリーム接続→Yストリームに変更 とする。
シームレス切り替えはまた後日だなー
Bストリームは常にフレームを製造し続ける(あるいはダミーフレームだが)ので、フラグでフレームをソケットに書き込むかだけ分岐すればよい?
切り替え処理のAtomicityを保証する必要があるかな。タイミングはエンドコードにしたいが、常に来るとは限らんから、入力プロセスの終了を充てる?
あとエンドコード($E)パケットは流さないで無視。
一定量のフレームが届かない場合は自動的にベースフレームに切り替える仕組みが必要。なので、フラグではなくステータス管理だね・・・
どうやって検出しようか?アラート?タイムアウト秒以下で一度流す感じになるか。ONCE_FRAME_SENDって感じ。

NextSreamステータス管理方式としてみようか。場合によって終了時に次候補を設定したり、終了前に流したりする感じで。
テレビ的に使うなら時間指定してストリーム読み出し始めるから、そのパターン。逆にファイルベースなら先に解析してしまえば終了時刻わかるからいけるだろうか
やっぱりFIFO(リングバッファ)は必要くさいな。1024バッファで満タンになったらffmpegへの要求を止める感じにしようか。
でもこれだとバックグラウンドで流し続けるのができない。うーむ・・・やはりダミーソケットの向き先にプレビューを用意する?考えようによっちゃ一石二鳥かもしれない。

バッファの使い方
$Eまたはプロセスの終わりが来たら、「次のストリームを呼ぶ」ロジックを走らせる。なければベースストリームを充てる
バッファが空になっていたら、ベースストリームで埋める。Bストリームは一瞬で埋めてしまう気がするが。
ソケットも同様。クライアントソケットがいなければダミーソケットに充てる。そっちはプレビュー再生用で、見る見ないはスイッチするが常時走らせておく(別スレ)
これをプレビューソケットと呼ぼう。ちなみにASFヘッダはベースストリームの奴で固定。
問題はクライアントソケットがキュータイミング同期できるかだな。鏡の仕組みによるんだと思うが。。。たぶん来たもの全部バッファリングだよなあ

じゃダメだ。考え直し。フレーム転送に速度制限入れるのは必須だな。うーんやっぱりfps管理するしかないのだろうか。というかパケットだな
1秒間に送れるフレーム量はどうやって算出する?MMSチャンクレベルの話だから難しいな・・・ライブストリームだとその辺の情報潰れてるはずだしな
しかしffmpeg上でfpsは管理できることを考えると、ある程度の常識的な出力は可能なのだろうか。Bフレームの製造数でタイミングを取るか?
サーバ起動→経過時刻で製造した、いやプレビューソケットに書き込まれたBストリームのフレームを割ることで、秒間書き込み数は算出できると思う
これを速度指標として演算し、敷居値を超える場合はwaitをかけてクライアントソケットへの書き込みを停止する、だな
これなら一般ストリームは速度を越えることはなく、ファイルソースストリームは書き込み速度を制限できるだろう。

結論
・ベースストリームとプレビュークライアントを常設しておく。
・ソケットへの掃きだしは、フレーム速度制限で調整する。
・ソースストリームの読み込みは、リングバッファの状態で切り替える。

EEでファイルソースを選択することはできるが、これはあくまでyoutube的なストリームサーバを企図しているもので、テレビ的な不可逆ストリームの製造とは違うんだろうな。

コメントを残す

メールアドレスが公開されることはありません。

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)