IMPORTANT: Per accedir als fitxer de subversion: http://acacha.org/svn (sense password). Poc a poc s'aniran migrant els enllaços. Encara però funciona el subversion de la farga però no se sap fins quan... (usuari: prova i la paraula de pas 123456)

El Android multimedia framework inclou suport per executar una amplia diversitat de tipus de medis de forma que sigui fàcil d'integrar àudio, vídeo o imatges a les aplicacions Android.

Els fitxers de media es pode executar des de fitxers emmagatzemats en local que poden estar dins dels fitxers o recursos Android de la mateixa aplicació (raw resources), de fitxers del sistema de fitxers local (p. ex. la memòria SSD) o d'streams de dades (Streaming). S'utilitzen les API MediaPlayer.

Classes i paquets

android.media

android.media.MediaPlayer

MediaPlayer és la classe principal de l'API i permet executar tant àudio com vídeo.

android.media.AudioManager

AudioManager és la classe que administra els recursos d'àudio i la sortida d'àudio del dispositiu.

Permisos. Fitxer de manifest

Al fitxer de manifest de l'aplicació (vegeu Manifest.xml) cal assignar els permisos correctes a l'aplicació:

   <uses-permission android:name="android.permission.INTERNET" />
   <uses-permission android:name="android.permission.WAKE_LOCK" />

Diagrama d'estats

El control de l'execució de medis (aka playback) es controlat per una màquina d'estats. El següent diagrama mostra el cicle de vida i els estats de l'objecte MediaPlayer:

Andrescorazon Android Multi mediaplayer state diagram.gif

Els ovoides representen els estats. A les fletxes apareixen les operacions de playback que provoquen un transició d'estat. Les fletxes simples representen mètodes síncrons, en canvi els dobles representen mètodes asíncrons.

