2012年10月3日水曜日

多重コンバートまわりとsegment作成まわり、よしなしごと。

多重コンバートはとりあえず成功したのですが、まだ動作不備がぽろぽろあるみたいでした。

そんな中からいくつか情報をピックアップします。

1つ目:コンバート動作を増やすと、開始が遅れる。

これはプログラムの構成に問題があります。
僕のつくっているプログラムでは、サーバーからrtmpでダウンロードしてきたデータをflvの形に復元しつつqueueにためて、別の変換用threadで適宜コンテナの開け閉めを実行しています。
中途で音声データが映像データが追加された場合に、コンテナを開き直して次の処理に入るようになっているのですが、これがまずいみたいです。
コンテナを開き直してエンコーダーやリサンプラーを再生成するようになっているのですが、ここで時間がかかるみたいです。コンバート数がおおいと、この変換の部分の処理が増大してしまい、結果として次のデータの処理になかなか入れない→遅延が発生するということが発生するみたいです。
実際11変換(flv6つ mpegts3つ webm2つ)変換しているときには30秒近く遅延していたのが、2変換にしたところ遅延が6秒ほどになりました。同じencoderのグループごとにマルチスレッド化した方が効率はよくなりそうですね。
なお、今回は音声コンバートのないデータで実験したので、音声のあるストリーミングを変換するともっと遅延しそうです。

2つ目:aggregate messageの扱いはデフォルトのflazrの動作の方がxuggleの変換に優しいみたい。

前日に実験したときには、FlashMediaLiveEncoderで1024x768サイズのh.264を配信し、そのデータを変換かけてみたのですが、x264の変換ミスが発生しました。
[ffmpeg] - [h264 @ 0x7fdd5c001700] AVC: nal size 498212287
こんなメッセージがでます。
このエラーメッセージがどうしてでるのかは、いまのところ不明です。変換がダウンロードにおいついたり、サイズが大きすぎるとh.264のHD用の処理がつかわれていたり等、いろいろとなにかがあるのかもしれません。
正直なんともいえないです、デフォルトのflazrの動作の方がよさそうというのも単なるカンです。


以下はsegmentに関する情報のメモ
1:mpegtsのsegmentはどうやらぶつ切りにするより、並べるときちんとしたmpegtsファイルになるように調整した方がよさそう。

segmenterのプログラムで切ったときもそうなんですが、切ったtsファイルを再生しようとすると、開始までに時間がかかったり、m3u8からiphoneで視聴してたりすると、たまに再生がはじまるまで時間がかかる時があります。
なぜかというと、h.264のキーフレームが先頭にない状態でぶつ切りにしている性みたいです。
mpegtsでは、188バイトのデータがならんでいるのですが、動画部にはいると
「動画情報+キーフレーム+中途フレーム」
がなんども繰り替えされます。
動画の情報の部分でうまくきってやると、うまくいくという次第です。
この先頭の個人的にみつけた判定方法は
47 41 00からはじまり5バイト目から2バイト分 75 00がつづき11バイト目から5バイト分00 00 00 01 E0がくるデータがそうであると判定してよさそうです。
例としてはこんな感じ

[47 41 00] 30 [07 50] 00 00 00 00 FE [00 00 00 01 E0] 0A 2F 80 80 05 21 00 01 00 03 00 00 00 01 09 ....
実際にhexを編集できるエディタでmpegtsのファイルからこの部分をいくつかみつけて、先頭にもってきたりすると、中途から始まる動画データをつくることができました。

2:webmのsegmentについて

webmのストリーミングは次の形でつくれるみたいです。
http://www.matroska.org/technical/diagram/index.html
ffmpegでwebmを出力すると、(変換途中でプロセスを殺したりすると次のようになります。)

Header
Segment Info
Cluster
Cluster
Cluster
...
みたいな形になっていました。

いろいろためしたところどうやらheader + segmentInfoをヘッダとして保持。
clusterをそれぞれの分割パケットとしておく。
新規アクセスがあった場合は、httpの応答でheader + segmentInfo + 最新のclusterとその続き
をおくりつづけてやれば、ライブ再生できそうです。
cluster1つはだいたい1分?数秒?程度のデータがはいっていたので、ちょうどよさそうです。
他のストリーミングと同じようにsegmentファイルをいくつもつくっておいて、httpでwebmの再生の要求がきたらそのsegmentファイルを組み合わせてうまく応答する・・・
これでいくのがベストっぽいですね。


とりあえず、こんなとこです。segment分割部分をはやくつくりたいけど、その前にまずはコンバートの安定ですね。

0 件のコメント:

コメントを投稿