MediaPlayer详解

MediaPlayer详解

1.创建

static MediaPlayer create(Context context,Uri uri);
从指定的Uri来装载音频文件并返回创建的MediaPlayer对象(本地文件和网络资源均可)

static MediaPlayer create(Context context,int resid);
从resid资源Id对应的资源文件中装载音频文件,并返回新创建的MediaPlayer对象。(资源文件一般放在res/raw文件中,R.raw.xx)

上述对于只播放一次的音频文件是有效的,但由于是静态方法,所以不建议对多个音频文件多次使用上述方法,可使用new构造一个对象再进行下面步骤的配置。

2.加载音频文件

setDataSource(String Path);
指定装载path路径所代表的文件

setDataSource(FileDescriptor fd,long offset,long length);
指定装载fd所代表的文件中从offset开始,长度为lenth的文件内容

setDataSource(FileDescriptor fd);
指定装载fd所代表的文件

setDataSource(Context context,Uri uri);
指定装载uri所代表的文件

以上只是装载了播放内容,并未真正开始播放,还需调用prepare();方法准备。

3.播放音频文件

player.reset(); //重设装载配置
player.setDataSource(…); //指定装载内容
player.prepare(); //装载内容
player.start(); //播放

4.监听事件

setOnCompleteListener(MediaPlayer.OnCompeleteListener listener);
interface MediaPlayer.OnCompeleteListener{
void onCompletion(MediaPlayer mp);
}

为MediaPlayer的播放完成时间绑定事件监听器。

setOnErrorListener(MediaPlayer.OnErrorListner listener);
interface MediaPlayer.OnErrorListner {
void onError(MediaPlayer mp,int what,int extra);
}

为MeidaPlayer的播放错误事件提供事件监听器。
what是错误类型
MEDIA_ERROR_UNKNOWN 未指明的错误类型
MEDIA_ERROR_SERVER_DIED 媒体服务关闭

extra是特别的错误代码
MEDIA_ERROR_IO 文件或者网络出现操作错误
MEDIA_ERROR_MALFORMED 比特流不符合编码标准或者文件规格
MEDIA_ERROR_UNSUPPORTED 比特流符合编码标准或者文件规格,但是媒体框架不支持
MEDIA_ERROR_TIMED_OUT 一些操作超时,一般超过3-5秒

setOnPreparedListener(MediaPlayer.OnPreparedListener listener);
interface MediaPlayer.OnPreparedListener {
void OnPrepared(MediaPlayer mp);
}

为MediaPlayer调用prepare()方法时触法该监听器。

setOnSeekCompleteListener(MediaPlayer.OnSeekCompleteListener listener);
interface MediaPlayer.onSeekComplete {
void onSeekComplete (MediaPlayer mp);
}

当MediaPlayer调用seek()方法时触法该监听器。

setOnBufferingUpdateListener(OnBufferingUpdateListener listener);
interface MediaPlayer.onBufferingUpdate  {
void onSeekComplete (MediaPlayer mp, int percent);
}

当从网络加载流媒体时流媒体缓冲的监听器
percent 从(0-100)表示缓冲的百分比

setOnInfolistener(OnInfoListener listener);
interface MediaPlayer.OnInfoListener{
public abstract boolean onInfo (MediaPlayer mp, int what, int extra)
}

监听mediaplayer对象在各个过程中一些信息或者警告的回调
what 信息类型或者警告类型
MEDIA_INFO_UNKNOWN 未知的信息
MEDIA_INFO_VIDEO_TRACK_LAGGING 视频编码过于复杂,解码器无法足够快的解码出帧
MEDIA_INFO_VIDEO_RENDERING_START 用户只推第一帧视频渲染
MEDIA_INFO_BUFFERING_START MediaPlayer临时暂停播放去加载更多缓冲
MEDIA_INFO_BUFFERING_END MediaPlayer加载满缓冲 开始播放
MEDIA_INFO_BAD_INTERLEAVING 音视频错乱传输,视频跟音频不同步
MEDIA_INFO_NOT_SEEKABLE 不可移动帧,对于直播流
MEDIA_INFO_METADATA_UPDATE 一系列新的metedata可被使用
MEDIA_INFO_UNSUPPORTED_SUBTITLE 字幕轨道不被媒体服务支持
MEDIA_INFO_SUBTITLE_TIMED_OUT 渲染字幕时间过长

extra 一些特别的信息特征代码

5.状态

IDLE 状态
When a MediaPlayer object is just created using new or after reset() is called, it is in the Idle state;

