Introduzione
I video sul telefono cellulare sono diventati una realtà.
Riprodurre un video che abbiamo scaricato o trasportato
sul telefono è una funzionalità offerta
da tutti i dispositivi di terza generazione.
E' interessante tuttavia capire come si possa riprodurre
un video localizzato su di un server o magari in streaming.
Vedremo come queste funzionalità siano offerte
dalle MMAPI mentre le AMMS ci consentono di settare
la camera del telefono per realizzare riprese di alta
qualità e di effettuare transcodifiche.
Riproduzione
di un video con MMAPI
Analogamente a quanto visto per le foto, i due oggetti
principali di cui abbiamo bisogno per la riproduzione
o la registrazione di un video sono Player e Canvas
o Form: Player per accedere al flusso video e Canvas
o Form per la visualizzazione sul display.
Ricordiamo che se utilizziamo una Canvas tutte le operazioni
relative alla riproduzione vanno implementate in una
classe che estende Canvas e viceversa se utilizziamo
un Form.
Abbiamo
già visto, a proposito dell'audio, quali sono
gli stati in cui un Player può transitare e gli
eventi che tali transizioni possono generare.
Il Player lo si ottiene tramite un Manager e un locator
nel quale viene specificata in sintassi URI la locazione
del video:
Player
player = Manager.createPlayer("http://myserver/video.mpg");
La
codifica video supportata dipende ovviamente dal dispositivo.
La maggior parte dei telefoni ad oggi supporta il formato
3gpp, basato su MPEG-4 e definito dal Third Generation
Partnership Project.
Oltre al protocollo http, il file video può essere
locale, può essere contenuto in un InputStream,
oppure per i dispositivi che consentono lo streaming
il video si può ricevere via RTP (Real Time Protocol)
secondo questa sintassi:
"rtp://"
address [ ":" port ] [ "/" type
]
Ad
esempio:
rtp://220.2.2.2:7777/video
Se il dispositivo non supporta la riproduzione di quel
particolare tipo di video viene lanciata una MediaException.
Mentre se il file non è disponibile viene lanciata
una IOException.
E' necessario poi che il Player sia nello stato realized
per ottenere le risorse di cui ha bisogno per la riproduzione:
player.realize
( );
Per
visualizzare il video sul display del telefono utilizziamo
il VideoControl:
VideoControl
videoControl = (VideoControl)(player.getControl("VideoControl"));
A
questo punto inizializziamo il VideoControl secondo
la modalità con cui vogliamo che il flusso ripreso
venga visualizzato. Nel caso in cui volessimo utilizzare
una Canvas avremo:
videoControl.initDisplayMode(VideoControl.USE_DIRECT_VIDEO,this);
Se
invece vogliamo utilizzare un Form:
Item
item = (Item) videoControl.initDisplayMode(GUIControl.USE_GUI_PRIMITIVE,
null);
append(item);
Ora
basta avviare il Player e rendere visibile sul display
il video:
player.start();
videoContro.setVisible(true);
A
parte la semplice visualizzazione è sicuramente
utile realizzare un vero e proprio player (nel suo significato
reale), in cui si possa mettere in pausa la riproduzione,
ricominciarla, cambiarne il volume e la velocità.
Quanto descritto di seguito è ovviamente valido
anche nel caso di riproduzione audio.
Abbiamo visto come avviare la riproduzione, metterla
in pausa è banale:
public
void pausa(){
try {
player.stop();
} catch (MediaException me) {}
}
Per
avviare la riproduzione dal punto in cui ci si era fermati
basta ristartare il Player:
public
void continua(){
try {
player.start();
} catch (MediaException me) {}
}
Per
riavviare la riproduzione dall'inizio occorre modificare
il punto di partenza temporale:
public
void riavvia(){
try {
player.setMediaTime(0);
player.start();
} catch (MediaException me) {}
}
Se
vogliamo rendere "muta" la riproduzione dobbiamo
far ricorso a VolumeControl:
public
void mute(){
try {
VolumeControl vc = (VolumeControl)
player.getControl("VolumeControl");
cc.setMute(true);
} catch (Exception me) {}
}
Analogamente
per ripristinare il volume:
public
void unmute(){
try {
VolumeControl vc = (VolumeControl) player.getControl("VolumeControl");
vc.setMute(false);
} catch (Exception me) {}
}
Se
invece si desiderasse cambiare il volume a proprio piacimento
si potrebbe utilizzare un TextField o una Gauge per
impostare il valore (che va da 0 a 100) per poi settarlo
in questo modo:
public
void setVolume(int level){
try {
VolumeControl vc = (VolumeControl) player.getControl("VolumeControl");
vc.setLevel (level);
} catch (Exception me) {}
}
Possiamo
anche decidere di cambiare la velocità di riproduzione.
Ricordando che il metodo setRate(int millirate) di RateControl
utilizza come parametro un valore in "millipercentuale"
(vedi articolo http://www.mokabyte.it/2005/06/j2me_multimedia-2.htm),
per raddoppiare la velocità di riproduzione avremo:
public
void raddoppiaVelocita(){
try {
RateControl rc = (RateControl) player.getControl("RateControl");
rc.setRate (200000);
} catch (Exception me) {}
}
Ovviamente
il dispositivo deve supportare l'aumento o la diminuzione
di velocità. Per conoscere quali sono le velocità
minima e massima di riproduzione basta utilizzare i
metodi getMinRate( ) e getMaxRate( ) di RateControl.
Registrazione
di un video con MMAPI
Per descrivere l'implementazione della registrazione
di un video, pensiamo alla situazione di uso reale.
Possiamo pensare che, una volta avviata l'applicazione,
essa ci mostri ciò che la telecamera riprende.
La pressione di un tasto (ad esempio con label "Registra
video") avvierà la registrazione, mantenendo
attiva la vista della camera e la pressione di "Stop
registrazione" ci permetterà di interromperla.
Come già visto per la cattura di una foto, per
connettere l'applicazione al dispositivo camera del
telefono costruiamo il Player in questo modo:
Player
player = Manager.createPlayer("capture://video?widht=640&height=480");
Il
formato del video catturato in questo caso è
640x480 e la codifica è quella di default per
il dispositivo. Le varie opzioni di codifica utilizzabili
sono le stesse descritte a proposito della cattura di
una foto.
Se il dispositivo non supporta la cattura video con
le caratteristiche richieste viene lanciata una MediaException.
A questo punto in modo identico a quanto visto per la
riproduzione (in effetto andiamo a riprodurre ciò
che la camera riprende) si ha:
player.realize
( );
videoControl = (VideoControl)(player.getControl("VideoControl"));
videoControl.initDisplayMode(VideoControl.USE_DIRECT_VIDEO,this);
player.start();
videoControl.setVisible(true);
Vediamo
ora ciò che succede quando si preme il tasto
relativo alla voce "Registra video". Nel metodo
CommandAction avremo:
if
(c == recordCommand) {
recordVideo();
}
Il
metodo recordVideo ( ) innanzitutto rimuove il comando
"Registrazione video" ed aggiunge "Stop
registrazione". Successivamente chiede al Player
il Control di tipo RecordControl ed inizia la memorizzazione
dei dati su un ByteArrayOutputStream:
public
void recordVideo() {
removeCommand(captureCommand);
removeCommand(recordCommand);
addCommand(stopRecordCommand);
rc = (RecordControl)player.getControl("RecordControl");
output = new ByteArrayOutputStream();
rc.setRecordStream(output);
rc.startRecord();
}
L'unica
azione che possiamo ora intraprendere è "Stop
registrazione":
if
(c == stopRecordCommand) {
stopRecording();
}
Il
metodo stopRecording ( ) interrompe la registrazione
e trasferisce i dati da un ByteArrayOutputStream ad
un ByteArray:
public
void stopRecording () {
try {
rc.commit();
ByteArray videoData = output.toByteArray();
} catch (MediaException me){
. . .
} catch (IOException ioe) {
. . .
}
}
Una
volta registrato il video si può salvarlo su
file system utilizzando le File Connection API, per
poi riguardarlo o uploadarlo su di un server.
Gestione
video con AMMS
Le AMMS non implementano un modo alternativo per la
riproduzione e la registrazione di un video. Queste
operazioni avvengono allo stesso modo descritto per
le MMAPI.
La differenza risiede nella possibilità di regolare
la camera del telefono per effettuare una ripresa quanto
migliore e personalizzata possibile.
I controlli disponibili sono stati già descritti
nell'articolo sulle foto e sono: CameraControl, ZoomControl,
ExposureControl, FocusControl.
Vediamo nello specifico alcuni metodi di CameraControl
relativi ai video e perciò tralasciati nel precedente
articolo:
- int[]
getSupportedVideoResolutions ( ): restituisce le risoluzioni
video supportate come coppia (larghezza, altezza).
Ad esempio se la camera supporta le risoluzioni 1024x768
e 640x 580, il risultato sarà un array di interi
[1024, 768, 640, 480].
- void
setVideoResolution(int index): imposta la risoluzione
video. Il parametro "index" indica la coppia
restituita da getSupportedVideoResolutions( ): "0"
indica la prima coppia, "1" la seconda e
così via.
- int
getVideoResolution( ): restituisce la risoluzione
video corrente sotto forma di intero che indica la
coppia restituita da getSupportedVideoResolutions(
): "0" indica la prima coppia, "1"
la seconda e così via.
AMMS
fornisce anche la possibilità di cambiare il
formato video utilizzando VideoFormatControl.
Per far questo dobbiamo prima di tutto creare un MediaProcessor
attraverso un GlobalManager e inizializzarlo:
MediaProcessor
processor = GlobalManager.createMediaProcessor("video/mpeg");
InputStream inputStream = // InputStream che contiene
il video mpeg
OutputStream outputStream = // OutputStream che conterrà
il video di output
processor.setInput(inputStream);
processor.setOutput(outputStream);
processor.start():
I
formati di video che si possono settare sono presenti
nella seguente tabella:
Format
PARAM_VERSION_TYPE Specification Market name
video/mjpeg MJPEG_DEFAULT No standard MJPEG
video/h263 H263 ITU H.263 H.263
video/h264 H264 ITU H.264 H.264
video/mpeg MPEG_1 MPEG-1 MPEG-1
video/mpeg MPEG_2 MPEG-2 MPEG-2
video/mpeg MPEG_4_SVP MPEG-4 Simple Visual Profile MPEG-4
video/mpeg MPEG_4_AVC MPEG-4 Advanced Video Codec (ITU
H.264) H.264
video/vnd.rn-realvideo REALVIDEO_8 RealVideo ver 8 RealVideo
video/x-ms-wm WMV_9 Windows Media Video WMV
Vediamo come cambiare il formato del video mpeg su cui
abbiamo prima costruito il MediaProcessor, in H.263:
VideoFormatControl
videoFormat = (VideoFormatControl)
processor.getControl("javax.microedition.media.control.VideoFormatControl");
videoFormat.setFormat("video/h263");
processor.complete();
Conclusioni
In questo articolo abbiamo visto come riprodurre e registrare
un video in J2ME.
Queste operazioni possono risultare molto utili per
realizzare un VideoBlog, oppure un'applicazione di infotainment
nella quale si voglia dare all'utente la possibilità
di visualizzare dei video in modalità embedded.
Bibliografia
[1] http://jcp.org/en/jsr/detail?id=234
[2] http://java.sun.com/products/mmapi/index.jsp
[3] http://java.sun.com/products/midp/index.jsp
Vincenzo
Viola è nato a Formia (LT) il 03/11/1977,
laureato in Ingegneria delle Telecomunicazioni presso
l'Università Federico II di Napoli con una tesi
sulla segmentazione automatica di video digitali in
scene, con sviluppo software implementato su piattaforma
Java - Oracle. Lavora come progettista software per
una Mobile Company che offre la sua consulenza ai gestori
di telefonia e alle major del settore ICT.
|