找了好久,网上有各种各样的代码,但都不是解决办法。目前我找到的解决办法有2个,也可以合在一起用。
what=100可以理解为播放器死掉了,有很多种原因导致播放器死掉了,我这个是解码失败,原因是同事编系统时少加了一个MPEG-4,所以导致播放视频时播放器无法解码从而死掉了。
错误码集合:
/** Unspecified media player error.
* @see android.media.MediaPlayer.OnErrorListener
*/
public static final int MEDIA_ERROR_UNKNOWN = 1;
/** Media server died. In this case, the application must release the
* MediaPlayer object and instantiate a new one.
* @see android.media.MediaPlayer.OnErrorListener
*/
public static final int MEDIA_ERROR_SERVER_DIED = 100;
/** File or network related operation errors. */
public static final int MEDIA_ERROR_IO = -1004;
/** Bitstream is not conforming to the related coding standard or file spec. */
public static final int MEDIA_ERROR_MALFORMED = -1007;
/** Bitstream is conforming to the related coding standard or file spec, but
* the media framework does not support the feature. */
public static final int MEDIA_ERROR_UNSUPPORTED = -1010;
/** Some operation takes too long to complete, usually more than 3-5 seconds. */
public static final int MEDIA_ERROR_TIMED_OUT = -110;
/** Unspecified low-level system error. This value originated from UNKNOWN_ERROR in
* system/core/include/utils/Errors.h
* @see android.media.MediaPlayer.OnErrorListener
* @hide
*/
public static final int MEDIA_ERROR_SYSTEM = -2147483648;
/**
* Interface definition of a callback to be invoked when there
* has been an error during an asynchronous operation (other errors
* will throw exceptions at method call time).
*/
public interface OnErrorListener
{
/**
* Called to indicate an error.
*
* @param mp the MediaPlayer the error pertains to
* @param what the type of error that has occurred:
* <ul>
* <li>{@link #MEDIA_ERROR_UNKNOWN}
* <li>{@link #MEDIA_ERROR_SERVER_DIED}
* </ul>
* @param extra an extra code, specific to the error. Typically
* implementation dependent.
* <ul>
* <li>{@link #MEDIA_ERROR_IO}
* <li>{@link #MEDIA_ERROR_MALFORMED}
* <li>{@link #MEDIA_ERROR_UNSUPPORTED}
* <li>{@link #MEDIA_ERROR_TIMED_OUT}
* <li><code>MEDIA_ERROR_SYSTEM (-2147483648)</code> - low-level system error.
* </ul>
* @return True if the method handled the error, false if it didn't.
* Returning false, or not having an OnErrorListener at all, will
* cause the OnCompletionListener to be called.
*/
boolean onError(MediaPlayer mp, int what, int extra);
}
/** Unspecified media player info.
* @see android.media.MediaPlayer.OnInfoListener
*/
public static final int MEDIA_INFO_UNKNOWN = 1;
/** The player was started because it was used as the next player for another
* player, which just completed playback.
* @see android.media.MediaPlayer#setNextMediaPlayer(MediaPlayer)
* @see android.media.MediaPlayer.OnInfoListener
*/
public static final int MEDIA_INFO_STARTED_AS_NEXT = 2;
/** The player just pushed the very first video frame for rendering.
* @see android.media.MediaPlayer.OnInfoListener
*/
public static final int MEDIA_INFO_VIDEO_RENDERING_START = 3;
/** The video is too complex for the decoder: it can't decode frames fast
* enough. Possibly only the audio plays fine at this stage.
* @see android.media.MediaPlayer.OnInfoListener
*/
public static final int MEDIA_INFO_VIDEO_TRACK_LAGGING = 700;
/** MediaPlayer is temporarily pausing playback internally in order to
* buffer more data.
* @see android.media.MediaPlayer.OnInfoListener
*/
public static final int MEDIA_INFO_BUFFERING_START = 701;
/** MediaPlayer is resuming playback after filling buffers.
* @see android.media.MediaPlayer.OnInfoListener
*/
public static final int MEDIA_INFO_BUFFERING_END = 702;
/** Estimated network bandwidth information (kbps) is available; currently this event fires
* simultaneously as {@link #MEDIA_INFO_BUFFERING_START} and {@link #MEDIA_INFO_BUFFERING_END}
* when playing network files.
* @see android.media.MediaPlayer.OnInfoListener
* @hide
*/
public static final int MEDIA_INFO_NETWORK_BANDWIDTH = 703;
/** Bad interleaving means that a media has been improperly interleaved or
* not interleaved at all, e.g has all the video samples first then all the
* audio ones. Video is playing but a lot of disk seeks may be happening.
* @see android.media.MediaPlayer.OnInfoListener
*/
public static final int MEDIA_INFO_BAD_INTERLEAVING = 800;
/** The media cannot be seeked (e.g live stream)
* @see android.media.MediaPlayer.OnInfoListener
*/
public static final int MEDIA_INFO_NOT_SEEKABLE = 801;
/** A new set of metadata is available.
* @see android.media.MediaPlayer.OnInfoListener
*/
public static final int MEDIA_INFO_METADATA_UPDATE = 802;
/** A new set of external-only metadata is available. Used by
* JAVA framework to avoid triggering track scanning.
* @hide
*/
public static final int MEDIA_INFO_EXTERNAL_METADATA_UPDATE = 803;
/** Informs that audio is not playing. Note that playback of the video
* is not interrupted.
* @see android.media.MediaPlayer.OnInfoListener
*/
public static final int MEDIA_INFO_AUDIO_NOT_PLAYING = 804;
/** Informs that video is not playing. Note that playback of the audio
* is not interrupted.
* @see android.media.MediaPlayer.OnInfoListener
*/
public static final int MEDIA_INFO_VIDEO_NOT_PLAYING = 805;
/** Failed to handle timed text track properly.
* @see android.media.MediaPlayer.OnInfoListener
*
* {@hide}
*/
public static final int MEDIA_INFO_TIMED_TEXT_ERROR = 900;
/** Subtitle track was not supported by the media framework.
* @see android.media.MediaPlayer.OnInfoListener
*/
public static final int MEDIA_INFO_UNSUPPORTED_SUBTITLE = 901;
/** Reading the subtitle track takes too long.
* @see android.media.MediaPlayer.OnInfoListener
*/
public static final int MEDIA_INFO_SUBTITLE_TIMED_OUT = 902;
/**
* Interface definition of a callback to be invoked to communicate some
* info and/or warning about the media or its playback.
*/
public interface OnInfoListener
{
/**
* Called to indicate an info or a warning.
*
* @param mp the MediaPlayer the info pertains to.
* @param what the type of info or warning.
* <ul>
* <li>{@link #MEDIA_INFO_UNKNOWN}
* <li>{@link #MEDIA_INFO_VIDEO_TRACK_LAGGING}
* <li>{@link #MEDIA_INFO_VIDEO_RENDERING_START}
* <li>{@link #MEDIA_INFO_BUFFERING_START}
* <li>{@link #MEDIA_INFO_BUFFERING_END}
* <li><code>MEDIA_INFO_NETWORK_BANDWIDTH (703)</code> -
* bandwidth information is available (as <code>extra</code> kbps)
* <li>{@link #MEDIA_INFO_BAD_INTERLEAVING}
* <li>{@link #MEDIA_INFO_NOT_SEEKABLE}
* <li>{@link #MEDIA_INFO_METADATA_UPDATE}
* <li>{@link #MEDIA_INFO_UNSUPPORTED_SUBTITLE}
* <li>{@link #MEDIA_INFO_SUBTITLE_TIMED_OUT}
* </ul>
* @param extra an extra code, specific to the info. Typically
* implementation dependent.
* @return True if the method handled the info, false if it didn't.
* Returning false, or not having an OnInfoListener at all, will
* cause the info to be discarded.
*/
boolean onInfo(MediaPlayer mp, int what, int extra);
}
我这边看见我的what为100,然后做了这样一个处理:
private void videoPlay() {
// 你的应用已经获得了音频焦点,其他应用会停止播放音频
videoView.setVisibility(View.VISIBLE);
videoView.setVideoURI(Uri.parse(ConstantUtil.videoUri));
videoView.setOnErrorListener(new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
videoView.stopPlayback(); //播放异常,则停止播放,防止弹窗使界面阻塞
if(what == 100) {
videoPlay();
}
return true;//直接return为true可以取消弹窗
}
});
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mp.setLooping(true);//设置循环播放
mp.start();
}
});
}
设置错误监听,当what等于100时重新试着去播放, 在没有此解码器的情况下,他能够正常运行一段时间,然后播放器报错崩溃,会接着走到这部分继续运行,可防止播放器报错时弹窗和视频卡主不动的情况,优化了用户体验。
后面同事加上解码器之后已经没问题了,播放视频当解码器不一致或缺少时,会需要打这样的补丁