background image

 

 

Java Media Framework

Kamil Płaczko

JMF (Java Media Framework) – technologia 
umożliwiająca wstawianie multimediów do 
aplikacji napisanych w 

Javie

, oraz transmisję 

audio/video za pomocą protokołu RTP

background image

 

 

…..o  Javie  

Java jest 

obiektowym

 

językiem programowania

 

stworzonym przez grupę roboczą pod kierunkiem 

Jamesa Goslinga

 z firmy 

Sun Microsystems

. Java 

jest językiem tworzenia 

programów źródłowych

 

kompilowanych

 do 

kodu bajtowego

, czyli postaci 

wykonywanej przez 

maszynę wirtualną

. Język 

cechuje się 

silnym typowaniem

. Jego 

podstawowe koncepcje zostały przejęte z języka 

Smalltalk

 (maszyna wirtualna, 

garbage collection

) oraz z języka 

C++

 (duża część składni i słów 

kluczowych). 

background image

 

 

Autorzy języka Java określili kilkanaście kluczowych 
koncepcji swojego języka. Najważniejsze z nich to: 

Obiektowość - W przeciwieństwie do 

proceduralno

-

obiektowego

 języka C++, Java jest silnie 

ukierunkowana na 

obiektowość

. Wszelkie dane i 

akcje na nich podejmowane są pogrupowane w klasy 
obiektów
. O obiekcie można myśleć jako o 
samoistnej części programu, która może przyjmować 
określone stany i posiada określone zachowania
które mogą zmieniać te stany bądź przesyłać dane 
do innych obiektów. Wyjątkiem od całkowitej 
obiektowości 
(jak np. w Smalltalku) są typy proste (int, float itp.).

background image

 

 

// oznacza komentarz 
// w tej postaci to obiekt reprezentujący kolorowy punkt 
public class Figura { 

// właściwości (atrybuty/pola) 
private float środekX;
private float środekY; 
private int kolor;       //tak naprawdę do 
przechowywania(tworzenia)
                                //koloru używa się zazwyczaj obiektu 
java.awt.Color
 
// operacje (metody)

 public float obliczPole()
{ return 0; } 
public float obliczObwód()
{ return 0; } 
public void wyświetl(){...} ... } 

background image

 

 

W Javie wszystkie obiekty są pochodną obiektu nadrzędnego 

(jego klasa nazywa się po prostu Object), z którego 

dziedziczą

 

podstawowe zachowania i właściwości, dzięki czemu 
wszystkie posiadają wspólny podzbiór podstawowych 
możliwości, takich jak ich: identyfikacja, porównywanie, 
kopiowanie, niszczenie czy wsparcie dla 

programowania współbieżnego

.

 

background image

 

 

Sieciowość i obsługa 

programowania rozproszonego

Dzięki wykorzystaniu reguł obiektowości, Java nie 
widzi różnicy między danymi płynącymi z 

pliku

 

lokalnego a danymi z pliku dostępnego przez 

HTTP

 czy 

FTP

.

Biblioteki Javy udostępniają wyspecjalizowane funkcje 
umożliwiające programowanie rozproszone - zarówno 
między aplikacjami Javy (

RMI

) jak i między aplikacją 

Javy a aplikacjami napisanymi w innych językach (

CORBA

usługi 

web 

service). Inne biblioteki 

udostępniają możliwość pisania aplikacji 
uruchamianych w 

przeglądarkach internetowych

 (

aplety

) oraz aplikacji działających ciągle po stronie 

serwera

 (

serwlety

).

background image

 

 

Niezawodność i bezpieczeństwo

 

W zamierzeniu Java miała zastąpić 

C++

 - obiektowego 

następcę języka 

C

. Jej projektanci zaczęli od rozpoznania cech 

języka C++, które są przyczyną największej liczby błędów 
programistycznych, by stworzyć język prosty w użyciu, 
bezpieczny i niezawodny.
O ile po pięciu odsłonach Javy jej prostota jest dyskusyjna, o 
tyle język faktycznie robi dużo, by utrudnić programiście 
popełnienie błędu. Przede wszystkim Java posiada system 

wyjątków

 czyli sytuacji, gdy kod programu natrafia na nie 

przewidywane trudności, takie jak np.:

----operacje na elemencie poza zadeklarowaną granicą 

tablicy

 

lub elemencie pustym 

----czytanie z niedostępnego pliku lub nieprawidłowego adresu 
URL 

-----podanie nieprawidłowych danych przez użytkownika 

background image

 

 

W innych językach programowania programista oczywiście 
może wprowadzić wewnętrzne testy sprawdzające poprawność 
danych, pozycję indeksu tablicy, inicjalizację zmiennych itd., 
ale jest to jego dobra wola i nie jest to jakoś szczególnie 
wspierane przez dany język. W Javie jest inaczej - obsługa 
wyjątków jest obowiązkowa, bez tego program się nie 
skompiluje. Przy tym obiekty wchodzące w skład pakietu 
standardowego Javy (i gros obiektów z pakietów pochodzących 
od poważnych programistów niezależnych) implementują 
wyjątki w każdym miejscu kodu, którego wykonanie jest 
niepewne ze względu na okoliczności zewnętrzne.

