一、使用方法
MediaPlayer可以播放以下资源:
1、Local resources
2、Internal URIs, such as one you might obtain from a Content Resolver
3、External URLs (streaming)
示例代码如下:
1、播放res/raw下的视频(代码摘自:http://wear.techbrood.com/guide/topics/media/mediaplayer.html):
MediaPlayer mediaPlayer = MediaPlayer.create(context, R.raw.sound_file_1); mediaPlayer.start(); // no need to call prepare(); create() does that for you2、播放Uri格式的文件(代码摘自:http://wear.techbrood.com/guide/topics/media/mediaplayer.html)
3、播放Url的文件(代码摘自:http://wear.techbrood.com/guide/topics/media/mediaplayer.html)Uri myUri = ....; // initialize Uri here MediaPlayer mediaPlayer = new MediaPlayer(); mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mediaPlayer.setDataSource(getApplicationContext(), myUri); mediaPlayer.prepare(); mediaPlayer.start();
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();
可以看到,播放uri和url的方式基本一样,区别在于setDataSource调用的方法不同。其实,播放res/raw的视频文件也可以采用uri的方式,
uri = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.video);
然后就可以使用上面的第二种方式播放。
至此,MediaPlayer已经初始化完毕,但还有以下问题需要解决:给它设置播放界面(SurfaceView),prepare需要异步调用( prepareAsync()
),播放状态管理,释放播放器。以下章节会介绍。
二、设置显示界面(SurfaceView)
需要在SurfaceView创建完毕的时候才能设置。所以,如果你的SurfaceView已经创建完毕,可以直接调用
mediaPlayer.setDisplay(surfaceView.getHolder()); 如果需要调用一个新的界面来播放视频,这时候就要监听SurfaceView的回调事件,在surfaceCreate函数里调用setDisplay的方法。
示例代码如下(代码摘自:http://www.open-open.com/lib/view/open1341754267229.html):
surfaceView = (SurfaceView)
this
.findViewById(R.id.video_surface);
//给SurfaceView添加CallBack监听
holder = surfaceView.getHolder();
mCallBack = new SurfaceHolder.Callback(){
@Override
public
void
surfaceChanged(SurfaceHolder arg0,
int
arg1,
int
arg2,
int
arg3) {
// 当Surface尺寸等参数改变时触发
Log.v(
"Surface Change:::"
,
"surfaceChanged called"
);
}
@Override
public
void
surfaceCreated(SurfaceHolder holder) {
// 当SurfaceView中的Surface被创建的时候被调用
//在这里我们指定MediaPlayer在当前的Surface中进行播放
player.setDisplay(holder);
//在指定了MediaPlayer播放的容器后,我们就可以使用prepare或者prepareAsync来准备播放了
player.prepareAsync();
}
@Override
public
void
surfaceDestroyed(SurfaceHolder holder) {
Log.v(
"Surface Destory:::"
,
"surfaceDestroyed called"
);
}
}
holder.addCallback(
mCallBack
);
//为了可以播放视频或者使用Camera预览,我们需要指定其Buffer类型
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
三、异步prepare
由于在UI线程调用prepare()可能会导致ANR,所以,最好要使用异步调用prepare的方法,然后再监听prepare,在prepare完成的时候,再调用mediaPlay的start方法。
调用方法如下(代码摘自:http://www.open-open.com/lib/view/open1341754267229.html):
mOnPreparedListener = new OnPreparedListener(){
@Override
public
void
onPrepared(MediaPlayer player) {
// 当prepare完成后,该方法触发,在这里我们播放视频
//首先取得video的宽和高
vWidth = player.getVideoWidth();
vHeight = player.getVideoHeight();
if
(vWidth > currDisplay.getWidth() || vHeight > currDisplay.getHeight()){
//如果video的宽或者高超出了当前屏幕的大小,则要进行缩放
float
wRatio = (
float
)vWidth/(
float
)currDisplay.getWidth();
float
hRatio = (
float
)vHeight/(
float
)currDisplay.getHeight();
//选择大的一个进行缩放
float
ratio = Math.max(wRatio, hRatio);
vWidth = (
int
)Math.ceil((
float
)vWidth/ratio);
vHeight = (
int
)Math.ceil((
float
)vHeight/ratio);
//设置surfaceView的布局参数
surfaceView.setLayoutParams(
new
LinearLayout.LayoutParams(vWidth, vHeight));
//然后开始播放视频
player.start();
}
}
mediaPlayer.setOnPreparedListener(mOnPreparedListener);
mediaPlayer.
prepareAsync();
当然,meidaPlayer还有很多其它的监听方法,如视频尺寸变化,播放结束,播放出错等。具体参考官方文档或上面示例代码的出处也有解释。
四、状态管理
看官网的这张图:
meidiaPlayer有些函数的调用有状态限制。
五、释放mediaPlayer
在你不需要播放视频的时候,就需要释放掉资源,方法如下:
mediaPlayer.release(); mediaPlayer = null;