2011-02-10

Flex/ActionSctipt開発: flv player の seekbar 上に buffering 進捗状況を表示

Flex で作成した flvプレイヤーのシークバー上に、バッファリング進捗状況を表示する方法です。
Youtubeのシークバー
イメージとしては、Youtube のシークバー(右図)のようなものを作ります。(シークバー途中からのバッファリングは非対応)

右図ではそれぞれ、
(1) 濃い赤い領域:再生済み
(2) その右の薄い赤い領域:バッファリング済み
(3) その右の灰色領域:未バッファリング
を表しています。

「再生済み領域(1)」と「未再生領域(2)+(3)」の2つの領域だけを表現するシークバーの場合、例えば
[flex]Flex2でFLVプレイヤーのシークバーを作ってみる - func09
のように実装できます。

「再生済み領域(1)」と「バッファリング済み領域(2)」と「未バッファリング領域(3)」の3つの領域を表現するシークバーの場合、次のようにすると実現できます。

下記実装によるバッファリング領域付きシークバー
概要としては、上記の実装に加えて、シークバー(HSlider)の背後にバッファ表示用のProgressBarを置いています。そして、HSliderのトラック領域のスタイルに、白い半透明画像(slider_track.png)を適用しています。ProgressBar のbarColorを黒色に指定しているので、白い半透明画像と色が混ざって、「バッファリング済み領域(2)」が濃い灰色として表示されることになります。

実装例は次の通り。
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
   width="640" height="510" backgroundColor="#cccccc"
   creationComplete="initApp()">

    <mx:Script>
    <![CDATA[
   
    //10px x 10px の半透明の白い正方形画像
    [Embed(source="image/slider_track.png")]
    private var imgSliderTrack:Class;

    //10px x 10px の青い正方形画像
    [Embed(source="image/slider_track_highlight.png")]
    private var imgSliderTrackHighlight:Class;

    private function initApp():void
        {
            hsSeek.setStyle("trackSkin", imgSliderTrack);
            hsSeek.setStyle("trackHighlightSkin", imgSliderTrackHighlight);
            hsSeek.addEventListener(ProgressEvent.PROGRESS, onProgress);
        }

        private function onProgress(e:ProgressEvent):void
        {
            pbBuffer.setProgress(e.bytesLoaded, e.bytesTotal);
        }

    ]]>
    </mx:Script>

    <mx:VideoDisplay id="vd" 
        x="0" y="0" width="640" height="480" 
        source="sample.flv" autoPlay="true"/>
    <mx:ProgressBar id="pbBuffer" 
        y="490" x="85" height="20" width="350" 
        label="" mode="manual" trackHeight="11" barColor="#000000"/>
    <mx:HSlider id="hsSeek" styleName="hsSeek" 
        y="480" x="80" height="20" width="360"
        maximum="{vd.totalTime}"
        minimum="0"
        value="{vd.playheadTime}"
        change="{ if(vd.stateResponsive) vd.playheadTime = hsSeek.value }"
        liveDragging="true"
        showTrackHighlight="true"
        allowTrackClick="true"/>

    </mx:Application>

0 件のコメント: