Exempel på video: videojukebox

Flash Player 9 och senare, Adobe AIR 1.0 och senare

I följande exempel skapas en enkel videojukebox som dynamiskt läser in en lista med videofilerna som spelas upp i ordningsföljd. Så här kan du skapa ett program som du kan använda för att bläddra igenom en serie videolektioner eller kanske specificera vilka annonser som ska spelas upp före leveransen av den begärda videon. Med detta exempel visas hur du använder ActionScript 3.0 för att göra följande:

  • Uppdatera ett spelhuvud baserat på videofilens uppspelningsförlopp

  • Avlyssna och tolka videofilens metadata

  • Hantera specifika koder i en nätdirektuppspelning

  • Läsa in, spela upp, pausa och stoppa en dynamiskt inläst FLV

  • Ändra storlek på ett videoobjekt i visningslistan baserat på nätdirektuppspelningens metadata

Programfilerna för det här exemplet finns på www.adobe.com/go/learn_programmingAS3samples_flash_se. Video Jukebox-programfilerna finns i mappen Samples/CapabilitiesExplorer. Programmet består av följande filer:

Fil

Beskrivning

VideoJukebox.fla

eller

VideoJukebox.mxml

Huvudprogramfilen för Flex (MXML) eller Flash (FLA).

VideoJukebox.as

Klassen som innehåller de flesta funktioner för programmet.

playlist.xml

En fil som visar vilka videofiler som läses in till videojukeboxen.

Läsa in en extern videouppspelningslistfil

Den externa playlist.xml-filen specificerar vilka videofiler som ska läsas in och i vilken ordning de ska spelas upp. För att läsa in XML-filen behöver du använda ett URLLoader-objekt och ett URLRequest-objekt enligt följande kod:

uldr = new URLLoader(); 
uldr.addEventListener(Event.COMPLETE, xmlCompleteHandler); 
uldr.load(new URLRequest(PLAYLIST_XML_URL));

Den här koden placeras i klassen VideoJukebox' konstruktor, så filen läses in innan övrig kod körs. Så fort som XML-filen har lästs in, anropas xmlCompleteHandler()-metoden som överför den externa filen till ett XML-objekt enligt följande kod:

private function xmlCompleteHandler(event:Event):void 
{ 
    playlist = XML(event.target.data); 
    videosXML = playlist.video; 
    main(); 
}

XML-objektet playlist innehåller rå XML-kod från den externa filen, medan XML-videokoden är ett XMLList-objekt som endast innehåller videonoderna. Ett exempel på playlist.xml-filen visas i följande kodutdrag:

<videos> 
    <video url="video/caption_video.flv" /> 
    <video url="video/cuepoints.flv" /> 
    <video url="video/water.flv" /> 
</videos>

Slutligen anropar xmlCompleteHandler()-metoden main()-metoden vilken anger de olika komponentinstanserna i visningslistan såväl som NetConnection- och NetStream-objekten som används för inläsning av de externa FLV-filerna.

Skapa ett användargränssnitt

Du måste dra fem Button-instanser till visningslistan och ge dem följande instansnamn för att skapa användargränssnittet: playButton, pauseButton, stopButton, backButton och forwardButton.

För var och en av de här knappinstanserna måste du tilldela click-händelsen en hanterare enligt följande kodutdrag:

playButton.addEventListener(MouseEvent.CLICK, buttonClickHandler); 
pauseButton.addEventListener(MouseEvent.CLICK, buttonClickHandler); 
stopButton.addEventListener(MouseEvent.CLICK, buttonClickHandler); 
backButton.addEventListener(MouseEvent.CLICK, buttonClickHandler); 
forwardButton.addEventListener(MouseEvent.CLICK, buttonClickHandler);

I buttonClickHandler()-metoden används en switch-programsats för att fastställa vilka knappinstanser som någon klickar på enligt följande kod:

private function buttonClickHandler(event:MouseEvent):void 
{ 
    switch (event.currentTarget) 
    { 
        case playButton: 
            ns.resume(); 
            break; 
        case pauseButton: 
            ns.togglePause(); 
            break; 
        case stopButton: 
            ns.pause(); 
            ns.seek(0); 
            break; 
        case backButton: 
            playPreviousVideo(); 
            break; 
        case forwardButton: 
            playNextVideo(); 
            break; 
    } 
}

Sedan lägger du till en Slider-instans i visningslistan och ger den instansnamnet volumeSlider. I följande kod sätts skjutreglageinstansens liveDragging-egenskap till true och en händelseavlyssnare definieras för skjutreglageinstansens change-händelse:

volumeSlider.value = volumeTransform.volume; 
volumeSlider.minimum = 0; 
volumeSlider.maximum = 1; 
volumeSlider.snapInterval = 0.1; 
volumeSlider.tickInterval = volumeSlider.snapInterval; 
volumeSlider.liveDragging = true; 
volumeSlider.addEventListener(SliderEvent.CHANGE, volumeChangeHandler);

Lägg till en ProgressBar-instans i visningslistan och ge den instansnamnet positionBar. Ställ in mode-egenskapen på manuell enligt följande kodutdrag:

positionBar.mode = ProgressBarMode.MANUAL;

Till sist lägger du till en Label-instans i visningslistan och ger den instansnamnet positionLabel. Det här Label-instansvärdet anges av timer-instansen.

Avlyssna videoobjektets metadata

