FLVファイルの再生時間の取得方法

FLVファイルの再生時間を取得するにはonMetaDataを
使うのが普通らしいけど、FLVのバージョンによっては
このonMetaDataがない場合がある。

onMetaDataがある場合は
// var my_ns:NetStream;
var totaltime;

my_ns.onMetaData = function(infoObj) {
totaltime = infoObj.duration;
};

で取得できる。
これについてはネット上にやり方が書いてあるページが
たくさんあるからいいけど、これが使えない場合には
Google先生で調べた結果、最後まで再生するしか方法がないようだ。
(探し方が悪いだけかもしれないが)

そこで、再生するしかないなら早送りすればいいじゃないと
いうわけで無理やり再生時間を調べてみた。
やり方としてはNetStreamのseekメソッドを使って
適当に再生位置を移動してみるだけ。

具体的には、まずここまでは再生時間はないという上限を調べるために
シークに失敗するまで、現在の再生位置の2倍の位置にシークし続ける。
シークに失敗したら再生時間の範囲が分かる(直前の再生位置とシークに失敗した再生位置の間)から、
あとはその範囲内を2分探索のように調べていく。

その再生位置が有効かどうか&再生が終了しないか調べるために
シークしたら一定時間(今回は10秒とした)待ち、再生が終了しなかったら
さらにシークするようにした。
再生が終了したら当然再生時間はそのときの時間ということになる。


ソースはこんな感じ。
// ボリュームを0にする
var sound_mc = "hidden_mc";
_root.createEmptyMovieClip(sound_mc, 1);
eval(sound_mc).attachAudio(ns);
var sound = new Sound(eval(sound_mc));
sound.setVolume(0);

var totaltime = 0; // 再生時間
var down = 0; // 再生時間の下限(ここまでは確実に再生できる)
var cur = 0; // 次に移動する再生位置
var up = undefined; // 再生時間の上限(ここは確実に再生できない)
var timer = undefined; // タイマーのID

function seek() {
clearInterval(timer);
timer = undefined;

// 現在の位置までは再生できる
down = ns.time;

if(up == undefined) {

// 上限がまだわかっていないときは
// とにかく再生時間の上限を調べるために
// 現在の位置を2倍した位置を調べる
cur = 2 * down;

} else {

if(up - down < 10) {
// 試しに再生してみる時間(ここでは10秒)よりも
// 調べる範囲の方が短かった場合は
// その範囲をすべて再生してみる
cur = down;
down -= 7; // 万が一のために調査範囲を広げる(数値は適当)
up += 5;
} else {
// 上限と下限の中間の位置を調べてみる
cur = (up + down) / 2;
}
}
ns.seek(cur);
}

ns.onStatus = function(info) {
if (info.code == "NetStream.Buffer.Full") {
// バッファリングが完了したとき以外に
// 移動が完了したときにもこのメッセージがくる

if(timer == undefined) {

// 10秒間待機
cur = this.time + 10;
timer = setInterval(seek, 10000);
}
} else if(info.code == "NetStream.Buffer.Flush") {
// 再生が終了したときにこのメッセージがくる

clearInterval(timer);
totaltime = this.time;
this.close();
} else if (info.code == "NetStream.Seek.InvalidTime") {
// 移動に失敗したときにこのメッセージがくる

// 現在の位置は再生できない
up = cur;
if(up - down < 10) {
// 試しに再生してみる時間よりも調べる範囲の方が短かった場合は
// その範囲をすべて再生してみる
cur = down;
down -= 7;
up += 5;
} else {
// 中間の位置を調べる
cur = (up + down) / 2;
}

this.seek(cur);
}
}


注意事項
・かなり頻繁に再生位置を移動させるのでメモリに負担がかかりそう。
・メッセージについては結構勘でやっているので
もしかしたら違うかもしれない。
・実行するたびに取得する時間が違うことがある。(0.5秒くらい)
・10秒待つので結構時間がかかる。

まあ全部普通に再生させるのが一番確実だとは思うけど、
こんな方法もあるよということで。

ただ、正確さがいまいちなのが駄目だなぁ。
手抜きをしようとしてるんだからしょうがないけど。

posted by oi at 2006年04月20日 01:10 | Comment(0) | TrackBack(0) | Flash
この記事へのコメント

この記事へのトラックバック
×

この広告は1年以上新しい記事の投稿がないブログに表示されております。