END 状态
and after release() is called, it is in the End state.

  • There is a subtle but important difference between a newly constructed MediaPlayer object and the MediaPlayer object after reset() is called. It is a programming error to invoke methods such as getCurrentPosition(), getDuration(), getVideoHeight(), getVideoWidth(), setAudioStreamType(int), setLooping(boolean), setVolume(float, float), pause(), start(), stop(), seekTo(int), prepare() or prepareAsync() in the Idle state for both cases. If any of these methods is called right after a MediaPlayer object is constructed, the user supplied callback method OnErrorListener.onError() won’t be called by the internal player engine and the object state remains unchanged; but if these methods are called right after reset(), the user supplied callback method OnErrorListener.onError() will be invoked by the internal player engine and the object will be transfered to the Error state.
    新构造的mediaplayer和调用了reset()方法的mediaplayer虽然都是在IDEL状态但是它们是有所区别的,在IDEL状态下直接调用(没有指定资源内容)getCurrentPosition(),getDuration(),getVideoHeight(),getVideoWidth(),setAudioStreamType(int), setLooping(boolean),setVolume(float, float), pause(), start(), stop(), seekTo(int),prepare() or prepareAsync()等方法都会引发错误,对于新构造的mediaplayer是不会在OnErrorListener中回调的,只有在调用了reset()方法的mediaPlayer才会在OnErrorListener中回调,并且状态由IDEL状态转为ERROR状态。

  • It is also recommended that once a MediaPlayer object is no longer being used, call release() immediately so that resources used by the internal player engine associated with the MediaPlayer object can be released immediately. Once the MediaPlayer object is in the End state, it can no longer be used and there is no way to bring it back to any other state.
    建议在mediaplayer不再使用的情况下及时调用release()方法进入END状态,一旦进入END状态将会是不可逆的。

  • Furthermore, the MediaPlayer objects created using new is in the Idle state, while those created with one of the overloaded convenient create methods are NOT in the Idle state. In fact, the objects are in the Prepared state if the creation using create method is successful.
    当使用构造函数new出来的mediaplayer对象是在IDEL状态,但是使用create方法获得的mediaplayer对象是处于PREPARED状态的

ERROR 状态
In general, some playback control operation may fail due to various reasons, such as unsupported audio/video format, poorly interleaved audio/video, resolution too high, streaming timeout, and the like. Thus, error reporting and recovery is an important concern under these circumstances. Sometimes, due to programming errors, invoking a playback control operation in an invalid state may also occur. Under all these error conditions, the internal player engine invokes a user supplied OnErrorListener.onError() method if an OnErrorListener has been registered beforehand via setOnErrorListener(android.media.MediaPlayer.OnErrorListener).

  • It is important to note that once an error occurs, the MediaPlayer
    object enters the Error state (except as noted above), even if an
    error listener has not been registered by the application.
    无论是否注册了错误监听器,只要出现错误,mediaplayer对象都会进入ERROR状态

  • In order to reuse a MediaPlayer object that is in the Error state and
    recover from the error, reset() can be called to restore the object
    to its Idle state.
    为了从ERROR状态中恢复到IDEL状态,可以调用reset()方法

  • IllegalStateException is thrown to prevent programming errors such as calling prepare(), prepareAsync(), or one of the overloaded setDataSource methods in an invalid state.
    当无效状态下,调用 prepare(),prepareAsync()或者指定装载内容都会抛出IllegalStateException

INITIALIZED 状态
Calling setDataSource(FileDescriptor), or setDataSource(String), or setDataSource(Context, Uri), or setDataSource(FileDescriptor, long, long) transfers a MediaPlayer object in the Idle state to the Initialized state.

  • An IllegalStateException is thrown if setDataSource() is called in any other state.
    除了IDEL状态,在其他状态下调用setDataSource()方法都会抛出IllegalStateException

  • It is good programming practice to always look out for IllegalArgumentException and IOException that may be thrown from the overloaded setDataSource methods.
    对调用setDataSource()的方法进行IllegalArgumentException和IOException的异常捕获是一个好的编程习惯

PREPARED 状态
A MediaPlayer object must first enter the Prepared state before playback can be started.

  • There are two ways (synchronous vs. asynchronous) that the Prepared state can be reached: either a call to prepare() (synchronous) which transfers the object to the Prepared state once the method call returns, or a call to prepareAsync() (asynchronous) which first transfers the object to the Preparing state after the call returns (which occurs almost right way) while the internal player engine continues working on the rest of preparation work until the preparation work completes. When the preparation completes or when prepare() call returns, the internal player engine then calls a user supplied callback method, onPrepared() of the OnPreparedListener interface, if an OnPreparedListener is registered beforehand via setOnPreparedListener(android.media.MediaPlayer.OnPreparedListener).
    这里有两种状态进入PREPARED状态,当调用的 prepare()方法(同步的)返回后,状态就会转变为PREPARED状态,当调用prepareAsync()(异步的)时,在mediaplayer内部会处理准备的装载资源直到所有准备工作完成,状态就会转变为PREPARED状态。无论是prepare()或者是prepareAsync(),当状态转为PREPARED状态时都为回调在setOnPreparedListener(android.media.MediaPlayer.OnPreparedListener).监听器中。

  • It is important to note that the Preparing state is a transient state, and the behavior of calling any method with side effect while a MediaPlayer object is in the Preparing state is undefined.

  • While in the Prepared state, properties such as audio/sound volume, screenOnWhilePlaying, looping can be adjusted by invoking the corresponding set methods.
    在PREPARED状态下,可以调用音量、屏幕属性、循环等相应的方法。

