MediaPlayer主要用于播放音频,它是没有提供输出图像的输出界面,这时我们就用到了SurfaceView控件,将它与MediaPlayer结合起来,就能达到了视频的输出了。
程序说明:
这个例子只是描述了MediaPlayer的基本使用步骤和方式,MediaPlayer还有多种使用方式和方法,并不只局限于例子所介绍的一种。具体来看:
1)如何获得MediaPlayer实例:
可以使用直接new的方式:MediaPlayer mp = new MediaPlayer();
也可以使用create的方式,如:MediaPlayer mp = MediaPlayer.create(this, R.raw.cat);//这时就不用调用setDataSource了。
2)如何设置要播放的文件:
MediaPlayer要播放的文件主要包括3个来源:
a. 用户在应用中事先自带的resource资源。例如:MediaPlayer.create(this, R.raw.cat);
b. 存储在SD卡或其他文件路径下的媒体文件。例如:mp.setDataSource("/sdcard/cat.3gp");
c. 网络上的媒体文件。例如:mp.setDataSource("http://www.citynorth.cn/music/confucius.mp3");
MediaPlayer的setDataSource一共四个方法:
setDataSource(String path)
setDataSource (FileDescriptor fd)
setDataSource (Context context, Uri uri)
setDataSource (FileDescriptor fd, long offset, long length)
3)对播放器的主要控制方法:
Android通过控制播放器的状态的方式来控制媒体文件的播放,其中:prepare()和prepareAsync()提供了同步和异步两种方式设置播放器进入prepare状态,需要注意
的是,如果MediaPlayer实例是由create方法创建的,那么第一次启动播放前不需要再调用prepare()了,因为create方法里已经调用过了。
start()是真正启动文件播放的方法。
pause()和stop()比较简单,起到暂停和停止播放的作用。
seekTo()是定位方法,可以让播放器从指定的位置开始播放,需要注意的是该方法是个异步方法,也就是说该方法返回时并不意味着定位完成,尤其是播放的网络文 件,真正定位完成时会触发OnSeekComplete.onSeekComplete(),如果需要是可以调用setOnSeekCompleteListener(OnSeekCompleteListener)设置监听器来处理 的。
release()可以释放播放器占用的资源,一旦确定不再使用播放器时应当尽早调用它释放资源。
reset()可以使播放器从Error状态中恢复过来,重新回到Idle状态。注意:更换资源时就要先调用mp.reset(), 第一次加载资源不用。
4)设置播放器的监听器:
MediaPlayer提供了一些设置不同监听器的方法来更好地对播放器的工作状态进行监听,以期及时处理各种情况。
如: setOnCompletionListener(MediaPlayer.OnCompletionListener listener)、setOnErrorListener(MediaPlayer.OnErrorListener listener)等,设置播放器时需要考虑到 播放器可能出现的情况设置好监听和处理逻辑,以保持播放器的健壮性。
注意:需要在res目录下新建raw文件夹,并在raw文件夹中放入3gp或MP4等视频格式文件,替换cat和test两个视频文件。
好了,不多说,直接上源码:
布局文件activity_main.xml
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
android:layout_width="fill_parent"
android:layout_height="350dp" >
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
java代码:MainActivity.java
package com.example.surfaceplayer;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Activity;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.view.View;
import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.SeekBar;
public class MainActivity extends Activity implements OnClickListener{
private SeekBar skb_video = null;
private Button btn_start_video = null;
private Button btn_stop_video = null;
private Button btn_last_video = null;
private Button btn_next_video = null;
private SurfaceView surfaceView;
private SurfaceHolder surfaceHolder;
private MediaPlayer m = null;
private Timer mTimer;
private TimerTask mTimerTask;
private boolean isChanging=false;//互斥变量,防止定时器与SeekBar拖动时进度冲突
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initListener();
m = MediaPlayer.create(this, R.raw.cat);//读取视频
}
private void initView(){
btn_start_video = (Button) this.findViewById(R.id.btn_start);
btn_stop_video = (Button) this.findViewById(R.id.btn_stop);
btn_last_video = (Button) this.findViewById(R.id.btn_last);
btn_next_video = (Button) this.findViewById(R.id.btn_next);
skb_video = (SeekBar) this.findViewById(R.id.SeekBar02);
surfaceView = (SurfaceView) findViewById(R.id.SurfaceView01);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.setFixedSize(100, 100);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
private void initListener(){
btn_start_video.setOnClickListener(this);
btn_stop_video.setOnClickListener(this);
btn_last_video.setOnClickListener(this);
btn_next_video.setOnClickListener(this);
skb_video.setOnSeekBarChangeListener(new SeekBarChangeEvent());
}
class SeekBarChangeEvent implements SeekBar.OnSeekBarChangeListener{
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
// TODO Auto-generated method stub
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
isChanging=true;
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
int time = seekBar.getProgress();
System.out.println("time = " + time);
m.seekTo(seekBar.getProgress());
isChanging=false;
}
}
@Override
public void onClick(View v) {
if(v==btn_stop_video)
{
if (m.isPlaying()) {
m.pause();
}else{
m.start();
}
}
else{
if(v == btn_last_video){
m.reset();
m=MediaPlayer.create(MainActivity.this, R.raw.cat);//读取视频
}
else if(v == btn_next_video){
m.reset();
m=MediaPlayer.create(MainActivity.this, R.raw.test);//读取视频
}
// else if(v==btn_start_video)
// {
// m.reset();//恢复到未初始化的状态
// m=MediaPlayer.create(testMedia.this, R.raw.cat);//读取视频
skb_video.setMax(m.getDuration());//设置SeekBar的长度
m.setAudioStreamType(AudioManager.STREAM_MUSIC);
m.setDisplay(surfaceHolder);//把视频画面输出到SurfaceView
try {
// m.setDataSource("rtsp://192.168.1.130:554/100060008/2031-03-10-18-00.mp4");
// m.prepare();
m.prepareAsync();
m.start();//播放
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// }
}
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);//shuangji
//定时器记录播放进度
mTimerTask = new TimerTask() {
@Override
public void run() {
// TODO Auto-generated method stub
if(isChanging==true)
return;
skb_video.setProgress(m.getCurrentPosition());
}
};
mTimer = new Timer();
mTimer.schedule(mTimerTask, 0, 10);
}
}