1.黑屏原因:可能是由于surfaceView还没有创建完成就播放,肯定不行,所以必须在surfaceViewCreated里面才能播放
2.黑屏的第二个原因:activity被用户强制性关闭,或者是界面,下次进来如果是 保存原来的状态,那么可能会黑屏,播放的起点也必须放在surfaceViewCreate里面,只能从这里恢复播放,同时activity强制性退出的时候,需要在surfaceDestroyed把position记录下来,同时如果mediaPlayer是正在播放,需要暂停
public void surfaceDestroyed(SurfaceHolder holder) { if(mediaPlayer.isPlaying()){ position = mediaPlayer.getCurrentPosition(); mediaPlayer.stop(); }
3.播放完毕之后,改变surfaceView的背景图片是 sv.setBackgroundResource(R.drawable.bg_finish); //改变SurfaceView的背景图片
4.卡顿问题之一,卡顿是超级严重的问题:如果是prepare那里报错的话,那么请把mp.start();方法放在监听事件里面,也就是onPrepare方法里面,这个位置就是你还没有准备好,怎么能够播放呢?在没有准备好之前,可以设置他在不停的加载把
5.播放失败,或者直接闪屏的原因之一:就是从一个视频activity或者view到另外一个视频view的播放,如果时间比较紧凑,可能会立即失败,或者闪退,这里面的原因就是 mediaPlayer还没有来得及释放,也有可能是surfaceView还没有完成销毁,总之存在两个对象,肯定就失败了,有人说这个原始Android设备的问题,如果这个设备使用的操作系统把第三方厂商给修改了,可能会出现这个元,如果是原生态的可能就不会,解决方法就是 第二个视频延迟播放,或者跳转的时候稍微延迟,或者在播放视频的时候弹出正在加载,让那个进度条延迟一秒的旋转时间,再播放,应该可以解决这个问题【http://doublekj.blog.163.com/blog/static/146818474201272453250354/】
6.要注意多次reset的时候,会消耗一部分时间,也即是mediaPlayer播放时间,
7.mediaPlayer如果多次销毁,又多次创建,可能也会每次都去分配一定的空间,代价也是蛮大的,但是安全,不会出现为null的情况
8.这个时候如果是播放同一个视频,这里也会造成卡顿的原因
9.关于声音问题,要在设置数据源之后执行比较好:
把 mPlayer.setAudioStreamType(AudioManager.STREAM_SYSTEM); 换成 mPlayer.setAudioStreamType(AudioManager.STREAM_ALARM); 或者 mediaPlayer.setAudioStreamType(AudioManager.STREAM_VOICE_CALL);//听筒模式
mediaPlayer 的方法是:
Method Name | Valid Sates | Invalid States | Comments |
---|---|---|---|
attachAuxEffect | {Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted} | {Idle, Error} | This method must be called after setDataSource. Calling it does not change the object state. |
getAudioSessionId | any | {} | This method can be called in any state and calling it does not change the object state. |
getCurrentPosition | {Idle, Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted} | {Error} | Successful invoke of this method in a valid state does not change the state. Calling this method in an invalid state transfers the object to the Error state. |
getDuration | {Prepared, Started, Paused, Stopped, PlaybackCompleted} | {Idle, Initialized, Error} | Successful invoke of this method in a valid state does not change the state. Calling this method in an invalid state transfers the object to the Error state. |
getVideoHeight | {Idle, Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted} | {Error} | Successful invoke of this method in a valid state does not change the state. Calling this method in an invalid state transfers the object to the Error state. |
getVideoWidth | {Idle, Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted} | {Error} | Successful invoke of this method in a valid state does not change the state. Calling this method in an invalid state transfers the object to the Error state. |
isPlaying | {Idle, Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted} | {Error} | Successful invoke of this method in a valid state does not change the state. Calling this method in an invalid state transfers the object to the Error state. |
pause | {Started, Paused} | {Idle, Initialized, Prepared, Stopped, PlaybackCompleted, Error} | Successful invoke of this method in a valid state transfers the object to the Paused state. Calling this method in an invalid state transfers the object to the Error state. |
prepare | {Initialized, Stopped} | {Idle, Prepared, Started, Paused, PlaybackCompleted, Error} | Successful invoke of this method in a valid state transfers the object to the Prepared state. Calling this method in an invalid state throws an IllegalStateException. |
prepareAsync | {Initialized, Stopped} | {Idle, Prepared, Started, Paused, PlaybackCompleted, Error} | Successful invoke of this method in a valid state transfers the object to the Preparing state. Calling this method in an invalid state throws an IllegalStateException. |
release | any | {} | After release(), the object is no longer available. |
reset | {Idle, Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted, Error} | {} | After reset(), the object is like being just created. |
seekTo | {Prepared, Started, Paused, PlaybackCompleted} | {Idle, Initialized, Stopped, Error} | Successful invoke of this method in a valid state does not change the state. Calling this method in an invalid state transfers the object to the Error state. |
setAudioSessionId | {Idle} | {Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted, Error} | This method must be called in idle state as the audio session ID must be known before calling setDataSource. Calling it does not change the object state. |
setAudioStreamType | {Idle, Initialized, Stopped, Prepared, Started, Paused, PlaybackCompleted} | {Error} | Successful invoke of this method does not change the state. In order for the target audio stream type to become effective, this method must be called before prepare() or prepareAsync(). |
setAuxEffectSendLevel | any | {} | Calling this method does not change the object state. |
setDataSource | {Idle} | {Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted, Error} | Successful invoke of this method in a valid state transfers the object to the Initialized state. Calling this method in an invalid state throws an IllegalStateException. |
setDisplay | any | {} | This method can be called in any state and calling it does not change the object state. |
setSurface | any | {} | This method can be called in any state and calling it does not change the object state. |
setVideoScalingMode | {Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted} | {Idle, Error} | Successful invoke of this method does not change the state. |
setLooping | {Idle, Initialized, Stopped, Prepared, Started, Paused, PlaybackCompleted} | {Error} | Successful invoke of this method in a valid state does not change the state. Calling this method in an invalid state transfers the object to the Error state. |
isLooping | any | {} | This method can be called in any state and calling it does not change the object state. |
setOnBufferingUpdateListener | any | {} | This method can be called in any state and calling it does not change the object state. |
setOnCompletionListener | any | {} | This method can be called in any state and calling it does not change the object state. |
setOnErrorListener | any | {} | This method can be called in any state and calling it does not change the object state. |
setOnPreparedListener | any | {} | This method can be called in any state and calling it does not change the object state. |
setOnSeekCompleteListener | any | {} | This method can be called in any state and calling it does not change the object state. |
setScreenOnWhilePlaying | any | {} | This method can be called in any state and calling it does not change the object state. |
setVolume | {Idle, Initialized, Stopped, Prepared, Started, Paused, PlaybackCompleted} | {Error} | Successful invoke of this method does not change the state. |
setWakeMode | any | {} | This method can be called in any state and calling it does not change the object state. |
start | {Prepared, Started, Paused, PlaybackCompleted} | {Idle, Initialized, Stopped, Error} | Successful invoke of this method in a valid state transfers the object to the Started state. Calling this method in an invalid state transfers the object to the Error state. |
stop | {Prepared, Started, Stopped, Paused, PlaybackCompleted} | {Idle, Initialized, Error} | Successful invoke of this method in a valid state transfers the object to the Stopped state. Calling this method in an invalid state transfers the object to the Error state. |
getTrackInfo | {Prepared, Started, Stopped, Paused, PlaybackCompleted} | {Idle, Initialized, Error} | Successful invoke of this method does not change the state. |
addTimedTextSource | {Prepared, Started, Stopped, Paused, PlaybackCompleted} | {Idle, Initialized, Error} | Successful invoke of this method does not change the state. |
selectTrack | {Prepared, Started, Stopped, Paused, PlaybackCompleted} | {Idle, Initialized, Error} | Successful invoke of this method does not change the state. |
deselectTrack | {Prepared, Started, Stopped, Paused, PlaybackCompleted} | {Idle, Initialized, Error} | Successful invoke of this method does not change the state. |
surfaceView的相关概念:
MediaPlayer主要用于播放音频,它是没有提供输出图像的输出界面,这时我们就用到了SurfaceView控件,将它与MediaPlayer结合起来,就能达到了视频的输出了。首先来了SurfaceView这个控件类
SurfaceView类
构造方法
方法名称 | 描述 |
---|---|
public SurfaceView(Context context) | 通过Context创建SurfaceView对象 |
public SurfaceView(Context context, AttributeSet attrs) | 通过Context对象和AttributeSet创建SurfaceView对象 |
public SurfaceView(Context context, AttributeSet attrs, int defStyle) | 通过Context对象和AttributeSet创建并可以指定样式,SurfaceView对象 |
常用方法
方法名称 | 描述 |
---|---|
public SurfaceHolder getHolder () | 得到SurfaceHolder对象用于管理SurfaceView |
public void setVisibility (int visibility) | 设置是否可见,其值可以是VISIBLE, INVISIBLE, GONE. |
SurfaceHolder
它是一个接口,用于管理SurfaceView。里面有两个常用的内部接口SurfaceHolder.Callback,SurfaceHolder.Callback2而Callback2是实现于Callback的
常用方法
方法名称 | 描述 |
---|---|
public abstract void addCallback (SurfaceHolder.Callback callback) | 添加一个Callback对象监听SurfaceView的变化 |
public abstract void removeCallback (SurfaceHolder.Callback callback) | 移除Callback |
public abstract void setType (int type) | 设置SurfaceView的控制方式 |
public abstract Canvas lockCanvas () | 锁定整个SurfaceView对象,获取该Surface上的Canvas |
public abstract Canvas lockCanvas (Rect dirty) | 锁定SurfaceView上Rect划分的区域,获取该Surface上的Canvas |
public abstract void unlockCanvasAndPost (Canvas canvas) | 调用该方法,之前所绘制的图形还处于缓冲之中,下一次的lockCanvas()方法锁定的区域可能会“遮挡”它 |
SurfaceHolder.CallBack
在Callback里有三个抽象方法
方法名称 | 描述 |
---|---|
public abstract void surfaceChanged (SurfaceHolder holder, int format, int width, int height) | SurfaceView改变时触发 |
public abstract void surfaceCreated (SurfaceHolder holder) | SurfaceView创建时触发 |
public abstract void surfaceDestroyed (SurfaceHolder holder) | SurfaceView销毁时触发 |
如何理解这几个类或者接口之间的关系?
这样理解:
SurfaceView它用于显示,SurfaceHolder就是用于用来管理这个显示的SurfaceView对象的,但在SurfaceHolder是怎么样去管理这个对象的呢?这就用到了SurfceHolder.addCallback()方法添加一个SurfaceHolder接口的内部接口的三个抽象方法用于管理或者说是用于监听SurfaceView。这样就达到了管理SurfaceView的目的。