Sama obsługa wyjątków polega na napisaniu kodu, który 
wykona się w odpowiedzi na taką sytuację nadzwyczajną. Może 
to być np. podstawienie wartości domyślnej przy natrafieniu na 
nieprawidłową wartość parametru, zaniechanie danej akcji i 
powrót do stanu stabilnego czy choćby zapisanie pracy przed 
wyjściem. W sytuacji wyjątkowej program przerywa normalne 
wykonanie i tworzy specjalny obiekt wyjątku odpowiedniej 
klasy, który "wyrzuca" z normalnego biegu programu. 
Następnie zdefiniowany przez użytkownika kod "łapie" ten 
obiekt wyjątku i podejmuje odpowiednie działanie. 

background image

 

 

Działanie może być dwojakiego typu: wspomniane wyżej środki 
zaradcze lub odrzucenie takiego „błedu " dalej, do bloku 
programu, który nakazał wykonanie wadliwej operacji. Takie 
podawanie sobie wyjątku może być wieloetapowe i jeśli 
skończy się w bloku głównym programu powoduje jego 
przerwanie i ogłoszenie błędu krytycznego.

Oprócz systemu wyjątków Java od wersji 1.4 posiada dwa inne 
systemy wspomagające pisanie niezawodnych programów: 
logowanie i asercje.

 Pierwsze pozwalają na zapisanie w plikach dziennika przebiegu 
działania programu, z dodatkową możliwością filtrowania 
zawartości, określenia poziomu logowanych błędów itp. Drugie 
rozwiązanie pozwala na upewnienie się, że pewne założenia co 
do określonych wyrażeń (np. że liczba, z której wyciągamy 
pierwiastek jest nieujemna) są prawdziwe. 

Asercje są o tyle ciekawe, że działają tylko z odpowiednią opcją 
wykonania programu, dzięki czemu programista może 
sprawdzić działanie programu, a później bez wysiłku 
spowodować pominięcie testowej części kodu po prostu przez 
ominięcie tej opcji.

background image

 

 

Krytyka i kontrowersje

Język Java pomimo swoich wielu zalet, posiada wiele 

wad w tym takie, które wzbudzają liczne 

kontrowersje:

 

Najczęściej wymienianą wadą języka Java jest to, że 

programy pisane w Javie wykonują się wolniej niż 

programy pisane w językach negatywnie 

kompilowanych (np. C++). Zarzut ten odnosi się 

szczególnie do starych wersji Javy, kiedy 

zaawansowane mechanizmy takie jak JIT albo 

współbieżny odśmiecacz nie były dostępne. Obecnie 

zdania są mocno podzielone. Można podać 

przykłady programów zarówno takich, które w Javie 

będą wykonywały się wolniej niż w C++, jak i takich, 

które będą wykonywały się szybciej. 

background image

 

 

Javie zarzuca się, że niezbyt dobrze nadaje się do 
zastosowań czasu rzeczywistego. Głównym problemem 
jest brak przewidywalności wydajności oraz 
nieoczekiwane przestoje powodowane działaniem 
odśmiecacza. W nowych wersjach Javy ten drugi problem 
został radykalnie ograniczony, jednak nadal do 
zastosowań czasu rzeczywistego lepiej stosować języki 
natywnie kompilowane. 

Często Javie zarzucane jest to, że posiada mniejszą 
funkcjonalność niż np. C++, co ogranicza programistę. 
Jako przykład przywołuje się czasami fakt, że aby 
uruchomić niewielki program trzeba napisać dłuższy kod 
programu. Niektórzy jednak zwracają uwagę, że również 
język C++ nie posiada wielu elementów, które można 
znaleźć w Javie jak np. klasy anonimowe, odśmiecacz, 
system pakietów

, dynamiczne ładowanie klas czy 

reflection API.

 

background image

 

 

Co możemy odtwarzać?

Niestety nie wszystko. JMF nie korzysta 

bowiem z kodeków, które mamy w systemie, 

lecz z własnych dekoderów

Np. support dla mp3 został dodany DOPIERO 

w listopadzie 2004!

Najważniejsze typy plików obsługiwane przez 

JMF 2.1.1

AIFF, AVI (ale bez kompresji Div-X ;-) lub XviD!), 

MIDI, MPEG-1 Video, MPEG Audio Layer II i Layer III, 

QuickTime, Sun Audio, Wave

Przy transmisji przez protokół RTP (przez sieć), lista 

ta zdecydowanie się zawęża 

background image

 

 

Dostępne formaty video

Dostępne formaty video

Format

