大重美幸の「これ見落としてませんか? ActionScript 3.0」

第4回 FLV をウィンドウ/画面全体に表示する

今回のテーマはFLVです。最近、FLVをブラウザのウィンドウいっぱいに広げたり、フルスクリーンで再生しているサイトを見かけます。あれはどうやっているのでしょうか? さらに、そうしたFLV映像の前面にロゴやボタンなどのグラフィックを表示するにはどうすればいいのでしょうか? FLVの疑問を今日こそ解決しましょう!

なお、記事の最後には、前回出した配列の宿題の回答を発表していますので、ぜひチェックしてください。

サンプルファイル : edge_oshige_04_sample_fla.zip (1.09MB)

縦横比率を変えずに FLV を再生する

FLVを再生するには FLVPlayback コンポーネントか VideoPlayer クラスを使います。VideoPlayer クラスも難しくはありませんが、スキンつまりFLVのコントローラを使える FLVPlayback コンポーネントはやっぱり手軽。フルスクリーンを使うなら断然 FLVPlayback コンポーネントです。

FLVPlayback コンポーネントを使う場合には注意点が2つあります。1つ目は FLVPlayback コンポーネントをライブラリにコピーしておくこと。そして忘れてならない2つ目はスキンに使う swf ファイルです。スキン用の swf ファイルを用意するには、ステージに FLVPlayback インスタンスを作り、使用するスキンを選んでパブリッシュします。するとスキン用 swf ファイルが fla ファイルと同じフォルダに保存されるのでこれを利用します。スキン用 swf ファイルが用意できたならばステージに作った FLVPlayback インスタンスは不要なので削除してしまいます。

(補足:スキン用の swf ファイルは Flash アプリケーションフォルダ内の Common/Configuration/FLVPlayback Skins に入っているので、ここから直接コピーすることもできます。FLV フォルダにはスキンの fla ファイルが入っているので、これを元にカスタムスキンを作ることもできます。)

では、さっそく次のサンプルを実際に見てもらいましょう。サンプルを実行すると新しいウィンドウが開いてFLVが再生されます。ウィンドウをリサイズするとウィンドウサイズに合わせてFLVが拡大縮小します。このとき画像が歪まないようにFLVの縦横比率が保たれるようにリサイズしている点に注目してください。

FLVがウィンドウのリサイズに合わせて伸縮
fig1 FLVがウィンドウのリサイズに合わせて伸縮します。

[sample] flv_maintainAspectRatio.fla

FLVを縦横比率を変えずにウィンドウサイズに合わせて再生します。

import fl.video.FLVPlayback;
import flash.events.FullScreenEvent;
import fl.video.VideoScaleMode;
//パブリッシュ設定(htmlでは100%指定も必要)
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
//FLVPlaybackコンポーネントのインスタンスを作る
var flvPlayer:FLVPlayback = new FLVPlayback();
flvPlayer.source = "http://av.adobe.com/jp/events/max2009/adobemax2009day1.flv";
flvPlayer.autoPlay = true;
flvPlayer.skin = "SkinOverPlaySeekFullscreen.swf";
flvPlayer.skinBackgroundColor = 0x666666;
flvPlayer.skinBackgroundAlpha = 0.5;
flvPlayer.skinAutoHide = true;
//フルスクリーンの余白の色
flvPlayer.fullScreenBackgroundColor = 0x000000;
addChild(flvPlayer);
//ロゴを表示する
var logo:MovieClip = new Logo();
logo.x = stage.stageWidth - logo.width / 2 - 10;
logo.y = logo.height / 2 + 10;
addChild(logo);

//縦横の比率を変えない
flvPlayer.scaleMode = VideoScaleMode.MAINTAIN_ASPECT_RATIO;
//ステージイベントのリスナーを登録する
stage.addEventListener(Event.RESIZE, resizeHandler);
stage.addEventListener(FullScreenEvent.FULL_SCREEN, fullScreenHandler);
resizeHandler();

//Stageのリサイズに合わせる
function resizeHandler(event:Event=null):void {
	//ロゴをウィンドウ右上に表示する
	logo.x = stage.stageWidth - logo.width / 2 - 10;
	logo.y = logo.height / 2 + 10;
	//ビデオサイズをフィットさせる
	flvPlayer.width = stage.stageWidth;
	flvPlayer.height = stage.stageHeight;
}
//フルスクリーンが終了した際にビデオサイズを再設定する
function fullScreenHandler(event:FullScreenEvent):void {
	if (! event.fullScreen) {
		resizeHandler();
	}
}

ではスクリプトを見てみましょう。まず最初に FLVPlayback コンポーネントのインスタンスを作り、再生する FLV の URL をsourceプロパティで設定します。autoPlayプロパティをtrueにしておけば、読み込みが完了した時点で自動再生されます。自動再生しないのであればfalseに設定しておきplay()で再生できます。load()で FLV ファイルを先読みして準備しておくこともできます。playWhenEnoughDownloaded()というおしゃれなメソッドもあるので気になった人は調べておきましょう。

