giovedì 26 maggio 2011

Android: esecuzione di file audio e video

L'esecuzione di file audio e video all'interno di un'applicazione Android avviene attraverso la classe MediaPlayer. Le risorse da riprodurre vanno messe nella cartella res/raw del progetto. Il file può essere letto eventualmente dal filesystem (ad esempio sulla scheda di memoria, referenziato dal suo path) oppure da un flusso di rete (in tal caso sarà referenziato dall'url per la risorsa). Android permette la riproduzione dei principali formati audio e video, alcuni di questi sono: mp3, ogg e flac per i file audio, 3gp ed mp4 per i file video. I protocolli supportati per i flussi di rete sono: http e rtsp. L'audio viene riprodotto nell'altoparlante del dispositivo, dalla documentazione leggo che non è possibile eseguire file audio all'interno di una conversazione telefonica (se ricordo bene esiste un'applicazione che riesce a farlo comunque).
Dopo aver aggiunto al progetto i file audio e/o video da riprodurre (nella cartella res/raw) è possibile avviarne la riproduzione attraverso i seguenti passi:
  • creare un'istanza della classe MediaPlayer, l'oggetto ottenuto verrà usato in seguito per avviare o fermare la riproduzione. Il costruttore della classe istanzia un oggetto vuoto, se abbiamo un riferimento alla risorse da riprodurre è preferibile usare il metodo create(context,resource) della classe MediaPlayer che accetta due parametri: l'oggetto Context da usare e il riferimento alla risorsa. Tale riferimento può essere fornito attraverso l'id (univoco) associato alla risorsa (nella classe R), che corrisponde al nome del file nella cartella res/raw, oppure attraverso l'uri (uniform resource identifier). Vedremo in seguito come riprodurre file audio e/o video da flussi di rete o da filesystem;
  • l'oggetto creato è in grado di riprodurre la risorsa all'interno dell'applicazione Android. I metodi start() e stop(), rispettivamente, avviano e fermano la riproduzione della risorsa. Attenzione, se la riproduzione della risorsa viene fermata con il metodo stop() non possiamo, poi, riavviarla! In tal caso andranno invocati prima i metodi reset() e prepare();
MediaPlayer sound=MediaPlayer.create(getBaseContext(),R.raw.sound);
sound.start();
Particolarmente utile è a mio avviso il metodo isPlaying(). Questo metodo, se invocato su un oggetto MediaPlayer, ritorna un valore booleano: true se l'oggetto MediaPlayer è in esecuzione, false altrimenti. Usatelo, ad esempio, se non volete sovrapporre l'esecuzione di due file audio!
MediaPlayer sound1=MediaPlayer.create(getBaseContext(),R.raw.sound1);
MediaPlayer sound2=MediaPlayer.create(getBaseContext(),R.raw.sound2);

public void playSound1() {
if (!sound2.isPlaying()) sound1.start();
}

public void playSound2() {
if (!sound1.isPlaying()) sound2.start();
}
Immaginate di avviare la riproduzione di un file audio o video all'interno di un'applicazione, dopo averla utilizzata per un po decidete di uscire dall'applicazione, premendo il tasto back. La riproduzione del file continuerà anche mettendo in background l'applicazione! Lo scenario che ho appena descritto può andar bene per alcune applicazioni, per altre è preferibile terminare la riproduzione non appena l'utente mette l'applicazione in background. In tal caso non dimenticate di mettere una chiamata al metodo stop() sull'oggetto MediaPlayer che sta eseguendo il file audio nel metodo di callback pause().
Altri metodi particolarmente utili sono setLooping(boolean loop), che permette di abilitare la riproduzione continua della risorsa referenziata nell'oggetto MediaPlayer, e seekTo(int ms), che sposta la riproduzione a ms millisecondi dall'inizio.
La riproduzione da un file del filesystem o da un flusso di rete può avvenire sia attraverso il metodo create() visto sopra che attraverso il metodo setDataSource(). In quest'ultimo caso, dopo aver istanziato un oggetto MediaPlayer vuoto (senza riferimento a una risorsa) occorrerà invocare il metodo setDataSource(string resource) per caratterizzare con una stringa il path o l'uri della risorsa da riprodurre. Esistono altri metodi setDataSource(), quello appena indicato è sicuramente più immediato. Con questo metodo è possibile cambiare la risorsa referenziata dall'oggetto MediaPlayer, anche se assegnata in prima battuta con il metodo create(). In questo modo possiamo riciclare un oggetto MediaPlayer per eseguire prima un suono e successivamente un altro. Ogni volta che usiamo il metodo setDataSource() dobbiamo necessariamente invocare il metodo prepare().
MediaPlayer sounds=new MediaPlayer()
String path="SOME_PATH_HERE";
String file="FILE_NAME_HERE";

public void playSound1() {
if (!sounds.isPlaying()) {
try {
sounds.setDataSource(path+"/"+file);
sounds.prepare();
}
catch (IllegalArgumentException e) {
sounds=MediaPlayer.create(getBaseContext(),R.raw.default1);
}
catch (IOException e) {
sounds=MediaPlayer.create(getBaseContext(),R.raw.default1);
}
sounds.start();
}
}

public void playSound2() {
if (!sounds.isPlaying()) {
try {
sounds.setDataSource(path+"/"+file);
sounds.prepare();
}
catch (IllegalArgumentException e) {
sounds=MediaPlayer.create(getBaseContext(),R.raw.default2);
}
catch (IOException e) {
sounds=MediaPlayer.create(getBaseContext(),R.raw.default2);
}
sounds.start();
}
}
Il metodo setDataSource() può lanciare un IOExcpetion (se il file non viene trovato al path/uri indicato) e un IllegalArgumentException (se al metodo vengono passati degli argomenti non corretti).

Nessun commento:

Posta un commento