Content Type

Quality

CPU 

Requirements

Bandwidth 

Requirements

Cinepak

AVI
QuickTime

Medium

Low

High

MPEG-1

MPEG

High

High

High

H.261

AVI
RTP

Low

Medium

Medium

H.263

QuickTime
AVI
RTP

Medium

Medium

Low

JPEG

QuickTime
AVI
RTP

High

High

High

Indeo

QuickTime AVI

Medium

Medium

Medium

background image

 

 

Dostępne formaty audio

Dostępne formaty audio

Format

Content Type

Quality

CPU 

Requirement

s

Bandwidth 

Requirements

PCM

AVI

QuickTime

WAV

High

Low

High

Mu-Law

AVI

QuickTime

WAV

RTP

Low

Low

High

ADPCM

(DVI,

IMA4)

AVI

QuickTime

WAV

RTP

Medium

Medium

Medium

MPEG-1

MPEG

High

High

High

MPEG

Layer3

MPEG

High

High

Medium

GSM

WAV

RTP

Low

Low

Low

G.723.1

WAV

RTP

Medium

Medium

Low

background image

 

 

Obiekt Player

Za odtwarzanie danych odpowiadają obiekty typu 
Player – udostępniają funkcjonalność typowego 
odtwarzacza – play, stop, przewijanie, głośność itp.

Tworzenie playera:

public SimpleAudioPlayer(URL url) throws IOException,
NoPlayerException, CannotRealizeException 
{

audioPlayer = Manager.createRealizedPlayer(url);

}

public SimpleAudioPlayer(File file) throws IOException, 
NoPlayerException, CannotRealizeException 
{

this(file.toURL());

}

background image

 

 

Player działa na stanach

Obiekt Playera jest maszyną opartą na stanach:

Unrealized – obiekt dopiero co stworzony

Realizing – Player zaczyna pobierać informacje o danych

Realized – 

wiemy co będziemy odtwarzać, możemy zwrócić 

komponenty GUI

Prefetching – zaczynamy przygotowanie do 

odtwarzania

Prefetched – mamy już zbuforowane dane

Started – gra i buczy 

Większość metod JMF jest nieblokująca

W naszym przypadku kazaliśmy Managerowi stworzyć 

Player będący od razu w stanie Realized. Dopóki obiekt 

nie został stworzony, główny wątek programu w którym 

tworzyliśmy Player, został zablokowany.

Takie rzeczy zwykle robi się w oddzielnym wątku

background image

 

 

Odtwarzanie: audioPlayer.play()

Zatrzymanie: audioPlayer.stop()

Usunięcie obiektu: audioPlayer.close()

Szybkość odtwarzania: audioPlayer.setRate()

0.0-1.0 – wolniej

1.0 – normalnie

>1.0 – szybciej (The Chipmunks)

Wartości ujemne – podobno od tyłu, ale ciężko mi na 

słuch ocenić czy to naprawdę działa

Głośność: 

GainControl gain = audioPlayer.getGainControl();
gain.setLevel(); // w zakresie od 0.0f do 1.0f 

background image

 

 

Przewijanie:

Time czas = audioPlayer.getDuration();

int czasSekundy = duration.getSeconds();

if (przewinDo >= 0 && przewinDo <= czasSekundy) {

/* mała uwaga – obiekt Time bez rzutowania na

 double stworzy się nam dla czasu w 

nanosekundach co nas raczej słabo urządza */

Time goto = new Time((double)przewinDo);

audioPlayer.setMediaTime(goto);

}

background image

 

 

Tworzenie komponentów 
odtwarzacza video

Component visual = player.getVisualComponent() – 

zwraca komponent odpowiedzialny za wyświetlanie danych 

video

Component ctrl = player.getControlPanelComponent() 

– zwraca panel sterujący

Component 

     vol = player.getGainControl().getControlComponent() 

– głośniej/ciszej. Obiekt GainControl może służyć do 

regulowania głośności z poziomu programu (np. fajny fade 

na końcu)

Warto by się upewnić, czy obiekty nie są przypadkiem null – 

np. getVisualComponent() wywołany dla obiektu Playera 

pliku audio „raczej” będzie miał wartość null. Jeżeli mimo to 

będziemy chcieli dodać go do okna – Java wyrzuci wyjątek.

background image

 

 

Dodajemy komponenty do 
okna

Teraz wystarczy już tylko dodać to do JFrame. 
W konstruktorze dodajemy:

JPanel panel = new JPanel();

panel.setLayout(new BorderLayout());

panel.add(visual, BorderLayout.NORTH);

panel.add(ctrl, BorderLayout.CENTER);

panel.add(vol, BorderLayout.SOUTH);

this.add(panel);

this.pack();

To wszystko! Komponenty są już skojarzone z 
odpowiednim obiektem Playera. Wystarczy kliknąć na 
play i zacznie się odtwarzanie.


Document Outline