FLVPlaybackコンポーネントのインスタンスを作ります。

var flvPlayer:FLVPlayback = new FLVPlayback();
flvPlayer.source = "http://av.adobe.com/jp/events/max2009/adobemax2009day1.flv";
flvPlayer.autoPlay = true;

次に使用するスキンの URL を指定します。スキンの色や透明度もプロパティで設定できます。skinAutoHideプロパティはマウスカーソルがロールアウトしたならば自然に隠す設定です。

スキンの設定。

flvPlayer.skin = "SkinOverPlaySeekFullscreen.swf";
flvPlayer.skinBackgroundColor = 0x666666;
flvPlayer.skinBackgroundAlpha = 0.5;
flvPlayer.skinAutoHide = true;

ところで、サンプルファイルをダウンロードしてパブリッシュして試すと次のような警告ダイアログが表示されたはずです。これはローカルディスクに保存してある swf ファイルからインターネット上にあるファイル(この場合は flv)にアクセスしようとしているけども、この swf を信頼してもだいじょうぶか?という警告です。

警告ダイアログ
fig2 ローカルのswfからサーバーにあるflvにアクセスしようとしたときに表示される警告ダイアログ。

swf を信頼して flv を再生するには、ダイアログの[設定...]ボタンをクリックします。すると「Adobe - Flash Player:設定マネージャ」のページが開きます。このページに表示されているのは単なる図ではなく、実際の設定プログラムです。次のように[追加...]を選び、利用したい swf ファイルまたは swf が入っているフォルダを選択してフィールドに追加します。これで次からは警告なしで swf を利用できるようになります。

設定マネージャ
設定マネージャ 追加後
fig3 テストしたい swf が入っているフォルダを追加すれば、次回からは警告されなくなります。

FLV をウィンドウにフィットさせる

FLV をブラウザのウィンドウサイズに合わせるためには、2つのことを行う必要があります。1つは FLV の縦横サイズをステージサイズに合わせることです。ステージサイズはstage.stageWidthstage.stageHeightなので、これと FLVPlayback インスタンスのwidthheightの値を合わせます。そしてステージサイズが変化したならば、それに合わせてwidthheightも設定し直す必要があります。そのためにstageEvent.RESIZEイベントのリスナーに resizeHandler を登録して縦横サイズを再設定します。resizeHandler では、ロゴの表示位置も再設定しています。

Stage のリサイズに合わせます。

function resizeHandler(event:Event=null):void {
	//ロゴをウィンドウ右上に表示する
	logo.x = stage.stageWidth - logo.width / 2 - 10;
	logo.y = logo.height / 2 + 10;
	//ビデオサイズをフィットさせる
	flvPlayer.width = stage.stageWidth;
	flvPlayer.height = stage.stageHeight;
}

しかし、ウィンドウのリサイズに合わせてステージサイズが変化しなければFLVもウィンドウには合いません。この設定はパブリッシュ設定の HTML パネルで「サイズ:パーセント 100×100」、「伸縮:拡大・縮小なし」、「Flash の位置:左上」に設定します。伸縮と Flash の位置はスクリプトのstage.scaleModestage.alignでも設定できますが、100% サイズの設定はスクリプトではできません。この設定は swf を表示する HTML に必要なコードなのでパブリッシュによって作られる HTML コードをよく調べてください。

パブリッシュ設定
fig4 ウィンドウサイズにステージサイズが合うようにパブリッシュ設定をします。

これでウィンドウのリサイズに合わせて FLV がフィットするようになりますが、さきほどのサンプルをよく見ると FLV の縦横の比率が変化しないように変形しています。これは縦横サイズの計算の必要はなく、FLVPlayback インスタンスのscaleModeプロパティの値をVideoScaleMode.MAINTAIN_ASPECT_RATIOに設定するだけです。

FLV の縦横の比率を変えない

flvPlayer.scaleMode = VideoScaleMode.MAINTAIN_ASPECT_RATIO;

フルスクリーンを利用する

さて、このサンプルにはもう1つ大事な機能があります。それはフルスクリーンへの対応です。フルスクリーンで表示するかどうかはstagedisplayStateプロパティの設定で切り替えることができます。この機能は FLV をフルスクリーン表示するかどうかというものではなく、ステージの任意の領域をフルスクリーンで表示する機能です。FLVPlayback の場合はフルスクリーン切り替えボタンが付いているスキンを使えば、FLV の領域をフルスクリーンで表示できます。ただし、フルスクリーンを利用するには swf を表示する HTML でallowFullScreenパラメータを"true"に設定しなければなりません。この設定はパブリッシュ設定の HTML パネルの「テンプレート:Flash のみ-フルスクリーンサポート」を選んでおくことで書き出されます。先の fig4 を確認してください。フルスクリーンにした際の余白の色はfullScreenBackgroundColorプロパティで設定します。

