サイズの大きいFLV ファイルのストリーミングにおけるシーク処理の遅延の問題
問題点
FLV ファイルのストリーミング再生において、長尺のシーク(指定時間まで経過したところから再生を開始)を行ったとき、再生開始までに30秒程度の遅延が発生する場合があります。
この問題は次の状況において発生する場合があることが確認されています:
- 対象ファイルに対して Flash Communication Server 再起動後に行った最初の長尺シークである
- 対処ファイルのサイズは 300MByte 以上の比較的大きいファイルである
Flash Communication Server MX 1.5 は特定の時間からの再生を可能にするために、キーフレームをベースとしたインデックスを生成し、これをメモリーにキャッシュします。一度インデックスが生成されると、この情報をもとにシークが行われるため、処理は高速に行われるのですが、サーバー再起動後最初の再生でシークが行われたとき、インデックスの生成とシークが同時に行われることとなるため、レスポンスに時間がかかります。この時間は 300MByte を超えるファイルでは 30秒を超える場合があることが確認されています。
回避方法
回避方法としては次が考えられます:
回避方法1:FLV ファイルがネットワークドライブに配置されている場合、これをサーバー上のローカルドライブに移動する
今件における遅延の度合いはOS機能におけるファイル、メモリー間のデータ交換のスループットにある程度依存します。もしストリームファイルがネットワークドライブ上に保存されている場合、ファイルをローカルドライブに移動するなどの方法でスループットの向上を図り、改善が見られないかご確認ください。
回避方法2:運用方法で対処、現象を一般ユーザーが体験しないように考慮する
報告の現象は、サーバー再起動後の最初のシークでのみ起こります。このため、サーバー再起動後、管理者によって、各ストリームの再生を確認するようにすれば、現象を一般ユーザーが体験する状況は防ぐことができます。
回避方法3:回避用のスクリプトコードをサーバー側に設ける
報告の現象は、サーバー再起動後の最初のシークでのみ起こります。このため、サーバーサイドアクションスクリプトにて、ストリームの最初の読み込みとシークを自動で行うようにすれば、現象を一般ユーザーが体験する状況は防ぐことができます。
次はこのような処理を行うサーバーサイドアクションスクリプト main.asc のサンプルです。
// 自動先送り再生を実施する flv を定義
// [{app:"アプリケーション名/インスタンス名",
// name:"ストリーム名", time:ストリームの長さ(秒)},...]
var mlist = [
{app:"mystream1/myInstance1", name:"record1", time:6225},
{app:"mystream1/myInstance1", name:"record2", time:7000},
{app:"mystream2/myInstance2", name:"record3", time:4000}];
// ---------------------------------------------------------------
var conn;
var cnt;
application.onAppStart = function(){
cnt = 0;
conn = new NetConnection();
conn.onStatus = function(infoObj) {
trace("onStatus..:" + infoObj.code);
switch (infoObj.code) {
case "NetConnection.Connect.Success":
playVideo();
break;
case "NetConnection.Connect.Closed":
case "NetConnection.Connect.Failed":
case "NetConnection.Connect.Rejected":
case "NetConnection.Connect.InvalidApp":
case "NetConnection.Connect.AppShutdown":
case "NetConnection.Call.Failed":
cnt++;
playNext();
break;
}
}
playNext();
};
function playNext() {
if (mlist.length < cnt) {
trace("Connect to : " + mlist[cnt].app
+ ": Play[" + mlist[cnt].name + "]"
+ (length:" + mlist[cnt].time + " sec)");
conn.connect("rtmp://localhost/" + mlist[cnt].app);
}
}
function playVideo() {
trace("video Stared...");
var playStream = Stream.get("foo");
playStream.onStatus = function(infoObj) {
trace(infoObj.code);
switch (infoObj.code) {
case "NetStream.Play.Stop":
case "NetStream.Play.Failed":
case "NetStream.Play.StreamNotFound":
case "NetStream.Failed":
conn.close();
}
};
playStream.play(mlist[cnt].name, mlist[cnt].time - 10,-1,false,conn);
}
このサンプルでは、変数 mlist で定義された FLV ファイルを順次 最後から 10秒だけ再生するようにしています。
Flash Communication Server の application ディレクトリに一つアプリケーションディレクトリを作成し、ここに main.asc を保存。またこのアプリケーションが Flash Communication Server 起動時に自動的に開始されるように同じディレクトリに Application.xml ファイルを作成し、次のように記述します。
<Application>
<LoadOnStartup>true</LoadOnStartup>
</Application>
関連する追加の考慮点
追加情報
最終更新日: 2005年3月28日
作成日: 2005年3月28日
