携帯動画をサーバで動的に FLV に変換したリ、mov などの動画ファイルを QuickTime Pro などのオーサリングソフトフェアで FLV 書き出しした場合、"モノ"によってはエンドが取れない FLV が混在する。言い変えれば60秒の動画が 59.382 秒とかで実質止まってしまうのである。(このエンドを取れない動画は特定の携帯機種に依存しているのか、変換時の問題なのか、動画作成時の問題なのかよく分からないので、この問題に関して分かってる人は教えていただきたい!)

エンドが取れない FLV のエンドを取る方法
動画のエンドを取る方法は、NetStream Object の onStatus イベントハンドラへ渡る情報オブジェクトの code プロパティが NetStream.Play.Stop に一致するのを確認するのが一般的だと思うのですが、エンドの取れない動画に関してはこの一致を確かめる事が出来ない。つまり、例えば、10個の動画を次々と流していく時に、NetStream の onStatus イベントに頼っていると、エンドの取れない動画で止まってしまうのである。
ここで代案として行ったのは、Flash Video Exporter ユーティリティ (バージョン 1.1 以降) で動画を FLV 変換する事で動画に組み込まれる Meta データの duration 値と NetStream の time プロパティを絶えず比較して、動画のエンドを確認する方法がである。こっちの方が経験上、問題を回避する可能性が大きいだろう!この NetStream の time プロパティと duration を絶えず比較する方法だが、おそらく onEnterFrame か setInterval のどちらかだと思うのだが、試した際 onEnterFrame の場合はフレームレートに依存するがあまりにも早く反応してしまうのでここでは適さず、今回は setInterval で 500 ミリセカンド毎に(このミリセカンドくらいがちょうど良かった。)比較用関数を呼び出すことにした。
サンプルソースは下記の通りである。
(このソースは、分かりやすさ優先で1つの動画が終了した時点で clearInterval しているが、連続する場合は次の動画を再生する関数と、clearInterval は使用しないようにする。)
// NetConnection オブジェクト設定
var nc:NetConnection = new NetConnection();
nc.connect(null);// NetStream オブジェクト設定
var receive_ns:NetStream = new NetStream(_root.nc);
receive_ns.play("FLV 名");
video_obj.attachVideo(receive_ns);// onStatus イベントハンドラ
receive_ns.onStatus = function(infoObj:Object):Void {
switch(infoObj.code) {
case "NetStream.Buffer.Full":
if(!initFlg) {
checkTime();
initFlg = true;
}
break;
default:
trace(infoObj.code);
}
}// Meta 情報から duration を取得
var duration:Number;
receive_ns.onMetaData = function(infoObj:Object):Void {
duration = Math.floor(infoObj["duration"]);
}// NetStream.time と duration の比較
function checkTime():Void {
function checkEachTime():Void {
if(receive_ns.time >= duration) {
clearInterval(progNum);
trace("動画が終了");
}
trace(receive_ns.time);
}
var progNum:Number = setInterval(checkEachTime ,500);
}
今回は動的に動画を作成したりする環境で、動画を1つ1つ確認できない環境下での動画の連続再生に適しているだろう。もし動画が確実にエンドを取るのを確認できる場合にはonStatus イベントハンドラのNetStream.Play.Stop で操作する方が効率いいだろう。
個人的には NetStream の onStatus が、http 通信下の不安定な状況下で予想外の挙動をするので setInterval を使うようにしている。他にも方法があると思うので、この問題を回避したという方は教えていただきたい。











