Nella lezione precedente abbiamo descritto la classe MediaPlayer come uno strumento in grado di fornire funzionalità multimediali, che consentono la fruizione
di contenuti audio e video in un'app Android.
Nell'esempio presentato in precedenza lo si è utilizzato per realizzare un semplice lettore MP3.
In questa lezione, sperimenteremo le sue capacità di gestione dei video. Grazie al MediaPlayer, infatti, potremo riprodurre un filmato all'interno della nostra
app. L'esempio che vedremo utilizzerà un file multimediale contenuto tra le risorse del progetto, ma accenneremo anche all'utilizzo del MediaPlayer per la fruizione di filmati disponibili in rete.
L'esempio
Il video che vorremo visualizzare sarà collocato nelle risorse, in particolare nella cartella raw destinata a contenere file di una tipologia non
perfettamente inquadrabile tra le categorie standard (layout, values, menu, drawable, ecc...).
Nel codice che verrà presentato, pertanto, ci riferiremo al video come risorsa, ed il suo ID sarà R.raw.video.
Quanto già appreso in precedenza in merito al MediaPlayer resta valido. In questo caso ci occuperemo per lo più di istanziarlo (sempre con il metodo di
comodo create
), avviare la proiezione del video e rilasciare le risorse al termine delle operazioni.
Il layout
Si è volutamente scelto di utilizzare un layout molto semplice. L'unica View al suo interno svolge il ruolo di “contenitore” del video:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#EEFFCD"
android:padding="20dp" >
<SurfaceView
android:id="@+id/surfView"
android:layout_width="match_parent"
android:layout_height="300dp" />
</RelativeLayout>
Il contenuto del layout sarà una SurfaceView
, una superficie disegnabile “incastonata” nella finestra dell’interfaccia utente. Solitamente, non è necessario specificare altre impostazioni, se non la posizione e le dimensioni.
I contenuti al suo interno vengono manipolati mediante un oggetto di classe SurfaceHolder. Un riferimento ad esso può essere recuperato tramite il metodo
getHolder()
, disponibile nella classe SurfaceView.
Il codice
L'Activity implementa l'interfaccia SurfaceHolder.Callback, che richiede il completamento di tre metodi: surfaceCreated
, surfaceChanged
,
surfaceDestroyed
. La loro invocazione si verificherà, rispettivamente, la prima volta che la superficie viene creata, ogni volta che subisce dei
cambiamenti e quando viene distrutta.
Nel nostro esempio, implementiamo soltanto il metodo surfaceCreated. Al suo interno, sicuri dell'avvenuta creazione della superficie, potremo
predisporre il codice di avvio del video.
Ecco l'Activity:
public class MyActivity extends Activity implements SurfaceHolder.Callback
{
private MediaPlayer mediaPlayer;
private SurfaceHolder holder;
private SurfaceView surface;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
surface = (SurfaceView) findViewById(R.id.surfView);
holder = surface.getHolder();
holder.addCallback(this);
}
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
mediaPlayer= MediaPlayer.create(this,R.raw.video);
mediaPlayer.setDisplay(holder);
mediaPlayer.setOnPreparedListener(
new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
mediaPlayer.start();
}
}
);
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
mediaPlayer.release();
}
});
}
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i2, int i3) {
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
}
}
Appena avviato l'esempio, vedremo il video apparire ed andare in esecuzione nel layout. Prima di farlo però dovremo ricordarci di inserire un video nelle
risorse.
All'interno del metodo onCreate
dell'Activity, non facciamo altro che svolgere impostazioni di base: assegnamo un layout alla UI e facciamo in modo che il
SurfaceHolder utilizzi l'Activity stessa come listener per i propri eventi di callback.
Più interessante è invece il codice all'interno del metodo surfaceCreated
. Per prima cosa, viene recuperato un riferimento al MediaPlayer tramite create()
, e viene passato anche l'ID del filmato come argomento.
Successivamente assegnamo il display al MediaPlayer indicando, in pratica, quale sarà il contenitore del video.
Affinchè il video possa essere avviato al momento opportuno, invocheremo il metodo start() all'interno di un listener di classe
OnPreparedListener. Analogamente, vorremo poter liberare memoria al termine della proiezione; pertanto, all'interno di un listener di tipo
OnCompletionListener, invocheremo il metodo release()
, sempre appartenente alla classe MediaPlayer.
Video “remoti”
Prima di terminare, vediamo come potere visualizzare un video remoto. In questo caso, il file che vogliamo riprodurre non sarà contenuto nelle risorse, bensì disponibile in rete ad un determinato URL. Per riprodurlo, quindi, dovremo:
- inserire nel file AndroidManifest.xml la permission per l'accesso a Internet:
<uses-permission android:name="android.permission.INTERNET" />
- invocare un overload del metodo
create()
che non richieda un ID di una risorsa, ma un oggetto Uri contenente l'indirizzo remoto del video:
mediaPlayer = MediaPlayer.create(this,Uri.parse("http://www.example.com/video.mp4"));