Els estats possibles són:

  • Idle: és l'estat en que es troba l'objecte just després de ser creat o just després d'un reset. Estat inicial.
  • Error: per múltiples raons (per posar alguns exemples: un format no suportat, un timeout d'Streaming, resolució massa alta, etc.) el reproductor pot fallar en qualsevol moment. Sigui quin sigui l'error el sistema invoca sempre el mètode OnErrorListener.onError() sempre i quan s'hagi registrat prèviament un OnErrorListener amb el mètode setOnErrorListener(android.media.MediaPlayer.OnErrorListener). En tot cas l'objecte entrarà en l'estat d'error i només es podrà sortir d'aquest estat i reutilitzar l'objecte amb un reset o amb un release.
  • Initialized: Cal executar un dels següents mètodes setDataSource(FileDescriptor), setDataSource(String, setDataSource(Context, Uri) o setDataSource(FileDescriptor, long, long) per passar a l'estat inicialitzat. Cal tenir en compte que els MediaPlayer creats amb un new van a l'estat Idle, però els creats amb mètodes creadors de l'objecte no, aquest últims es creen ja inicialitzats. Un excepció de tipus IllegalStateException succeïx quan es crida a qualsevol dels mètodes setDataSource() des de un estat diferent al Idle. Hi ha dos formes en que es pot arribar a l'estat prepared.
  • Prepared: l'objecte MediaPlayer ha d'entrar en aquest estat abans de poder fer un play dels continguts multimèdia. Hi ha dos formes d'assolir aquest estat:
  • Sincronament: si arriba amb el mètode prepare() un cop s'ha executat amb èxit.
  • Asíncronament: si arriba amb el mètode prepareAsync() , en aquest cas primer es canvia l'estat de l'objecte a Prepared i mentrestant es realitzen les tasques per preparar realment l'objecte. Consulteu Execució asíncrona.
  • Un cop la preparació s'acaba (sigui síncrona o asíncrona) el sistema crida al mètode onPrepared() de la interfície OnPreparedListener, sempre i quan s'hagi enregistrat un objecte de tipus OnPreparedListener utilitzant el mètode: setOnPreparedListener(android.media.MediaPlayer.OnPreparedListener). Els mètodes prepare() o prepareAsync() només es poden cridar des de l'estat initialized o stoppped sinó succeirà una IllegalStateException.
En aquest estats es poden fer ajustos com el controlar el volum, looping invocant els mètodes corresponents...
  • Started: s'arriba a aquest al finalitzar correctament l'execució del mètode start(). Es pot utilitzar el mètode isPlaying() per tal de comprovar si un MediaPlayer s'està executant. Durant l'execució es crida al mètode OnBufferingUpdateListener.onBufferingUpdate() si prèviament s'ha registrat un OnBufferingUpdateListener amb el mètode: setOnBufferingUpdateListener(OnBufferingUpdateListener). Això permet controlar els buffers al fer Streaming.Cridar el mètode start en un MediaPlayer que ja estigui en aquest estat no té cap efecte.
  • Paused: s'entra en aquest estat quan el mètode pause() s'executa correctament. Cal fer notar que la transició de Started a paused és asíncrona i pot tardar diversos segons, per exemple en el cas de continguts d'Streaming.
  • Stopped: S'arriba a aquest estat un cop executat correctament el mètode stop(). A diferència de la pausa no es pot reprendre l'execució amb start() si no es torna a preparar l'objecte amb els mètode prepare() o prepareAsync.
  • PlayBackcompleted: si arriba un cop acabada la reproducció dels medis i un cop executat el mètode OnCompletion.onCompletion() sempre i quan s'hagi registrat un OnCompletionListener amb setOnCompletionListener(OnCompletionListener) i sinó està activat el Looping (setLooping(boolean)). Un start torna a executar el medi des de l'inici.
  • End: just després de cridar release(). L'objecte deixa d'existir i utilitzar recursos dels sistema. Estat final.

Utilitzar el MediaPlayer

Un objecte de la classe MediaPlayer facilita l'execució d'àudio i vídeo amb una configuració mínima.

És possible executar:

Podeu consultar una llista dels formats suportats a:

http://developer.android.com/guide/appendix/media-formats.html

Vegem un exemple:

 MediaPlayer mediaPlayer = MediaPlayer.create(context, R.raw.sound_file_1);
 mediaPlayer.start(); // no need to call prepare(); create() does that for you

L'exemple executa un àudio d'un raw resource (carpeta res/raw/):

Ara vegem un exemple de com utilitzar una URI:

 Uri myUri = ....; // initialize Uri here
 MediaPlayer mediaPlayer = new MediaPlayer();
 mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
 mediaPlayer.setDataSource(getApplicationContext(), myUri);
 mediaPlayer.prepare();
 mediaPlayer.start();

O un exemple d'una URL remota:

 String url = "http://........"; // your URL here
 MediaPlayer mediaPlayer = new MediaPlayer();
 mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
 mediaPlayer.setDataSource(url);
 mediaPlayer.prepare(); // might take long! (for buffering, etc)
 mediaPlayer.start();

IMPORTANT: Cal implementar les excepcions adients per controlar els errors en cas que el recurs a executar no existeixi (IllegalArgumentException i IOException).

Alliberar recursos. Releasing MediaPlayer

OnDestroy

Fils d'execució. Execució asíncrona

Executar un medi com un servei en segon terme

Handling asynchronous errors

VideoView

VideoView és un Android Widget que permet veure de forma simple un vídeo a la nostra aplicació.

NOTA: Internament utilitza MediaPlayer.

Exemple bàsic:

Layout XML:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#FFFFFFFF" >

    <VideoView
        android:id="@+id/videoView_video"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentTop="true"
        android:layout_centerInParent="true" />

</RelativeLayout>

Codi Java:

 @Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		VideoView videoView = (VideoView) findViewById(R.id.videoView_video);

		Uri path = Uri.parse("android.resource://com.example.reproducirvideo/"
				+ R.raw.intromono);

		videoView.setVideoURI(path);
                videoView.setMediaController(new MediaController(this));
                videoView.requestFocus();
		videoView.start();
	}

Recursos:

Exemples

Aturar la reproducció quan es passa de treballar amb cascos a treballar sense. AUDIO_BECOMING_NOISY Intent

Vegeu també

Enllaços externs