謎解きウェブ

なぜなにどうして。

ストリーミングサウンド付きのSWFでFlashのフレームレートを変えてみる

text:

メインのSWF(main.swf)と外部読み込み用のSWF(load.swf)のフレームレートが異なっている場合、load.swfが正しいフレームレートで再生されなくなります。じゃあmain.swfのフレームレートかload.swfのフレームレートをお互い同じにしてパブリッシュすればいいじゃん、というのがごもっともな意見。しかし例えばload.swfのフレームレートが10fpsかつ元のFLAファイルは無いとかいう状況だと、main.swfのフレームレートを10fpsに下げなくちゃいけない。すると全体的にアニメーションがカクカクしちゃってトゥイーンとかぎこちない感じになっちゃう。

ではせめてload.swfを再生している間だけmain.swfのフレームレートを上げたり下げたりできないか、という発想になるのですが、load.swfにストリーミングサウンドを埋め込むか、ストリーミングサウンドを埋め込んだ別のSWFを読み込むことでそれが可能です。けっこう昔からあるやり方のようですが、実際やったことなかったので実験。

1. main.swf(30fps, ストリームサウンド無し, ダイナミックサウンド有り)

まず、メインのSWF(main.swf)として30fpsで歩く赤いねずみのアニメーションを用意してみました。タイムライン・アニメーションです。左下の再生ボタン(▲)を押して再生・停止を行えます。

タイムラインに埋め込んだサウンドは無いのですが、ねずみをクリックすることでライブラリ内にリンケージ指定したサウンドがスクリプトで動的に再生される仕様になっています(ダイナミックサウンド)。ねずみがジャンプするとともに「ピョーン」と音が鳴るはずです。

2. load.swf(10fps, ストリームサウンド無し, ダイナミックサウンド有り)

つづいてmain.swfに外部読み込みするload.swfを単体で再生するサンプルが以下。こちらは緑のねずみで、main.swfと同様にタイムラインアニメーションですが、フレームレートは10fpsです。10fpsなので動きはぎこちない。

こちらもmain.swfと同様にタイムラインへのサウンド埋め込みは無く、一方クリック時に「ピョーン」と動的にサウンドが再生される仕様です。

3. main.swf + load.swf

ではmain.swf上にload.swfを外部読み込みするとどうなるかというのが以下のサンプルです。再生ボタンを押すと同時にmain.swf上にload.swfを読み込んでいます。厳密にはこのサンプルで読み込んでいるload.swfと上のload.swfは異なりますが(再生ボタンのインターフェースの有無など)、緑のねずみのタイムラインアニメーション自体は同じです。

これを再生してみると分かるとおり、load.swfはmain.swfのフレームレートに合わせて再生されるため、意図した速度で再生されなくなってしまいます。理論上は3倍速。ただし、緑のねずみをクリックした時に鳴る「ピョーン」というダイナミックサウンドは3倍速になるわけではなく等倍速のままです。

4. ストリーミングサウンド付きのSWFでフレームレートを制御

ではここでmain.swfのフレームレートの設定は30fpsのままで変更せずに、load.swfを等倍速で再生させる方法の1つについて。冒頭で述べたとおり「ストリーミングサウンド付きのSWF」を使います。

実際にそのサンプルを見る前に、まずはそのストリーミングサウンド付きのSWFの構造を解説。今回は10fps(10fps.swf)と20fps(20fps.swf)と60fps(60fps.swf)の3つを用意してみたのですが、それぞれの内部構造は次のようになっています。

見たままですが、タイムライン上に適当なMP3サウンドを埋め込んでいます(今回は無音のsilence.mp3というファイルを用意しました)。ポイントは「ストリーミング」であること、「ループ」であること、「MP3」であることの3点です。

実はWAVサウンドだと今回の方法はうまく行きませんでした。なのでMP3に変換しておくか、以下のようにパブリッシュ設定で [オーディオストリーム] 部分にMP3圧縮の設定をしておく必要があるようです。

それでは本題に戻って。以下は3.のサンプルと同様に、main.swfにload.swfを読み込んだものです。さらに [Load 10fps] [Load 20fps] [Load 60fps] の各ボタンを押すことで、上記で述べたストリーミングサウンド付きのSWFをmain.swf上にロードしたりアンロードできるようになっています。

まず再生ボタンを押すと、3.のサンプル同様緑のねずみが3倍速で再生されますが、この状態で [Load 10fps] ボタンをクリックしてみてください。すると、main.swfのフレームレートが10fpsに落ちるはずです。

これは読み込んだムービーにストリーミングサウンドがあると、その再生を優先させようとする特性がFlash Playerにあるためです。main.swfに10fpsのストリーミング付きサウンド(10fps.swf)を読み込むと、本来10fps.swfもload.swf同様にmain.swfに合わせて30fpsで再生されるはずなのですが、サウンドの再生を優先させるためにmain.swf側が強制的に10fpsになる。

すると本来10fpsであるload.swfの再生速度が正常に見えるようになるというわけ。で、10fps.swfをアンロードするとmain.swfのフレームレートは30fpsに戻り、load.swfの再生速度は再び速くなる。

では10fps, 20fps, 60fpsのストリーミングサウンド付きのSWFを全てあるいは複数個同時にmain.swfへ読み込んだ場合はどうなるか?実はこれが分からなくて今回実験をしてみるに至ったわけですが...実際に試してみてください。

結論としては、最後に読み込んだものが有効になる模様。main.swf + load.swf + 10fps.swfの状態だとmain.swfのフレームレートは10fpsになりますが、これにさらに20fps.swfを読み込むと、main.swfのフレームレートは20fpsになります。

さて。見て分かったと思いますが、この方法を使えばload.swfの再生を本来のフレームレートで行うことは出来ますが、全体のフレームレートが変わってしまうので、今回のサンプルのようにmain.swfにタイムライン・アニメーションが含まれている場合には今度はmain.swfの再生がおかしくなってしまいますね。もしこの方法を使う場合には、load.swfの再生中はmain.swfの動きを止めておくとか、動作全てをスクリプトベースで行う必要がありそう。

また、main.swfのフレームレートを30fpsに維持したままload.swfを正常な速度で再生させる方法もあるようです。load.swfは基本止めておき、main.swf内からsetInterval()を使ってload.swfのフレームを定期的に進めるという方法なのですが、これは後日やってみたりやらなかったり。なんかマシンへの負荷が高そう。