フルスクリーンにした際の余白の色を黒にします。

flvPlayer.fullScreenBackgroundColor = 0x000000;

ところで、フルスクリーンを利用する場合にハマってしまう罠があります。それはこのサンプルのように FLVPlayback インスタンスの縦横サイズを元のビデオサイズと変えている場合に、フルスクリーンから戻ったときに改めて縦横サイズを再設定する必要があるという点です。そのためには、stageFullScreenEvent.FULL_SCREENイベントが発生したならばイベントオブジェクトのfullScreenプロパティを調べます。この値がfalseならばフルスクリーンの終了なので、flvPlayer の縦横サイズを再設定します。スクリプトの最後の fullScreenHandler() はこのための関数です。

フルスクリーンの切り替えイベントにリスナーを登録します。

stage.addEventListener(FullScreenEvent.FULL_SCREEN, fullScreenHandler);

フルスクリーンが終了した際にビデオサイズを再設定します。

function fullScreenHandler(event:FullScreenEvent):void {
	if (! event.fullScreen) {
		resizeHandler();
	}
}

FLV をウィンドウサイズにフィットさせる

それでは今日の2番目のサンプルを見てもらいましょう。見てすぐにわかるように FLV がブラウザウィンドウにぴったりフィットしています。

 

FLVがウィンドウサイズにフィット
fig5 FLVがウィンドウサイズにフィットしています。

[sample] flv_exactFit.fla

このサンプルと先のサンプルとの違いはたった1つ、FLVPlayback のscaleModeの設定です。scaleModeVideoScaleMode.MAINTAIN_ASPECT_RATIOからVideoScaleMode.EXACT_FITにするだけでこのような結果になります。

ウィンドウサイズにフィットさせます。

flvPlayer.scaleMode = VideoScaleMode.EXACT_FIT;

しかし、これだと FLV 画像の縦横比が変わってしまい、場合によっては映像として好ましくありません。そこで、画像の横幅はウィンドウの幅に合わせ、画像の縦の長さは画像の縦横比が変わらない値に設定するようにしたのが次のサンプルです。この場合はウィンドウ幅に対して高さが十分でない場合は画像の下が見切れてしまいますが、画像が歪むことが無く、ウィンドウ幅をせばめれば画像全体が見えるようになります。 FLV 画像の縦横比を一定にするには元のFLVの縦横サイズが必要になりますが、この値はビデオ準備完了のVideoEvent.READYイベント後にpreferredWidthpreferredHeightのプロパティで調べることができます。

ウィンドウ幅に合わせてFLV画像の縦を決める
fig6 画像の縦横比率が変わらないようにウィンドウ幅に合わせてFLV画像の縦を決めます。

[sample] flv_exactFit2.fla

さらにこのサンプルではこれまでと大きく違っているところが2つあります。1つはスキンを利用していないところです。スキンを使わずに自分で作ったフルスクリーンボタンを画像右下に表示しています。もう1つの違いはフルスクリーンの状態のFLV画像の重なりです。フルスクリーンの状態でも、右上のロゴマークとフルスクリーンボタンが画像の上に表示されます。この2点に注意して次のスクリプトを読み取ってください。

スキンを使わずにフルスクリーン状態でもボタンやロゴを表示します。

import fl.video.FLVPlayback;
import flash.events.FullScreenEvent;
import fl.video.VideoScaleMode;
import fl.video.VideoEvent;
//パブリッシュ設定(htmlでは100%指定も必要)
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
//FLVPlaybackコンポーネントのインスタンスを作る
var flvPlayer:FLVPlayback = new FLVPlayback();
flvPlayer.source = "http://av.adobe.com/jp/events/max2009/adobemax2009day1.flv";
flvPlayer.autoPlay = true;
//フルスクリーンの余白の色
flvPlayer.fullScreenBackgroundColor = 0x000000;
//skinを使わない
flvPlayer.skin = null;
//フルスクリーンの際にFLVを最前面にしない
flvPlayer.fullScreenTakeOver = false;
addChild(flvPlayer);
//ロゴを表示する
var logo:MovieClip = new Logo();
logo.visible=false;
addChild(logo);
//FullScreenボタンを作り設定する
var fullscreenBtn:FullScreenButton = new FullScreenButton();
flvPlayer.fullScreenButton = fullscreenBtn;
fullscreenBtn.visible=false;
addChild(fullscreenBtn);

//FLVソースの縦横サイズ
var videoWidth:Number;
var videoHeight:Number;
//ビデオの準備完了イベント
flvPlayer.addEventListener(VideoEvent.READY, readyHandler);
function readyHandler(event:VideoEvent):void{
	videoWidth=flvPlayer.preferredWidth;
	videoHeight=flvPlayer.preferredHeight;
	resizeHandler();
}

