Tuesday, March 6, 2012

Play media on surfaceview using android.media.MediaPlayer

Last exercise "Play the selected video media using build-in media player, by intent with action of Intent.ACTION_VIEW". In this exercise, we will implement our simple MediaPlayer to play the video, in seperated activity.

Play media on surfaceview using android.media.MediaPlayer

Implement a new PlayerActivity.java, extends Activity implements SurfaceHolder.Callback.
package com.exercise.AndroidListMedia;

import java.io.IOException;

import android.app.Activity;
import android.graphics.PixelFormat;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.media.AudioManager;

public class PlayerActivity extends Activity
implements SurfaceHolder.Callback {

Uri targetUri;

MediaPlayer mediaPlayer;
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
boolean pausing = false;;

@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.playerlayout);

TextView mediaUri = (TextView)findViewById(R.id.mediauri);
targetUri = this.getIntent().getData();
mediaUri.setText(targetUri.toString());

Button buttonPlayVideo = (Button)findViewById(R.id.playvideoplayer);
Button buttonPauseVideo = (Button)findViewById(R.id.pausevideoplayer);

getWindow().setFormat(PixelFormat.UNKNOWN);
surfaceView = (SurfaceView)findViewById(R.id.surfaceview);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setFixedSize(176, 144);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
mediaPlayer = new MediaPlayer();

buttonPlayVideo.setOnClickListener(new Button.OnClickListener(){

@Override
public void onClick(View arg0) {
pausing = false;

if(mediaPlayer.isPlaying()){
mediaPlayer.reset();
}

mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDisplay(surfaceHolder);

try {
mediaPlayer.setDataSource(getApplicationContext(), targetUri);
mediaPlayer.prepare();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

mediaPlayer.start();

}});

buttonPauseVideo.setOnClickListener(new Button.OnClickListener(){

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
if(pausing){
pausing = false;
mediaPlayer.start();
}
else{
pausing = true;
mediaPlayer.pause();
}
}});
}

@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
mediaPlayer.release();
}

@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub

}

@Override
public void surfaceCreated(SurfaceHolder arg0) {
// TODO Auto-generated method stub

}

@Override
public void surfaceDestroyed(SurfaceHolder arg0) {
// TODO Auto-generated method stub

}

}


Add a new layout file, /res/layout/playerlayout.xml, for the PlayerActivity.java.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<TextView
android:id="@+id/mediauri"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/playvideoplayer"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="- PLAY Video -"/>
<Button
android:id="@+id/pausevideoplayer"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="- PAUSE Video -"/>
<SurfaceView
android:id="@+id/surfaceview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>

</LinearLayout>


Modify the main activity, AndroidListMediaActivity.java, to start PlayerActivity.java once media clicked.
package com.exercise.AndroidListMedia;

import android.app.ListActivity;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.View;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.Toast;

public class AndroidListMediaActivity extends ListActivity {

SimpleCursorAdapter adapter;

final Uri mediaSrc = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String[] from = {
MediaStore.MediaColumns.TITLE};
int[] to = {
android.R.id.text1};

Cursor cursor = managedQuery(
mediaSrc,
null,
null,
null,
MediaStore.Audio.Media.TITLE);

adapter = new SimpleCursorAdapter(this,
android.R.layout.simple_list_item_1, cursor, from, to);
setListAdapter(adapter);
}

@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
Cursor cursor = adapter.getCursor();
cursor.moveToPosition(position);

String _id = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media._ID));

Uri playableUri
= Uri.withAppendedPath(mediaSrc, _id);

Toast.makeText(this, "Play: " + playableUri.toString(), Toast.LENGTH_LONG).show();

Intent intent = new Intent();
intent.setClass(AndroidListMediaActivity.this,
PlayerActivity.class);
intent.setData(playableUri);
startActivity(intent);
}


}


Finally, modify AndroidManifest.xml, to add the new activity PlayerActivity.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.exercise.AndroidListMedia"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk android:minSdkVersion="10" />

<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:name=".AndroidListMediaActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".PlayerActivity"
android:label="@string/app_name" >
</activity>
</application>

</manifest>


Download the files.

Next:
- Play media in Fragment, run on Android 3.0 Tablet.

3 comments:

Alvaro said...

Thanks, it has helped me :)

Andrew B said...

Yea this article helped me make logic to play videos that are in a listview. Great work thanks!

Hagen B. said...

I know this is written long ago but hopefully you can answer. I am playing a video with surfaceView and then drawing on top of that view, I want to save the video with the canvas on top. Any help please?