STARTED 状态
To start the playback, start() must be called. After start() returns successfully, the MediaPlayer object is in the Started state. isPlaying() can be called to test whether the MediaPlayer object is in the Started state.

  • While in the Started state, the internal player engine calls a user supplied OnBufferingUpdateListener.onBufferingUpdate() callback method if a OnBufferingUpdateListener has been registered beforehand via setOnBufferingUpdateListener(OnBufferingUpdateListener). This callback allows applications to keep track of the buffering status while streaming audio/video.
    在STARTED状态下,mediaplyaer对象内部会将音/视频流的缓冲状态回调到用户注册的setOnBufferingUpdateListener(OnBufferingUpdateListener).监听器中

  • Calling start() has not effect on a MediaPlayer object that is already in the Started state.
    在STARTED状态下调用start()是无效的

PAUSED 状态
Playback can be paused and stopped, and the current playback position can be adjusted. Playback can be paused via pause(). When the call to pause() returns, the MediaPlayer object enters the Paused state. Note that the transition from the Started state to the Paused state and vice versa happens asynchronously in the player engine. It may take some time before the state is updated in calls to isPlaying(), and it can be a number of seconds in the case of streamed content.

  • Calling start() to resume playback for a paused MediaPlayer object, and the resumed playback position is the same as where it was paused. When the call to start() returns, the paused MediaPlayer object goes back to the Started state.
    方法,会重新在停止的点上继续播放,并且当调用返回后,PAUSED状态将会转为STARTED状态

  • Calling pause() has no effect on a MediaPlayer object that is already in the Paused state.
    在PAUSED状态下调用pause() 是无效的

STOPPED 状态
Calling stop() stops playback and causes a MediaPlayer in the Started, Paused, Prepared or PlaybackCompleted state to enter the Stopped state.

  • Once in the Stopped state, playback cannot be started until prepare() or prepareAsync() are called to set the MediaPlayer object to the Prepared state again.
    一旦进入STOPPED状态,mediaplayer对象即不能调用start()方法,必须重新调用 prepare() 或者prepareAsync() 进入PREPARED状态。

  • Calling stop() has no effect on a MediaPlayer object that is already in the Stopped state.
    在STOPPED状态下调用 stop() 是无效的

SEEKTO 方法
The playback position can be adjusted with a call to seekTo(int).

  • Although the asynchronuous seekTo(int) call returns right way, the actual seek operation may take a while to finish, especially for audio/video being streamed. When the actual seek operation completes, the internal player engine calls a user supplied OnSeekComplete.onSeekComplete() if an OnSeekCompleteListener has been registered beforehand via setOnSeekCompleteListener(OnSeekCompleteListener).
    尽管异步方法 seekTo(int)调用返回很及时,但实际移动时间点操作还是要花费一些时间去完成,特别在音视频正在流播放。当移动成功后,mediaplayer对象内部会回调成功在setOnSeekCompleteListener(OnSeekCompleteListener).监听器中

  • Please note that seekTo(int) can also be called in the other states, such as Prepared, Paused and PlaybackCompleted state.
    不仅可以在STARTED状态中,同时可以在PREPARED 、PAUSED、PLAYBACKCOMPLETED状态中。

PLAYBACKCOMPLETED 状态
When the playback reaches the end of stream, the playback completes.

  • If the looping mode was being set to truewith setLooping(boolean), the MediaPlayer object shall remain in the Started state.
    如果循环模式被设置,mediaplayer对象将会依旧在STATED状态

  • If the looping mode was set to false , the player engine calls a user supplied callback method, OnCompletion.onCompletion(), if a OnCompletionListener is registered beforehand via setOnCompletionListener(OnCompletionListener). The invoke of the callback signals that the object is now in the PlaybackCompleted state.
    如果没有设置循环装态,播放结束后将会回调播放结束标识在用户注册的setOnCompletionListener(OnCompletionListener).监听器中

  • While in the PlaybackCompleted state, calling start() can restart the playback from the beginning of the audio/video source.
    在PLAYBACKCOMPLETED 状态中,可以调用 start() 方法重新播放音/视频

6.视频加载

结合sufaceView,将mediaplayer的视频帧传输到surfaceview进行渲染,调用mediaplayer的setDisplayer(SurfaceHolder holder)方法,即可。

你可能感兴趣的:(Android)