FLVのCuepoint(キューポイント)は一番近いキーフレームを指す

CuepointとはFlashビデオ中に他のイベントと同期するために設定するマーカーの様なものです。

例えば、
・映像の場面が切り替わる時に、背景の色を変える
・映像とスライドショーを同期させる
・字幕や映像に連動したアニメーションをつける
・Cuepointを通過したよ〜 というイベントをもとに何かを動かす
・特定のCuepointへ再生位置を移動させる

といったことが可能です。
詳しくはアドビサイトにチュートリアルがあります

flv2.gif

Cuepointを設定するには、flvのエンコード時に埋め込んでしまうかActionScriptで後付けします。

エンコード時に埋め込むと 後で変更ができないので、ActionScriptで設定したいところですが、実は非常に大きな問題をかかえています。

ActionScriptで設定したCuepointはキーフレームと一致しないために、Cuepoint にseekできません。

しっかりマニュアルにも書いてありました
プログレッシブダウンロードの場合はキーフレームへのシークしか実行できないので、シークすると、指定した時間以降にある最初のキーフレームの時間に移動します

FMSを使えば可能らしいのですが、普通のWebサーバにflvを置いている場合やローカルで再生している場合などは最寄りのキーフレームにシークします。

なんとも不便な話です。
この問題への対処としては、

Flash CS3 Video Encoderをつかって事前にCuepointをいれておけばよいのです
この場合はCuepointが設定されたフレームをキーフレームにしてくれるので問題はおきません。

でもどのフレームにCuepointを設定したいかが事前に決められない場合はActionScriptで後付けしたいところです。

ActionScriptでの後付で正確にシークしたい場合は、こんな方法が可能です。

1, Cuepoint 定義のXMLを用意

例 1秒の精度で1000秒分〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<FLVCoreCuePoints Version="1">
<CuePoint><Time>0</Time><Type>navigation</Type><Name>0</Name></CuePoint>
<CuePoint><Time>1000</Time><Type>navigation</Type><Name>1000</Name></CuePoint>
<CuePoint><Time>2000</Time><Type>navigation</Type><Name>2000</Name></CuePoint>


<CuePoint><Time>1000000</Time><Type>navigation</Type><Name>1000000</Name></CuePoint>
</FLVCoreCuePoints>
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜

2, FLVのエンコード時に1のXMLを埋め込む
 1秒以上の精度が必要な場合はCuepointを間隔を増やす

3, 連番のCuepoint名にActionScriptでシーク処理をする

問題はこの手法で事前にcuepointを大量に入れてしまうと、キーフレームを大量にいれたことになり、flvなのにすごいファイルサイズになってしまう点です。

逆に再生、停止、任意の場所への移動(シーク)を頻繁に正確に行いたい場合には、有効な方法です。1/10秒単位程度のシークはちゃんと動作します。

.f4vでの実験はしていませんが、多分同じ現象が起きるのではないかと思われます。

(kani君ありがとう)