När Flash Player påträffar metadata för var och en av de inlästa videofilerna, anropas callback-hanteraren för onMetaData() i NetStream-objektets client-egenskap. I följande kod initieras ett objekt och den specificerade callback-hanteraren anges:

client = new Object(); 
client.onMetaData = metadataHandler;

Med metadataHandler()-metoden kopieras dess data till metaegenskapen som definierades tidigare i koden. Det innebär att du har åtkomst till metadata för den aktuella videon när som helst igenom hela programmet. Sedan ändras storleken på videoobjektet på scenen så att den överensstämmer med dimensionerna som returneras från metadatan. Slutligen flyttas förloppsindikatorn för positionBar och storleken ändras baserat på storleken för den video som spelas upp för tillfället. Följande kod innehåller hela metadataHandler()-metoden:

private function metadataHandler(metadataObj:Object):void 
{ 
    meta = metadataObj; 
    vid.width = meta.width; 
    vid.height = meta.height; 
    positionBar.move(vid.x, vid.y + vid.height); 
    positionBar.width = vid.width; 
}

Dynamisk inläsning av en video

För att läsa in varje video använder programmet ett NetConnection- och NetStream-objekt. I följande kod skapas ett NetConnection-objekt och null överförs till connect()-metoden. Genom att ange null, ansluter Flash Player till en video på den lokala servern i stället för att ansluta till en server som Flash Media Server.

I följande kod skapas både NetConnection- och NetStream-instanserna, en händelseavlyssnare definieras för netStatus-händelsen och client-egenskapen tilldelas client-objektet:

nc = new NetConnection(); 
nc.connect(null); 
 
ns = new NetStream(nc); 
ns.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler); 
ns.client = client;

Metoden netStatusHandler() anropas när status för videon ändras. Det inkluderar start eller stopp av en videouppspelning, buffring eller om en videodirektuppspelning inte hittas. I följande kod visas netStatusHandler()-händelsen:

private function netStatusHandler(event:NetStatusEvent):void 
{ 
    try 
    { 
        switch (event.info.code) 
        { 
            case "NetStream.Play.Start": 
                t.start(); 
                break; 
            case "NetStream.Play.StreamNotFound": 
            case "NetStream.Play.Stop": 
                t.stop(); 
                playNextVideo(); 
                break; 
        } 
    }  
    catch (error:TypeError)  
    { 
        // Ignore any errors. 
    } 
}

Föregående kod utvärderar kodegenskapen för info-objektet och filtrerar fram om koden är ”NetStream.Play.Start”, ”NetStream.Play.StreamNotFound” eller ”NetStream.Play.Stop”. Alla andra koder ignoreras. Om nätdirektuppspelningen startar, startar koden Timer-instansen vilken uppdaterar spelhuvudet. Om nätdirektuppspelningen inte hittas eller stoppas, stoppas Timer-instansen och programmet försöker spela upp nästa video i spelningslistan.

Varje gång Timer körs, uppdaterar positionBar-förloppsinsdikatorinstansen sin aktuella position genom att anropa setProgress()-metoden för klassen ProgressBar och Label-instansen positionLabel uppdateras med den förflutna tiden och total tid för den aktuella videon.

private function timerHandler(event:TimerEvent):void 
{ 
    try 
    { 
        positionBar.setProgress(ns.time, meta.duration); 
        positionLabel.text = ns.time.toFixed(1) + " of " meta.duration.toFixed(1) + " seconds"; 
    }  
    catch (error:Error) 
    { 
        // Ignore this error. 
    } 
}

Styra volymen för videon

Du kan styra volymen för den dynamiskt inlästa videon genom att ange soundTransform-egenskapen i NetStream-objektet. I videojukeboxprogrammet kan du ändra volymnivån genom att ändra värdet för skjutreglageinstansen volumeSlider. I följande kod visas hur du kan ändra volymnivån genom att tilldela SoundTransform-objektet värdet från Slider-komponenten vilket anges i soundTransform-egenskapen i NetStream-objektet:

private function volumeChangeHandler(event:SliderEvent):void 
{ 
    volumeTransform.volume = event.value; 
    ns.soundTransform = volumeTransform; 
}

Styra videouppspelning

Resten av programmet styr videouppspelningen när videon kommer till slutet av videoflödet eller användaren hoppar till föregående eller nästa video.

Med följande metod hämtas video-URL:en från XMLList för den valda positionen:

private function getVideo():String 
{ 
    return videosXML[idx].@url; 
}

Metoden playVideo() anropar play()-metoden i NetStream-objektet för att läsa in vald video:

private function playVideo():void 
{ 
    var url:String = getVideo(); 
    ns.play(url); 
}

Metoden playPreviousVideo() minskar aktuell videoindexposition, anropar playVideo()-metoden för att läsa in den nya videofilen och anger att förloppsindikatorn ska visas:

private function playPreviousVideo():void 
{ 
    if (idx > 0) 
    { 
        idx--; 
        playVideo(); 
        positionBar.visible = true; 
    } 
}

Den sista metoden playNextVideo() ökar videoindexpositionen och anropar playVideo()-metoden. Om den aktuella videon är den sista videon i spelningslistan, anropas clear()-metoden för Video-objektet och förloppsindikatorinstansens visible-egenskap sätts till false:

private function playNextVideo():void 
{ 
    if (idx < (videosXML.length() - 1)) 
    { 
        idx++; 
        playVideo(); 
        positionBar.visible = true; 
    } 
    else 
    { 
        idx++; 
        vid.clear(); 
        positionBar.visible = false; 
    } 
}