surfaceView+MediaPlayer的问题
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/】
- private Runnable runner = new Runnable()
- {
- @Override
- public void run()
- {
- handler.sendEmptyMessageDelayed(0, 2000);
- }
- };
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 的方法是:
Valid and invalid states
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的目的。
- 5个经典的JavaScript面试题
- 轻松初探 Python 篇(四)—list tuple range 知识汇总
- CSS深入理解学习笔记之overflow
- Python爬虫实践——简单爬取我的博客
- Python爬虫入门(二)
- 在ASP.NET MVC5应用程序中快速接入QQ和新浪微博OAuth起步创建应用程序使用NUGET更新OWIN中间件启动SSL支持申请腾讯QQ的Oauth申请新浪微博的Oauth快速接入资源地址&源码
- 有趣的算法(六) ——Find-Union算法
- 有趣的算法(七) ——快速排序改进算法
- 编写你人生中第一个机器学习代码吧!
- 使用Octave来学习Machine Learning(二)
- RESTful API的十个最佳实践1. 使用名词而不是动词 2. Get方法和查询参数不应该改变资源状态3. 使用名词的复数形式 4. 为关系使用子资源 5. 使用HTTP头决定序列化格式 6. 使
- MYSQL数据库设计的一些小技巧[转载]
- 在ASP.NET 5应用程序中的跨域请求功能详解什么是“同域”添加CORS包在应用程序中配置CORSCORS策略选项跨域请求中的凭据设置先行请求的过期时间CORS是怎么样工作的先行请求
- 有趣的算法(八) ——红黑树插入算法
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 【Rust日报】 2020-08-20 Chrome 的 Rust 与 C++ 的互操作性
- 聊聊claudb的DatabaseCleaner
- nc很强大,容易让人蹲号子
- Rust FFI 编程 - Rust导出共享库05
- 详解ENet | CPU可以实时的道路分割网络
- Linux进程调度之 - O(1)调度算法
- 从零开始编写一个WEB服务器 - 基础
- Redis 6.0 IO线程功能分析
- RCU锁原理与实现
- HBase Bulkload 实践探讨
- 如何在 Linux 上恢复误删除的文件或目录?
- 有赞 Android 编译进阶之路——全量编译提效方案
- Redis 模块机制 - 模块编写篇
- 揭开「拓扑排序」的神秘面纱
- docker使用记录