//ウィンドウサイズにフィットさせる
flvPlayer.scaleMode = VideoScaleMode.EXACT_FIT;
stage.addEventListener(Event.RESIZE, resizeHandler);
stage.addEventListener(FullScreenEvent.FULL_SCREEN, fullScreenHandler);

//Stageのリサイズに合わせる
function resizeHandler(event:Event=null):void {
	//ロゴをウィンドウ右上に表示する
	logo.x = stage.stageWidth - logo.width / 2 - 10;
	logo.y = logo.height / 2 + 10;
	//ビデオサイズをフィットさせる
	flvPlayer.width = stage.stageWidth;
	flvPlayer.height = stage.stageWidth * videoHeight/videoWidth - 10;
	//フルスクリーンボタンを右下に表示する
	fullscreenBtn.x = Math.min(flvPlayer.width, stage.stageWidth) - fullscreenBtn.width - 10;
	fullscreenBtn.y = Math.min(flvPlayer.height, stage.stageHeight) - fullscreenBtn.height - 10;
	//ロゴとボタンを表示する
	logo.visible=true;
	fullscreenBtn.visible=true;
}
//フルスクリーンが終了した際にビデオサイズを再設定する
function fullScreenHandler(event:FullScreenEvent):void {
	if (! event.fullScreen) {
		resizeHandler();
	}
}

フルスクリーン画像より上の重なりで表示する

先にも書いたように、このサンプルではフルスクリーン表示の際にも右上にロゴマーク、右下にはフルスクリーンボタンが表示されます。このように通常モードと同じ重なりでフルスクリーンを表示したい場合には、FLVPlayback のfullScreenTakeOverプロパティの値をfalseに設定します。

フルスクリーンの際にFLVを最前面にしない設定。

flvPlayer.fullScreenTakeOver = false;

スキンのフルスクリーンボタンを使わずにフルスクリーンを切り替えるには Stage クラスのdisplayStateプロパティ、fullScreenSourceRectプロパティなどを使いますが、FLVPlayback コンポーネントを利用して FLV を再生している場合には、 FLVPlayback のfullScreenButtonプロパティに FullScreenButton コンポーネントのインスタンスを設定することで、手軽にボタンを作ることができます。

FullScreen ボタンを作りフルスクリーン切り替えボタンに設定します。

var fullscreenBtn:FullScreenButton = new FullScreenButton();
flvPlayer.fullScreenButton = fullscreenBtn;

さて、今回もだいぶ長くなってきたので続きは次回までの宿題にしましょう。次のサンプルでは FLV 画像全体に模様が入っています。最近、このような画像処理が施されている FLV を見ることがあると思いますが、いったいどのように行っているのでしょうか?それが今回の宿題です。これは CS4、Flash Player 10 から利用できる機能ですよ。

画像処理が施されているFLV
fig7 画像処理が施されているFLV。これはどうやってる?

[sample] flv_Quiz.html

前回の宿題の答:値をシャッフルする

最後に前回の宿題の解答です。「席替えをしたとき、元と同じ席には続けて当たらないようにするにはどうすればよいでしょうか?」という配列をシャッフルする問題でした。席替え後に同じ席にならないようにするには、自分が今座っている席のクジ引きに参加しなければよいわけです。そこで配列の後ろから値を決めようとしたとき、決める位置よりも手前に並んでいる値の中からランダムに値を選び、その値と入れ替えていけば同じ位置に元の値が納まることがありません。これをスクリプトで書くと次のようになります。

[sample] shuffle_fisher-2.fla

値が必ず別の位置に移動するように配列をシャッフルします。

var colors:Array = ["green","red","white","blue"];
//100回テスト
for (var i:uint=0; i<100; i++) {
	var newlist:Array = shuffle(colors.slice());
	trace(newlist);//出力結果の例:red,blue,green,white
}

//Fisher-Yates
function shuffle(list:Array):Array {
	var i:uint = list.length;
	while (i>0) {
		var j = Math.floor(Math.random()*(i-1));
		var tmp:* = list[--i];
		list[i] = list[j];
		list[j] = tmp;
	}
	return list;
}

 

関連情報


大重美幸氏写真大重美幸
(おおしげよしゆき)

日立情報システムズ、コミュニケーションシステム研究所を経て独立。株式会社ロクナナ顧問。執筆、講師、ソフトウェア開発を行う。趣味はサーフィンとジョギング。茅ヶ崎在住。著著は約50冊。twitter @oshige、@as3note

近著:Adobe Flash CS4 詳細!ActionScript 3.0入門ノート[完全改訂版]ActionScript3.0辞典[FlashPlayer10/9対応]