playerunknown 进游戏set 箱子怎么获得

小新专栏 的BLOG
用户名:小新专栏
文章数:88
评论数:48
访问量:903484
注册日期:
阅读量:5863
阅读量:12276
阅读量:408757
阅读量:1097007
51CTO推荐博文
package com.mike. import java.io.IOE import android.app.A import android.content.I import android.media.MediaP import android.media.MediaPlayer.OnBufferingUpdateL import android.media.MediaPlayer.OnCompletionL import android.media.MediaPlayer.OnErrorL import android.media.MediaPlayer.OnPreparedL import android.media.MediaPlayer.OnSeekCompleteL import android.media.MediaPlayer.OnVideoSizeChangedL import android.media.MediaR import android.media.MediaRecorder.OnInfoL import android.net.U import android.os.B import android.os.E import android.util.L import android.view.D import android.view.SurfaceH import android.view.SurfaceV import android.view.V import android.widget.LinearL public class VedioPlayByMediaPlayerDemoActivity extends Activity implements &&&&OnCompletionListener, OnErrorListener, OnPreparedListener, &&&&OnSeekCompleteListener, OnVideoSizeChangedListener, &&&&SurfaceHolder.Callback, android.media.MediaPlayer.OnInfoListener, &&&&OnBufferingUpdateListener { &&private SurfaceView mSurfaceV &&private SurfaceHolder mSurfaceH &&private MediaPlayer mMediaP &&private int mVideoWidth = 0; &&private int mVideoHeight = 0; &&private boolean readyToPlay = false; &&public static final String TAG = "MEDIA_PLAY_VEDIO_PLAY"; &&/** Called when the activity is first created. */ &&@Override &&public void onCreate(Bundle savedInstanceState) { &&&&super.onCreate(savedInstanceState); &&&&setContentView(R.layout.main); &&&&Log.d("path", "path is :" + Environment.getExternalStorageDirectory()); &&&&mSurfaceView = (SurfaceView) findViewById(R.id.surfaceView1); &&&&mSurfaceHolder = mSurfaceView.getHolder(); &&&&mSurfaceHolder.addCallback(this);// 添加到回调监听器 &&&&mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);// 需要确保底层表面是一个推送缓冲区表面,需要将其应用于视频播放和摄像头预览 &&&&mMediaPlayer = new MediaPlayer(); &&&&// 设置各种监听 &&&&mMediaPlayer.setOnCompletionListener(this); &&&&mMediaPlayer.setOnErrorListener(this); &&&&mMediaPlayer.setOnInfoListener(this); &&&&mMediaPlayer.setOnPreparedListener(this); &&&&mMediaPlayer.setOnSeekCompleteListener(this); &&&&mMediaPlayer.setOnVideoSizeChangedListener(this); &&&&mMediaPlayer.setOnBufferingUpdateListener(this); &&&&String path = Environment.getExternalStorageDirectory() &&&&&&&&+ "/Movies/vedio1.mp4"; &&&&try { &&&&&&mMediaPlayer.setDataSource(path);// 此处可能抛出异常 &&&&} catch (IllegalArgumentException e) { &&&&&&// TODO Auto-generated catch block &&&&&&Log.v(TAG, e.getMessage()); &&&&&&this.finish(); &&&&} catch (IllegalStateException e) { &&&&&&// TODO Auto-generated catch block &&&&&&Log.v(TAG, e.getMessage()); &&&&&&this.finish(); &&&&} catch (IOException e) { &&&&&&// TODO Auto-generated catch block &&&&&&Log.v(TAG, e.getMessage()); &&&&&&this.finish(); &&&&} &&&&mMediaPlayer.setDisplay(mSurfaceHolder);// mediaPlayer将在其表面播放 &&&&try { &&&&&&mMediaPlayer.prepare();// prepare方法是同步的(synchronous),所以可能会阻塞,prepareAsync()是异步方法(asynchronous)。 &&&&} catch (IllegalStateException e) { &&&&&&// TODO Auto-generated catch block &&&&&&Log.v(TAG, e.getMessage()); &&&&&&this.finish(); &&&&} catch (IOException e) { &&&&&&// TODO Auto-generated catch block &&&&&&Log.v(TAG, e.getMessage()); &&&&&&this.finish(); &&&&} &&&&// 设置表面大小以匹配视频或显示器大小,取决于那个大小较小 &&&&mVideoWidth = mMediaPlayer.getVideoWidth(); &&&&mVideoHeight = mMediaPlayer.getVideoHeight(); &&&& &&&&int screenWidth = getWindowManager().getDefaultDisplay().getWidth(); &&&&int screenHeight = getWindowManager().getDefaultDisplay().getHeight(); &&&&if (mVideoWidth & screenWidth &&&&&&&&|| mVideoHeight & getWindowManager().getDefaultDisplay() &&&&&&&&.getHeight()) {//如果视频宽度大于显示器大小,得到比率 &&&&&&&&float heightRatio = (float)mVideoHeight / (float)screenH &&&&&&&&float widthRatio = (float)mVideoWidth / (float)screenW &&&&&&&& &&&&&&&&if (heightRatio & 1 || widthRatio &1) {//只需宽或高一个方向超出即可 &&&&&&&&&&&&&&&&&&&& if (heightRatio & widthRatio) {//以高为准 &&&&&&&&&&&&mVideoHeight = (int) Math.ceil((float)mVideoHeight / (float)heightRatio); &&&&&&&&&&&&mVideoWidth = (int) Math.ceil((float)mVideoWidth / (float)heightRatio);&&&&&&&&&&&& } else {//以宽为准 &&&&&&&&&&&&mVideoHeight = (int) Math.ceil((float)mVideoHeight / (float)widthRatio); &&&&&&&&&&&&mVideoWidth = (int) Math.ceil((float)mVideoWidth / (float)widthRatio); &&&&&&&& } &&&&&&&&&&&&&&&&&&&&} &&&&&&&&&&&&} &&&& &&&& &&&&//设置显示大小---- &&&&mSurfaceView.setLayoutParams(new LinearLayout.LayoutParams(mVideoWidth, mVideoHeight)); &&&&mMediaPlayer.start();//播放视频 &&} &&public void surfaceChanged(SurfaceHolder holder, int format, int width, &&&&&&int height) {// 当SurfaceView的底层表面的宽度,高度或者其他参数发生变化时,将调用SurfaceChanged方法 &&&&// TODO Auto-generated method stub &&&&Log.v(TAG, "surfaceChanged"); &&} &&public void surfaceCreated(SurfaceHolder holder) {// 因为实现了SurfaceHolder.Callback,并将其指定为回调监听器,所以将触发Surface的3个方法 &&&&// TODO Auto-generated method stub &&&&Log.v(TAG, "surfaceCreated"); &&} &&public void surfaceDestroyed(SurfaceHolder holder) {// 当Surface表面销毁时,将调用SurfaceDestroy方法 &&&&// TODO Auto-generated method stub &&&&Log.v(TAG, "surfaceDestroyed"); &&} &&public void onVideoSizeChanged(MediaPlayer mp, int width, int height) { &&&&// TODO Auto-generated method stub &&&&Log.v(TAG, "onVideoSizeChanged"); &&} &&public void onSeekComplete(MediaPlayer mp) { &&&&// TODO Auto-generated method stub &&&&Log.v(TAG, "onSeekComplete"); &&} &&public void onPrepared(MediaPlayer mp) { &&&&// TODO Auto-generated method stub &&&&Log.v(TAG, "onPrepared"); &&} &&public boolean onError(MediaPlayer mp, int what, int extra) { &&&&// TODO Auto-generated method stub &&&&Log.v(TAG, "onError"); &&&&if (what == MediaPlayer.MEDIA_ERROR_SERVER_DIED) { &&&&&&Log.v(TAG, "MEDIA_ERROR_SERVER_DIED"); &&&&&&mMediaPlayer.reset();// 可调用此方法重置 &&&&} else if (what == MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK) { &&&&&&Log.v(TAG, "MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK"); &&&&} else if (what == MediaPlayer.MEDIA_ERROR_UNKNOWN) { &&&&&&Log.v(TAG, "MEDIA_ERROR_UNKNOWN"); &&&&} &&&&return false;// 返回false,表示错误没有被处理 &&} &&public void onCompletion(MediaPlayer mp) { &&&&// TODO Auto-generated method stub &&&&Log.v(TAG, "onCompletion"); &&&&this.finish(); &&} &&public void onBufferingUpdate(MediaPlayer arg0, int arg1) { &&&&// TODO Auto-generated method stub &&&&Log.v(TAG, "onBufferingUpdate"); &&} &&public boolean onInfo(MediaPlayer mp, int what, int extra) {// 当出现关于播放媒体的特定信息需要发出警告时,将调用此方法 &&&&// TODO Auto-generated method stub &&&&Log.v(TAG, "onInfo"); &&&&switch (what) { &&&&case MediaPlayer.MEDIA_INFO_BAD_INTERLEAVING:// 当文件中的音频和视频数据不正确的交错时,将触发如下操作。 &&&&&&&&&&&&&&&&&&&&&&&&&&&&// 在一个正确交错的媒体文件中,音频和视频样本依序排列,从而使得播放能够有效平稳的进行。 &&&&&&Log.v(TAG, "MEDIA_INFO_BAD_INTERLEAVING extar is :" + extra); &&&&&&break; &&&&case MediaPlayer.MEDIA_INFO_METADATA_UPDATE:// 当心的元数据可用时,将触发它,android &&&&&&&&&&&&&&&&&&&&&&&&&&// 2.0以上版本可用。 &&&&&&Log.v(TAG, "MEDIA_INFO_METADATA_UPDATE extar is :" + extra); &&&&&&break; &&&&case MediaPlayer.MEDIA_INFO_NOT_SEEKABLE:// 媒体不能正确定位,意味着它可能是一个在线流 &&&&&&Log.v(TAG, "MEDIA_INFO_NOT_SEEKABLE extar is :" + extra); &&&&&&break; &&&&case MediaPlayer.MEDIA_INFO_VIDEO_TRACK_LAGGING:// 当无法播放视频时,可能是将要播放视频,但是视频太复杂 &&&&&&Log.v(TAG, "MEDIA_INFO_VIDEO_TRACK_LAGGING extar is :" + extra); &&&&&&break; &&&&case MediaPlayer.MEDIA_INFO_UNKNOWN: &&&&&&Log.v(TAG, "MEDIA_INFO_UNKNOWN extar is :" + extra); &&&&&&break; &&&&} &&&&return false; &&} }本文出自 “” 博客,请务必保留此出处
了这篇文章
类别:未分类┆阅读(0)┆评论(0)
14:20:53 10:14:07 15:08:09 13:58:29Android开发之MdiaPlayer详解
MediaPlayer类可用于控制音频/视频文件或流的播放,我曾在《Android开发之基于Service的音乐播放器》一文中介绍过它的使用。下面让我们看一下MediaPlayer类的详细介绍。 一、类结构:
java.lang.Object
android.media.MediaPlayer
& 二、构造方法和公有方法
构造方法:
Public Constructors
MediaPlayer()
默认构造方法。
公有方法:
Public Methods
static&MediaPlayer
create(Context&context,&Uri&uri,&SurfaceHolder&holder) 指定从资源ID对应的资源文件中来装载音乐文件,同时指定了SurfaceHolder对象并返回MediaPlyaer对象。
static&MediaPlayer
create(Context&context, int resid) 指定从资源ID对应的资源文件中来装载音乐文件,并返回新创建的MediaPlyaer对象。
static&MediaPlayer
create(Context&context,&Uri&uri) 从指定Uri装在音频文件,并返回新创建的MediaPlayer对象。
getCurrentPosition()
获取当前播放的位置。
getDuration()
获取音频的时长。
getVideoHeight()
获取视频的高度。
getVideoWidth()
获取视频的宽度。
isLooping()
判断MediaPlayer是否正在循环播放。
isPlaying()
判断MediaPlayer是否正在播放。
暂停播放。
准备播放(装载音频),调用此方法会使MediaPlayer进入Prepared状态。
prepareAsync()
准备播放异步音频。
释放媒体资源。
重置MediaPlayer进入未初始化状态。
seekTo(int msec)
寻找指定的时间位置。
setAudioStreamType(int streamtype)
设置音频流的类型。
setDataSource(String&path)
指定装载path路径所代表的文件。
setDataSource(Context&context,&Uri&uri,&Map&String,&String headers)
指定装载uri所代表的文件。
setDataSource(Context&context,&Uri&uri)
指定装载uri所代表的文件。
setDataSource(FileDescriptor&fd, long offset, long length)
指定装载fd所代表的文件中从offset开始长度为length的文件内容。
setDataSource(FileDescriptor&fd)
指定装载fd所代表的文件。
setDisplay(SurfaceHolder&sh)
设置显示方式。
setLooping(boolean looping)
设置是否循环播放。
setNextMediaPlayer(MediaPlayer&next)
设置当前流媒体播放完毕,下一个播放的MediaPlayer。
setOnBufferingUpdateListener(MediaPlayer.OnBufferingUpdateListener&listener)
注册一个回调函数,在网络视频流缓冲变化时调用。
setOnCompletionListener(MediaPlayer.OnCompletionListener&listener)
为Media Player的播放完成事件绑定事件监听器。
setOnErrorListener(MediaPlayer.OnErrorListener&listener)
为MediaPlayer的播放错误事件绑定事件监听器。
setOnPreparedListener(MediaPlayer.OnPreparedListener&listener)
当MediaPlayer调用prepare()方法时触发该监听器。
setOnSeekCompleteListener(MediaPlayer.OnSeekCompleteListener&listener)
当MediaPlayer调用seek()方法时触发该监听器。
setOnVideoSizeChangedListener(MediaPlayer.OnVideoSizeChangedListener&listener)
注册一个用于监听视频大小改变的监听器。
setScreenOnWhilePlaying(boolean screenOn)
置是否使用SurfaceHolder来显示。
setSurface(Surface&surface)
设置Surface。
setVideoScalingMode(int mode) 设置视频缩放的模式。
setVolume(float leftVolume, float rightVolume)
设置播放器的音量。
setWakeMode(Context&context, int mode)
为MediaPlayer设置低级电源管理行为。.
开始或恢复播放。
停止播放。
& 三、常用方法分析:
1.使用进度条:
进度条SeekBar可以用来显示播放进度,用户也可以利用SeekBar的滑块来控制音乐的播放。
SeekBar需要使用的一些方法:
setProgress(int value):设置滑块的位置方法为。
setMax(int value):设置进度条的最大长度。
setOnSeekBarChangeListener(OnSeekBarChangeListener l):设置SeekBar的进度改变事件。
MusicPlayer需要使用的一些方法:
getDuration():获得音乐长度为。
getCurrentPosition():获得现在播放的位置。
seekTo(int msec):调用seekTo()方法可以调整播放的位置。
seekTo(int)方法是异步执行的,所以它可以马上返回,但是实际的定位播放操作可能需要一段时间才能完成,尤其是播放流形式的音频/视频。当实际的定位播放操作完成之后,内部的播放引擎会调用客户端程序员提供的OnSeekComplete.onSeekComplete()回调方法。可以通过setOnSeekCompleteListener(OnSeekCompleteListener)方法注册。
seekTo(int)方法也可以在其它状态下调用,比如Prepared,Paused和PlaybackCompleted状态。此外,目前的播放位置,实际可以调用getCurrentPosition()方法得到,它可以帮助如音乐播放器的应用程序不断更新播放进度。
创建并使用进度条的步骤:
第一步:创建一个进度条
static SeekBarskbM skbMusic=(SeekBar)findViewById(R.id.skbMusic);
第二步:为进度条的改变事件注册并添加监听器
skbMusic.setOnSeekBarChangeListener(sChangeListener);
&&* SeekBar进度改变事件
&&*/ OnSeekBarChangeListenersChangeListener=new OnSeekBarChangeListener() {&&&&&&&&&&&&&&&&& &&&&&&&&@Override &&&&&&&&public void onStopTrackingTouch(SeekBar seekBar) { &&&&&&&&&&&&&&&&&&// TODO Auto-generated method stub &&&&&&&&&&&&&&&&&&//当拖动停止后,控制mediaPlayer播放指定位置的音乐 &&&&&&&&&&&&&&&&&&MusicService.mediaPlayer.seekTo(seekBar.getProgress()); &&&&&&&MusicService.isChanging=false;&& &&&&&&&&}&&&&&&&
&&&&&&&&@Override &&&&&&&&public void onStartTrackingTouch(SeekBar seekBar) { &&&&&&&&&&&&&&&&&&// TODO Auto-generated method stub &&&&&&&&&&&&&&&&&&MusicService.isChanging=true; &&&&&&&&}&&&&&&&
&&&&&&&&@Override &&&&&&&&public void onProgressChanged(SeekBar seekBar, int progress, &&&&&&&&&&&&&&&&&&&&&&&&&&&boolean fromUser) { &&&&&&&&&&&&&&&&&&// TODO Auto-generated method stub&&&&&&&&&&& &&&&&&&&} };
第三步:设置进度条的最大长度:
//getDuration()方法要在prepare()方法之后,否则会出现Attempt to call getDuration without a valid mediaplayer异常 MusicBox.skbMusic.setMax(mediaPlayer.getDuration());//设置SeekBar的长度
第四步:更新进度条
//----------定时器记录播放进度---------//
mTimer =new Timer();
mTimerTask =new TimerTask() {
&&& @Override
&&& publicvoid run() {
&&& &&& isTimerRunning=true;
&&&&&&& if(isChanging==true)//当用户正在拖动进度进度条时不处理进度条的的进度
&&&&&&&&&&&return;&
&&&&&&& MusicBox.skbMusic.setProgress(mediaPlayer.getCurrentPosition());
//每隔10毫秒检测一下播放进度 mTimer.schedule(mTimerTask, 0, 10);
2.装载音频文件:
为了让MediaPlayer来装载指定音频文件,MediaPlayer提供了如下简单的静态方法。
static MediaPlayer create(Context context, Uri uri):从指定Uri来装载音频文件,并返回新创建的MediaPlayer对象。
static MediaPlayer create(Context context, int resid):从 resid资源 ID对应的资源文件中装载音频文件,并返回新创建的MediaPlayer对象。
提示:上而这两个方法用起来非常方便,但这两个方法每次都会返回新创建的MediaPlayer对象,如来程序需要使用MediaPlayer循环播放多个音频文件,使用MediaPlayer的静态create方法就不太合适了,此时可通过MediaPlayer的setDataSource()方法来装载指定的音频文件。MediaPlayer提供了如下方法来指定装载相应的音频文件。
setDataSource(String path):指定装载path路径所代表的文件。
setDataSource(FileDescriptor fd, long offset,long length):指定装载fd所代表的文件中从offset开始长度为length的文件内容。
setDataSource(FileDescriptor fd):指定装载fd所代表的文件。
setDataSource(Context context, Uri uri):指定装载uri所代表的文件。
提示:执行上面所示的setDataSource()方法之后,MediaPlayer并未真正去装载那些音频文件,还需要调用MediaPlayer的prepare()方法去准备音频,所谓“准备”,就是让MediaPlayer真正去装载音频文件。
使用已有的MediaPlayer对象装载“一首”歌曲的代码模板为:
mPlayer.reset(); //装战下一竹歌曲 mPlayer.setDataSource(M/mnt/sdcard/next.mp3); //准备声音 mPlayer.prepare(); &播放 mPlayer.start(); } catch (IOException e) e.printStackTrace(); }
3.与MediaPlayer有关的事件监听器:
MediaPlayer提供了一些绑定事件监听器的方法,用于监听MediaPlayer播放过程中所发生的特定事件,绑定事件监听器的方法如下。
setOnCompletionListener(MediaPlayer.OnCompletionListener listener):为 Media Player的播放完成事件绑定事件监听器。
setOnErrorListener(MediaPlayer.OnErrorListener listener):为MediaPlayer的播放错误事件绑定事件监听器。
setOnPreparedListener(MediaPlayer.OnPreparedListener listener):当 MediaPlayer调用prepare()方法时触发该监听器。
setOnSeekCompleteListener(MediaPlayer.OnSeekCompleteListener listener):当MediaPlayer调用seek()方法时触发该监听器。
因此可以在创建一个MediaPlayer对象之后,通过为该MediaPlayer绑定监听器来监听相应的事件,例如如下代码:
//为MediaPlayer的播放完成事件绑定事件监听器
mPlayer.setOnErrorListener(new OnErrorListener() {&&&&&&&&&
&&& @Override
&&& publicboolean onError(MediaPlayer mp,int what,int extra) {&&&&&&&
&&&&&&& // TODO Auto-generated method stub
&&&&&&& //针对错误进行相应的处理
//&&&&&&&&&&&&&... ...
//为MediaPlayer的播放完成讲件绑定市件监听器
mPlayer.setOnCompletionListener(new OnCompletionListener() {&&&&&&&&&&&
&&& @Override
&&& publicvoid onCompletion(MediaPlayer mp) {
&&&&&&& // TODO Auto-generated method stub
&&&&&&&&&&&current++;
&&&&&&&&&&&prepareAndPlay(current);&&&
&&&&&&& } &&&});
& 四、MediaPlayer播放不同来源的音频文件:
1.播放应用的资源文件
播放应用的资源文件需要两步即:
1)&调用MediaPlayer的create(Context context,int resid)方法加指定资源文件。
2)&调用 MediaPlayer的 start()、pause()、stop()等方法控制播放即可。
例如如下代码:
MediaPlayer mPlayer=new MediaPlayer(); mPlayer.create(this, R.raw.music);
2.& 播放应用的原始资源文件
播放应用的资源文件按如下步骤执行。
1)&调用 Context的 getAssets()方法获取应用的 AssetManager。
2)&调用AssetManager对象的openFd(String name)方法打开指定的原生资源,该方法返回一个AssetFileDescriptor对象。
3)&调用 AssetFileDescriptor的 getFileDescriptor()、getStartOffset()和 getLength()方法来获取音频文件的FileDescriptor、开始位置、长度等。
4)&创建MediaPlayer对象(或利用已有的MediaPlayer对象),并调用MediaPlayer对象的setDataSource(FileDescriptor fd,long offset, long length)方法来装载音频资源。
5)&调用MediaPlayer对象的prepare()方法准备音频。
6)&调用MediaPlayer的start()、pause()、stop()等方法控制播放即可。
例如如下代码片段:
//获取assets目录下指定文件的AssetFileDescriptor对象
AssetFileDescriptor assetFileDescriptor=assetManager.openFd(musics[current]);
mediaPlayer.reset();//初始化mediaPlayer对象
mediaPlayer.setDataSource(assetFileDescriptor.getFileDescriptor(),&&&&&assetFileDescriptor.getStartOffset(), assetFileDescriptor.getLength());
//准备播放音乐
mediaPlayer.prepare();
//播放音乐
mediaPlayer.start();
3.& 播放外部存储器上音频文件
播放外部存储器上音频文件按如下步骤执行。
1)&创建MediaPlayer对象(或利用已有的MediaPlayer对象),并调用MediaPlayer对象的setDateSource(String path)方法装载指定的音频文件。&&
2)&调用MediaPlayer对象的prepare()方法准备音频。&&&&
3)&调用MediaPlayer的start()、pause()、stop()等方法控制播放即可。
例如如下代码:
//加载SD卡上的指定资源音频文件
mPlayer.setDataSource(&/mnt/You Are The One.mp3&);
mPlayer.prepare();//准备因音频
mPlayer.start();//播放音频
4.播放来自网络的音频文件
播放来自网络的音频文件?两种方式:1.直接使用MediaPlayer的静态create(Context context, Uri uri)方法;2.调用 MediaPlayer的setDataSource(Context context,Uri uri)装载指定Uri对应的音频文件。
以第二种方式播放来自网络的音频文件的步骤如下。
1.&根据网络上的音频文件所在的位置创建Uri对象。
2.&创建MediaPlayer对象(或利用己有的MediaPlayer对象),并调用MediaPlayer对象的 setDateSource(Context context,Uri uri)方法装载Uri对应的音频文件。
3.&调用MediaPlayer对象的prepare()方法准备音频。
4.&调用MediaPlayer的start()、pause()、stop()等方法控制播放即可。
例如如下代码片段:
Uri uri = Uri.parse(&/heihei.mp3&);
MediaPlayer mPlayer = new MediaPlayer();
//使用MediaPlayer根据Uri来加载指定的声音文件
mPlayer.setDataSource(this, uri);
mPlayer.prepare();//准备因音频 mPlayer.start();//播放音频
MediaPlayer除了调用prepare()方法来准备声音之外,还以调用prepareAsync()来准备声音,prepareAsync()与普通prepare()方法的区别在于,prepareAsync()是异步的,它不会阻塞当前的UI线程。 五、解析MdiaPlayer的状态图
上面这张状态转换图清晰的描述了MediaPlayer的各个状态,也列举了主要的方法的调用时序,每种方法只能在一些特定的状态下使用,如果使用时MediaPlayer的状态不正确则会引发IllegalStateException异常。
Idle状态:当使用new()方法创建一个MediaPlayer对象或者调用了其reset()方法时,该MediaPlayer对象处于idle状态。在处于Idle状态时,调用getCurrentPosition(), getDuration(), getVideoHeight(),getVideoWidth(),setAudioStreamType(int), setLooping(boolean), setVolume(float, float), pause(), start(), stop(), seekTo(int), prepare()或者 prepareAsync()方法都会出现相应错误。这两种方法的一个重要差别就是:当一个MediaPlayer对象刚被构建的时候,内部的播放引擎和对象的状态都没有改变,在这个时候调用以上的那些方法,框架将无法回调客户端程序注册的OnErrorListener.onError()方法,所以不会进入Error状态;但若这个MediaPlayer对象调用了reset()方法之后,再调用以上的那些方法,内部的播放引擎就会回调客户端程序注册的OnErrorListener.onError()方法,这时MediaPlayer会进入Error状态。
提示:使用new操作符创建的MediaPlayer对象处于Idle状态,而那些通过重载的create()便利方法创建的MediaPlayer对象却不是处于Idle状态。事实上,如果成功调用了重载的create()方法,那么这些对象已经是Prepare状态了。
End状态:通过release()方法可以进入End状态,只要MediaPlayer对象不再被使用,就应当尽快将其通过release()方法释放掉,以释放相关的软硬件组件资源,这其中有些资源是只有一份的(相当于临界资源)。如果MediaPlayer对象进入了End状态,则不会再进入任何其他状态了。
Initialized状态:这个状态比较简单,MediaPlayer调用setDataSource()方法就进入Initialized状态,表示此时要播放的文件已经设置好了。
提示:若当此MediaPlayer处于其它的状态下,调用setDataSource()方法,会抛出IllegalStateException异常。
Prepared状态:初始化完成之后还需要通过调用prepare()或prepareAsync()方法,这两个方法一个是同步的一个是异步的,只有进入Prepared状态,才表明MediaPlayer到目前为止都没有错误,可以进行文件播放。
提示:在不合适的状态下调用prepare()和prepareAsync()方法会抛出IllegalStateException异常。当MediaPlayer对象处于Prepared状态的时候,可以调整音频/视频的属性,如音量,播放时是否一直亮屏,循环播放等。
Preparing状态:这个状态比较好理解,主要是和prepareAsync()配合,如果异步准备完成,会触发OnPreparedListener.onPrepared(),进而进入Prepared状态。
Started状态:显然,MediaPlayer一旦准备好,就可以调用start()方法,这样MediaPlayer就处于Started状态,这表明MediaPlayer正在播放文件过程中。可以使用isPlaying()测试MediaPlayer是否处于了Started状态。如果播放完毕,而又设置了循环播放,则MediaPlayer仍然会处于Started状态,类似的,如果在该状态下MediaPlayer调用了seekTo()或者start()方法均可以让MediaPlayer停留在Started状态。
Paused状态:Started状态下MediaPlayer调用pause()方法可以暂停MediaPlayer,从而进入Paused状态,MediaPlayer暂停后再次调用start()则可以继续MediaPlayer的播放,转到Started状态,暂停状态时可以调用seekTo()方法,这是不会改变状态的。
Stop状态:Started或者Paused状态下均可调用stop()停止MediaPlayer,而处于Stop状态的MediaPlayer要想重新播放,需要通过prepareAsync()和prepare()回到先前的Prepared状态重新开始才可以。
PlaybackCompleted状态:文件正常播放完毕,而又没有设置循环播放的话就进入该状态,并会触发OnCompletionListener的onCompletion()方法。此时可以调用start()方法重新从头播放文件,也可以stop()停止MediaPlayer,或者也可以seekTo()来重新定位播放位置。
Error状态:在一般情况下,由于种种原因一些播放控制操作可能会失败,如不支持的音频/视频格式,缺少隔行扫描的音频/视频,分辨率太高,流超时等原因,等等会触发会触发OnErrorListener.onError()事件,此时MediaPlayer会进入Error状态,及时捕捉并妥善处理这些错误是很重要的,可以帮助我们及时释放相关的软硬件资源,也可以改善用户体验。
开发者可以通过setOnErrorListener(android.media.MediaPlayer.OnErrorListener设置监听器来监听MediaPlayer是否进入Error状态。如果MediaPlayer进入了Error状态,可以通过调用reset()来恢复,使得MediaPlayer重新返回到Idle状态。}

我要回帖

更多关于 playerunknown 进游戏 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信