FLVPlayerを自作してみる (2009.1.7)

2017.6.27追記
Flashは絶滅に向かっているので、当サイトでも使用を停止しています。videoタグを使いましょう。

このサイトの動画をFLV化するにあたり、Dreamweaver付属のプレイヤコンポーネントでは物足りなかったので自作してみた。
最初はここを参考にFlashで作ってみたもののFlashの操作性が自分に合わないので、結局Flexで作成。

コンセプト

基本的にはVideoDisplayコントロールをそのまま利用し、機能を追加していく。

開発の上でポイントとなった部分のみについてメモを残しておきます。
完成品はToolsに置いてあります。

1. とりあえず再生

FLVを再生するだけならば、VideoDisplayコントロールを置いてsourceプロパティでFLVの場所を指定すれば自動的に再生します。

    <?xml version="1.0" encoding="utf-8"?>
	<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
		<mx:VideoDisplay id="vdDisplay" source="http://www.example.com/path/to/file/test.flv" />
	</mx:Application>
    

2. シークバー

シークバーはここを参考にさせて頂きました。
水平スライダーの最小値を0,最大値をビデオファイルのトータル時間とし、現在位置をビデオの現在位置とすることで自動的にスライダーが更新される仕組みですね。
で、スライダーをドラッグした時の動作をchangeプロパティで実装しているところが良くできてます。

    <mx:HSlider id="hsSeekBar"
      width="100%"
      maximum="{vdDisplay.totalTime}"
      minimum="0"
      value="{vdDisplay.playheadTime}"
      change="{ if(vdDisplay.stateResponsive) vdDisplay.playheadTime = hsSeekBar.value }"
      liveDragging="true"
      showTrackHighlight="true"
    />
    

3. 現在時刻の表示(ビデオの情報取得)

プログレッシブダウンロード等では、ある程度ダウンロードが完了しないとビデオの情報はスクリプトから取得できないため、VideoDisplayの「metadataReceived」イベントにて取得できる状況を把握します。
現在位置の取得は「playheadUpdate」イベントを利用して「playheadTime」プロパティを参照すれば実現出来ます。

	<mx:Script>
		<![CDATA[
			/**
			 *  メタデータ受信完了イベント
			 */
			private function onMetadataReceived():void
			{
				var total_Min:String = "0" + Math.floor(vdDisplay.totalTime/60);
				var total_Sec:String = "0" + Math.floor(vdDisplay.totalTime%60);
				labelDuration.text = total_Min.substr(-2,2) + ":" + total_Sec.substr(-2,2);
			}

			/** 
			 *  現在時間更新用
			 */
			private function onUpdateVideoFrame():void
			{
				var cur_Min:String = "0" + Math.floor(vdDisplay.playheadTime/60);
				var cur_Sec:String = "0" + Math.floor(vdDisplay.playheadTime%60);
				labelCurrent.text = cur_Min.substr(-2,2) + ":" + cur_Sec.substr(-2,2);
			}
		]]>
	</mx:Script>

	<mx:VideoDisplay id="vdDisplay" autoPlay="false" autoRewind="false"
	  width="320" height="240"
	  metadataReceived = "onMetadataReceived();"
	  playheadUpdate = "onUpdateVideoFrame();"
	/>
	<mx:Label text="00:00" id="labelCurrent" color="#DCDCDC" width="40" height="18" fontSize="9" textAlign="center"/>
	<mx:Label text="/" width="8.333334" height="18" color="#DCDCDC" fontSize="9" textAlign="center"/>
	<mx:Label text="00:00" id="labelDuration" color="#DCDCDC" width="40" height="18" fontSize="9" textAlign="center"/>

	

4. ボタン画像の動的変更

再生ボタンは再生中は一時停止ボタンとして機能するので、画像の動的変更が必要です。
Button.setStyleでボタンの画像は変更することができます。
引数がクラスなので、ファイル名を渡すのではなく、スクリプト冒頭で埋め込みイメージをバインドしておく必要があります。

埋め込みイメージのバインド

<mx:Script>
    <![CDATA[
        //ボタンイメージ
        //一時停止ボタン画像
        [Embed(source="../assets/btn_pause.png")]
        [Bindable]
        public var imgPause:Class;

        //再生ボタン画像
        [Embed(source="../assets/btn_play.png")]
        [Bindable]
        public var imgPlay:Class;
    ]]>
</mx:Script>
	

ボタン画像の動的変更

    /**
     *  再生ボタンクリックイベント
     */
    private function onPlayButtonClick():void
    {
        if( isPlay == false ){
            vdDisplay.play();
            isPlay = true;
            btnPlay.setStyle("icon",    imgPause);
        }else{
            vdDisplay.pause();
            isPlay = false;
            btnPlay.setStyle("icon",    imgPlay);
        }
    }
    

5. flashvarsの参照

HTMLからActionScriptにパラメータを渡すときは、いにしえのルールで「flashvars」を使うことになっています。
これをFlexで実現するには、「Application.application.parameters」を参照することで実現します。

    //ビデオのソースをflashvarsから受け取る(src)
    srcVideoFile =Application.application.parameters.src;

    //再生前のプレビュー画像のソースをflashvarsから受け取る(preview)
    srcImageFile =Application.application.parameters.preview; 
	

参考にしたサイト