FLV: 2009年4月アーカイブ

今更な感がありますが、AS3.0から、簡単にフルスクリーン機能を実装できるようになりました。

その方法は

  1. FlvPlaybackコンポーネントから、フルスクリーンボタンが配置されたコンポーネントを選択する。
  2. FLV Playback カスタム UI コンポーネントのFullScreenButtonを配置する。
  3. enterFullScreenDisplayState () メソッドを実行する
  4. スクリプトで実装する。

の4パターンが考えられるでしょう。

しかし、この4パターンのうち、1~3は、Flvムービーにしか適用できず。
さらに、FlvPlaybackコンポーネントを利用し、かつ、ディスプレイカードによるハードウェアアクセラレーションを利用する場合、コンポーネントの矩形範囲で拡大されてしまい、ビデオソースの解像度は無視されます。

例えば

  1. 実際のビデオのソースは、1920×1080のフルHDサイズだが、初期起動時は480×270で表示する。
  2. 画面に配置されたひとつのFlvPlaybackコンポーネントで、480×270画面内表示と、1920×1080フルスクリーンを切り替える。

上記のケースだと、フルHDの映像を480×270に縮小表示している場合、フルスクリーンにした際に
480×270で表示している画面をスケーリングしてしまうため(小さい動画をハードウェア側でスムージングを掛けて表示される)ソースがフルHDの映像だとしても、表示上480×270などに縮小している場合は、縮小された画面を引き伸ばしてしまい、小さい動画をただ引き伸ばしただけになってしまいます。

どうやらコレは、上記1~3のフルスクリーン実装方法だと、FlvPlaybackコンポーネントのメソッドを呼び出すかたちになるみたいなのですが(FlvPlaybackのenterFullScreenDisplayState () メソッド)どうやらこのメソッドを実行すると、FlvPlaybackコンポーネントの矩形範囲をハードウェアアクセラレーションでスケーリング表示するようです。(予想ですが!!)

結果、小さいサイズの動画をただ引き伸ばしたような映像になってしまいます。

そこで、FlvPlaybackコンポーネントの機能を使わずに、4の「スクリプトで実装する」ことにしましょう。
スクリプトで実装すると、Flvコンテンツだけでなく、実際のFlashコンテンツもFullScreenで表示することが出来るので、こちらで実装するほうが汎用性がありそうですしね。

さて、その方法ですが

stage.displayState = StageDisplayState.FULL_SCREEN;

と、stageのdisplayStateプロパティを、フルスクリーンなパラメータに設定するだけで、とりあえずFullScreenに出来ます。簡単です。プロパティにパラメータが入ったと同時にフルスクリーンが実行されます。
しかし問題が、コレだけではハードウェアアクセラレーションがかかりません。

なので、上記のコードを実行する前に、

stage.fullScreenSourceRect = new Rectangle(0, 0, 1920, 1080);

上記のコードを実行し、フルスクリーンで拡大する矩形エリアを設定します。

fullScreenSourceRectプロパティを設定すると
可能な場合、拡大 / 縮小は、ユーザーのコンピュータ上でグラフィックカードやビデオカードを使用してハードウェアで行われます。

てことで、こういうコードになります。

stage.fullScreenSourceRect = new Rectangle(0, 0, 1920, 1080);
stage.displayState = StageDisplayState.FULL_SCREEN;

FlvPlaybackコンポーネントのfullScreenTakeOverプロパティがtrueの場合(通常デフォルトでture)フルスクリーンに移行すると、自動的にFlvPlaybackコンポーネントは前面に表示され、フルHDのビデオのエリア「Rectangle(0, 0, 1920, 1080);」に対して、フルスクリーンのディスプレイアクセラレーションが実行されます。

この方法を利用すれば、Flvではなく、通常のFlashコンテンツに対してフルスクリーン機能を実装できますし、fullScreenTakeOverプロパティにfalseを設定した場合は、FlvPlaybackを含んだFlashコンテンツのデザインを、そのままフルスクリーンに出来ます。
その際は、Rectangleに対してRectangle(0, 0, Flashコンテンツの横幅, Flashコンテンツの高さ)を渡してやればOK!

ただし、フルスクリーンを実装する再は、スクリプトで実装する再もFlvPlaybackのメソッドを利用する場合も
必ずマウスクリックまたはキー操作をトリガにする必要がありあますので、ご注意を。

そして、貼り付けるHTML側の、allowFullScreenをtrueに設定してあげるのを忘れないように。

前回の記事「FLVPlaybackコンポーネントで、closeVideoPlayer()メソッドを使う。」との2部構成みたいな感じです。

