Poniższy przykład tworzy prosty odtwarzacz wideo, który dynamicznie ładuje listę plików wideo do odtworzenia i umożliwia odtworzenie ich po kolei. W ten sposób możemy zbudować aplikację, która pozwoli użytkownikowi na przeglądanie serii samouczków wideo lub określi, na przykład, która reklama powinna być odtworzona przed właściwym materiałem wideo wybranym przez użytkownika. Przykład ilustruje następujące techniki w języku ActionScript 3.0:
-
Aktualizacja położenia głowicy odtwarzania na podstawie postępu odtwarzania pliku wideo.
-
Wykrywanie i analizowanie metadanych pliku wideo.
-
Obsługa konkretnych kodów w strumieniu NetStream.
-
Ładowanie, odtwarzanie, wstrzymywanie i zatrzymywania odtwarzania dynamicznie załadowanego pliku FLV.
-
Zmiana rozmiaru obiektu wideo na liście wyświetlania na podstawie metadanych strumienia NetStream.
Aby pobrać pliki tej przykładowej aplikacji, należy przejść na stronę
www.adobe.com/go/learn_programmingAS3samples_flash_pl
. Pliki aplikacji Video Jukebox znajdują się w folderze Samples/VideoJukebox. Aplikacja składa się z następujących plików:
File
|
Opis
|
VideoJukebox.fla
lub
VideoJukebox.mxml
|
Główny plik aplikacji dla środowiska Flex (MXML) lub programu Flash (FLA).
|
VideoJukebox.as
|
Klasa realizująca podstawowe funkcje aplikacji.
|
playlist.xml
|
Plik z listą plików wideo, które zostaną załadowane do odtwarzacza.
|
Ładowanie zewnętrznego pliku z listą odtwarzania plików wideo
Zewnętrzny plik playlist.xml file określa, które pliki wideo mają zostać załadowane, oraz w jakiej kolejności powinny być odtwarzane. Aby załadować plik XML, musimy użyć obiektu URLLoader oraz obiektu URLRequest, co ilustruje poniższy kod:
uldr = new URLLoader();
uldr.addEventListener(Event.COMPLETE, xmlCompleteHandler);
uldr.load(new URLRequest(PLAYLIST_XML_URL));
Ten kod znajduje się w konstruktorze klasy VideoJukebox, a zatem plik jest ładowany przed wykonaniem innych części kodu. Po zakończeniu ładowania pliku XML wywoływana jest metoda
xmlCompleteHandler()
, która analizuje plik zewnętrzny i przekształca go w obiekt XML, co zilustrowano poniżej:
private function xmlCompleteHandler(event:Event):void
{
playlist = XML(event.target.data);
videosXML = playlist.video;
main();
}
Obiekt XML
playlist
zawiera nieprzetworzony kod XML z pliku zewnętrznego, natomiast obiekt XML videos to obiekt XMLList zawierający tylko węzły video. Poniższy urywek kodu przedstawia przykładowy plik playlist.xml:
<videos>
<video url="video/caption_video.flv" />
<video url="video/cuepoints.flv" />
<video url="video/water.flv" />
</videos>
Na koniec metoda
xmlCompleteHandler()
wywołuje metodę
main()
, która konfiguruje różne instancje składników na liście wyświetlania, a także obiekty NetConnection i NetStream służące do ładowania zewnętrznych plików FLV.
Tworzenie interfejsu użytkownika
Aby zbudować interfejs użytkownika, należy przeciągnąć pięć instancji klasy Button na listę wyświetlania i nadać im następujące nazwy:
playButton
,
pauseButton
,
stopButton
,
backButton
i
forwardButton
.
Dla każdej z tych instancji klasy Button należy przypisać funkcję obsługi zdarzenia
click
, co ilustruje poniższy urywak kodu:
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);
Metoda
buttonClickHandler()
zawiera instrukcję switch określającą, który przycisk został kliknięty, co ilustruje poniższy 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;
}
}
Następnie należy dodać instancję klasy Slider do listy wyświetlania i nadać jej nazwę
volumeSlider
. Poniższy kod ustawia właściwość
liveDragging
instancji suwaka na
true
i definiuje detektor zdarzeń
change
dla tej instancji:
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);
Należy dodać instancję klasy ProgressBar do listy wyświetlania i nadać jej nazwę
positionBar
. Właściwości
mode
tej instancji przypisujemy wartość manual, co ilustruje poniższy urywek kodu:
positionBar.mode = ProgressBarMode.MANUAL;
Na koniec należy dodać instancję klasy Label do listy wyświetlania i nadać jej nazwę
positionLabel
. Wartość tej instancji klasy Label będzie ustawiana przez instancję klasy Timer.
Wykrywanie metadanych obiektu wideo
Gdy program Flash Player napotyka metadane każdego z ładowanych plików wideo, zwrotnie wywoływana jest funkcja
onMetaData()
właściwości
client
obiektu NetStream. Poniższy kod inicjuje obiekt Object i konfiguruje określoną funkcję obsługi wywołania zwrotnego:
client = new Object();
client.onMetaData = metadataHandler;
Metoda
metadataHandler()
kopiuje dane do właściwości meta zdefiniowanej wcześniej w kodzie. Umożliwia to dostęp do metadanych bieżącego pliku wideo w dowolnym momencie, w całej aplikacji. Następnie wymiary obiektu wideo na stole montażowym są dopasowywane do wymiarów odczytanych z metadanych. Na koniec instancja paska postępu positionBar jest przemieszczana, a jej rozmiar jest aktualizowany na podstawie rozmiaru aktualnie odtwarzanego pliku wideo. Poniższy kod zawiera całą metodę
metadataHandler()
:
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;
}
Dynamiczne wczytywanie wideo
Do dynamicznego ładowania poszczególnych plików wideo aplikacja używa obiektów NetConnection i NetStream. Poniższy kod tworzy obiekt NetConnection i przekazuje wartość
null
do metody
connect()
. Wartość
null
powoduje, że program Flash Player łączy się z serwerem lokalnym, a nie z serwerem zdalnym, takim jak Flash Media Server.
Poniższy kod tworzy instancje klas NetConnection i NetStream, definiuje detektor zdarzeń
netStatus
i przypisuje obiekt
client
klasy Object do właściwości
client
:
nc = new NetConnection();
nc.connect(null);
ns = new NetStream(nc);
ns.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
ns.client = client;
Metoda
netStatusHandler()
jest wywoływana po każdej zmianie statusu wideo. Do takich zmian zalicza się rozpoczęcie i zatrzymanie odtwarzania, buforowanie wideo lub brak możliwości znalezienia strumienia wideo. Poniższy kod analizuje listę wartości przekazanej ze zdarzeniem
netStatusHandler()
:
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.
}
}
Kod przedstawiony powyżej odczytuje właściwość code obiektu informacyjnego i filtruje kody "NetStream.Play.Start", "NetStream.Play.StreamNotFound" oraz "NetStream.Play.Stop". Wszystkie pozostałe kody będą ignorowane. Jeśli zdarzenie informuje o rozpoczęciu odtwarzania strumienia wideo, uruchamiana jest instancja klasy Timer, która aktualizuje położenie głowicy odtwarzania. Jeśli nie jest możliwe znalezienie strumienia lub odtwarzanie zostało zatrzymane, obiekt Timer jest zatrzymywany, a aplikacja próbuje odtworzyć następny plik wideo z listy odtwarzania.
Przy każdym wywołaniu obiektu Timer instancja paska postępu
positionBar
aktualizuje swoje bieżące położenie, wywołując metodę
setProgress()
klasy ProgressBar, a instancja klasy Label
positionLabel
jest aktualizowana poprzez wpisanie czasu od początku odtwarzania i całkowitego czasu trwania bieżącego pliku wideo.
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.
}
}
Sterowanie głośnością wideo
Istnieje możliwość sterowania głośnością dynamicznie załadowanego wideo poprzez przypisywanie wartości właściwości
soundTransform
obiektu NetStream. Aplikacja odtwarzacza umożliwia modyfikowanie głośności poprzez zmianę wartości instancji
volumeSlider
. Poniższy kod ilustruje sposób zmiany głośności poprzez przypisanie wartości składnika Slider do obiektu SoundTransform we właściwości
soundTransform
obiektu NetStream:
private function volumeChangeHandler(event:SliderEvent):void
{
volumeTransform.volume = event.value;
ns.soundTransform = volumeTransform;
}
Sterowanie odtwarzaniem wideo
Pozostały kod aplikacji steruje odtwarzaniem wideo po osiągnięciu końca strumienia wideo lub wymuszonego przez użytkownika przeskoku do poprzedniego lub następnego pliku wideo.
Poniższa metoda pobiera adres URL wideo z obiektu XMLList dla aktualnie wybranego indeksu:
private function getVideo():String
{
return videosXML[idx].@url;
}
Metoda
playVideo()
wywołuje metodę
play()
obiektu NetStream w celu załadowania aktualnie wybranego wideo:
private function playVideo():void
{
var url:String = getVideo();
ns.play(url);
}
Metoda
playPreviousVideo()
dekrementuje indeks bieżącego pliku wideo, wywołuje metodę
playVideo()
w celu załadowania nowego pliku wideo i sprawia, że pasek postępu staje się widoczny:
private function playPreviousVideo():void
{
if (idx > 0)
{
idx--;
playVideo();
positionBar.visible = true;
}
}
Ostatnia metoda,
playNextVideo()
, inkrementuje indeks pliku wideo i wywołuje metodę
playVideo()
. Jeśli bieżący plik wideo jest ostatnim na liście odtwarzania, wywoływana jest metoda
clear()
obiektu Video, a właściwość
visible
instancji paska postępu jest ustawiana na
false
:
private function playNextVideo():void
{
if (idx < (videosXML.length() - 1))
{
idx++;
playVideo();
positionBar.visible = true;
}
else
{
idx++;
vid.clear();
positionBar.visible = false;
}
}
|
|
|