AIRやFLASHなどを表示するのに不便なので、ブログから自作サイトに移転します。

N2-Works移転先

今後はこちらで更新を行っていきます。


FLVPlayer制作第5回はMetaDataについての続きです。


前回 、MetaDataの中にdurationプロパティがない場合とMetaData自体が存在しない場合、動画の総再生時間が取れない問題が発生していました。


かなり強引なやり方で、その問題を解決する方法があると書いたと思いますが、このやり方はFLVフォーマットを解析して行うというような正式なやり方ではありませんので、取得できないケースがあることをあらかじめご了承下さい。


ではそのやり方を以下に記します。


実はNetStream.seekメソッドに失敗した時のコールバック情報NetStatusEvent.info.detailsに総再生時間が挿入されているのです。


つまり動画を一度再生させた後で、わざとシークエラーを発生させればコールバック情報から総再生時間を取得できます。


NetStream.seekメソッド の引数は動画の位置(秒単位)を指定します。シークエラーを起こすにはシークできない位置の秒数を引数に指定してやればいいでしょう。


そこで最初に考えたのが-1を指定すればよいのではないかということです。ですが、予想に反してシークエラーは発生しませんでした。


どうやらマイナスの値はそもそも受け付けていないのかもしれません。そうなると動画の最終秒より大きい値を指定するしかありません。


ただその動画の総再生時間が分からないので、最終秒は何秒なのかは分かりません。そこでできるだけ大きい数値を引数としてやる必要があります。


これも色々と試してみましたが、大きすぎる値だとシークエラーが発生しませんでした。仕方がないので動画の秒数としてはまずありえない値でシークエラーが発生するような値で妥協することにしました。


その値とは0xffffです。10進数にすると「65535」という値になります。これは秒単位ですから3600で割ると約18時間です。


こんな長い動画はありませんよね。これで確実にシークエラーを発生させることができそうです。


具体的なコードは以下のようになります。

// ストリームのシークにわざと失敗
stream.seek(0xffff);

// NetStatusEventのイベントハンドラ
private function NetStatusHandler(evt:NetStatusEvent) : void
{
    // 総再生時間格納変数
    var total_sec:Number;

    switch (evt.info.code) {
    case "NetStream.Seek.InvalidTime":	// ストリームのシークに失敗
        total_sec = evt.info.details;
       break;
    }
}


このように核となる考え方は単純なものなのです。ただ実装する際におそらく細々とした問題に直面する可能性があると思いますので、実装したフローを以下に示します。


1)onMetaDataが発生したかどうかを確認(フラグなどで対処)

2)NetStreamのbufferingがFullになった時にイベントが発生するので、
  この時点でonMetaDataが発生していなければ、その動画にMetaDataが
  存在していないので、シークにわざと失敗し、上記のように
  総再生時間を取得する。

3)動画を初期状態に戻して再度再生する。


一度動画を再生するので、上記のやり方で総再生時間を取得する場合、動画の状態を初期状態に戻さなければいけません。


ただこの辺りの実装は個々によって異なると思いますので、各自判断してやってみて下さい。


というわけでMetaDataに関しては今回で終了です。


次回は最終回としてSoundクラスについて書きたいと思います。