まずはコイツを見てくれ。
僕は、ココのアカウントを持っていないし、同様の問題に直面したときは、投稿日時からだいぶ日数が経ってたので、特にココにはコメントしなかったんだけれど、今後同様の問題に直面した人の救いになればと思ってエントリーを書いてみることにするよ。

前回、

movie.closeVideoPlayer(1);

にて、NetStreamを閉じましが、再度再生するために

movie.activeVideoPlayerIndex = 1;
movie.visibleVideoPlayerIndex = 1;
movie.source = "flvファイルへのパス";
movie.play();

このように記述すると、コンポーネントの表示上はミュートになっていないのに、音声が再生されません。
さらに、ボリュームのハンドルや、ミュートボタンを弄ると、音が流れ出します。

どうやら、ビデオとサウンドは、別々のプロセス(インスタンス)で管理されているみたいで、FLVPlaybackコンポーネントを生成したときは、ビデオとサウンドが両方生成され、closeVideoPlayer()メソッドを実行すると、ビデオとサウンドが両方削除されるが、その後に同じコンポーネントに対して
movie.source = "flvファイルへのパス";
movie.play();
上記を実行すると、ビデオ再生だけが生成され、サウンドは生成されず、音声ボタン等を操作したときに初めて生成されているようだ。(全部予想な!!)

この予想が正しければ、FlvPlaybackコンポーネントにサウンドを制御するプロパティがあって、それはきっとクラス型だ!
とあたりをつけて、ドキュメントを漁る。
ほどなくして、soundTransformというプロパティを発見。予想通りSoundTransformというクラスのインスタンスだ。
ということは、再度、FlvPlaybackで再生するときに、soundTransformプロパティを再設定してやればいけるはず!!ってことで

var sound:SoundTransform = new SoundTransform(1 , 0);
movie.soundTransform = sound;

コンストラクタに、SoundTransform(1 , 0);
で、第1引数にボリューム(1で最大音量)、第2引数にパン(0でパン無し)を与えて、生成したSoundTransformクラスのインスタンスを、FlvPlaybackコンポーネントのプロパティsoundTransformに渡します。

これで、晴れて音声が再生されるようになります。やったね♪

まず、ことの発端は

大きなFLVファイルをサーバに置いたら、ものすごい負荷で参ったwww
てな事があって、
ならば、FLVPlaybackコンポーネントが表示される画面を閉じても裏でプログレッシブダウンロードが走ってるから、画面を閉じるたびに、きちんとNetStreamを閉じて、なるべく負荷がかからないようにしよう。

と考えたからなわけです。
そこで利用するのが「closeVideoPlayer()」メソッドです。

closeVideoPlayer()メソッドは、引数として渡されたindexのNetStream を閉じ、ビデオプレーヤーを削除します。

ここでいうビデオプレーヤーとは、FLVPlaybackコンポーネント自身ではなく、なんというか、FLVPlaybackコンポーネントに指定されている、プロセスみたいなもの?
僕はなんとなくこんな感じで理解してます。

さて、
■閉じたビデオプレーヤーがアクティブまたは可視のビデオプレーヤーである場合は、アクティブまたは可視のビデオプレーヤーを FLVPlayback インスタンスでデフォルトプレーヤーに設定します (インデックス 0)。
■デフォルトプレーヤーを閉じることはできません。閉じようとすると、エラーがスローされます。

とあるので、簡単な話、indexの値が0だと、closeVideoPlayer()メソッドを使えません。
なので、activeVideoPlayerIndexパラメータとvisibleVideoPlayerIndexを適当な数値にします。

仮に、movieという名前のFLVPlaybackコンポーネントが配置されているとして
例えばビデオ再生用の小窓をFlashのStageに表示させる場合に

movie.activeVideoPlayerIndex = 1;
movie.visibleVideoPlayerIndex = 1;
movie.source = "flvファイルへのパス";
movie.play();

と、予め再生する処理で上記の様に記述することで、この小窓を閉じる(非表示にしたり、removeChild()する)再に

movie.closeVideoPlayer(1);

上記の様に記述して、ネットコネクションを切ることが出来ます。
例えば、こんなソフトでネットワークを監視してみると、明らかに負荷が軽減されているのが分かります。

まぁ結局あまりたいした効果が出ずに、rtmpが使えるストリーミングサーバを借りたんですがねww

プロフィール

HN.NoBody

NoBody

市ヶ谷のとあるオフィスでFlashクリエイターとして労役中。
なんとなくチーフ。

twitterでつぶやき中