最近使用MediaPlayer + TextureView 实现了一个视频播放器,并且实现了它的横竖屏切换的效果,唯一美中不足的是在横竖屏切换的时候画面会卡顿一下,虽然也不影响播放,但是怕测试会报Bug,到时候还得自己解决,所以就先把这个问题处理下,并记录之:

TextureView的监听方法有以下四个:

  @Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i1) { } @Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i1) { } @Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
return true;
} @Override
public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) { }

我们一般是在 onSurfaceTextureAvailable() 方法里面取得 SurfaceTexture 并包装成一个 Surface 再调用MediaPlayer的 setSurface 方法完成播放器的显示工作,然而在横竖屏切换的时候,由于当前TextureView所在的ViewGroup会把该TextureView remove掉,这里便触发了TextureView的 onSurfaceTextureDestroyed 方法,然后在横屏窗口中,由于需要重新添加TextureView以便于显示,所以这里又调用了 onSurfaceTextureAvailable 方法,我最开始的做法是这样的:

mSurface = new Surface(surfaceTexture);

然后传递给MediaPlayer, 由于在横竖屏切换时给MediaPlayer传递了两个不同的Surface,因此导致了这个问题,那么解决问题的方法也很简单,只要保存SurfaceTexture, 保证横竖屏切换时使用同一个Surface即可:

@Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) {
if (mSurfaceTexture == null) {
mSurfaceTexture = surfaceTexture;
openMediaPlayer();
} else {
mTextureView.setSurfaceTexture(mSurfaceTexture);
}
}

这里将SurfaceTexture保存为一个成员变量,在使用前对其进行判断,保证使用的是同一个SurfaceTexture,也可以在

@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
Log.d(TAG, "onSurfaceTextureDestroyed: ");
mSurfaceTexture = surface;
return false;
}

也可以在 onSurfaceTextureDestroyed 方法中保存,不过不管在哪个方法中保存这个SurfaceTexture, 都需要注意 onSurfaceTextureDestroyed 方法的返回值必须为false, 官方API的解释说明如下:

Invoked when the specified SurfaceTexture is about to be destroyed. If returns true, no rendering should happen inside the surface texture after this method is invoked. If returns false, the client needs to call release(). Most applications should return true.

大致的意思是如果返回ture,SurfaceTexture会自动销毁,如果返回false,SurfaceTexture不会销毁,需要用户手动调用release()进行销毁。
所以我们在销毁的时候返回false,并保存SurfaceTexture对象,然后在切换成全屏的时候在onSurfaceTextureAvailable()方法中,调用setSurfaceTexture(mSurfaceTexture)方法,这样就恢复之前的画面了。
另外,TextureView的生命周期为:
  • 切换至后台的时候会调用onSurfaceTextureDestroyed,从后台切换回来会调用onSurfaceTextureAvailable。
  • TextureView的ViewGroup remove TextureView的时候会调用onSurfaceTextureDestroyed方法。相同,TextureView的ViewGroup add TextureView的时候会调用onSurfaceTextureAvailable。这些都是建立在视图可见的基础上,如果视图不可见,add也不会调用onSurfaceTextureAvailable方法,remove也不会调用onSurfaceTextureDestroyed方法。
  • 当TextureView设置为Gone的时候,并不会调用onSurfaceTextureDestroyed方法法。

参考链接:

 
 

MediaPlayer: 在不同控件之间实现视频的无缝切换的方法的更多相关文章

  1. .NET同页面内用户控件与父页面以及控件之间方法调用

    用户控件调用父页面的方法: //获得父页面 Page p =this.Parent.Page; Type pageType = p.GetType(); //父页面的方法名 MethodInfo mi ...

  2. 修复duilib CEditUI控件和CWebBrowserUI控件中按Tab键无法切换焦点的bug

    转载请说明原出处,谢谢~~:http://blog.csdn.net/zhuhongshu/article/details/41556615 在duilib中,按tab键会让焦点在Button一类的控 ...

  3. sharepoint 2013 附件控件FileUpload怎样检验是否为图片的方法

    记录一下关于附件控件FileUpload怎样检验是否为图片的方法: function checkImg() { var fileObj =document.getElementById('<%= ...

  4. C# WinForm窗体控件Panel修改边框颜色以及边框宽度方法

    C# WinForm窗体控件Panel修改边框颜色以及边框宽度方法 1.新建组件这里可以自定义一个Panel控件起名为PanelEx 2.增加一个BoderColor属性和BoderSize属性 pr ...

  5. OLE、OCX和ActiveX控件之间的比较

      OLE(Object Linking and Embedding,对象连接与嵌入) 一.过去的OLE和今天的OLE 最初的OLE含义是指在程序之间链接和嵌入对象数据,它提供了建立混合文档的手段(资 ...

  6. 【WPF】使用控件MediaElement播放视频

    需求是点击按钮后,弹出弹窗播放视频.按钮的点击事件如下. public void ShowVideo() { Window window = new Window(); window.Width = ...

  7. android控件之间事件传递

    public boolean dispatchTouchEvent(MotionEvent ev){} 用于事件的分发.Android中全部的事件都必须经过这种方法的分发.然后决定是自身消费当前事件还 ...

  8. WPF——控件之间的绑定

    一.启动窗口 二.控件绑定(注意看光标的位置,一个是单向绑定,一个是双向绑定) 注意看单向绑定与双向绑定的绑定方法:

  9. WPF中获取控件之间的相对位置

    1,获取元素相对于父控件的位置 使用Vector VisualTreeHelper.GetOffset(Visual visual)方法,其会返回visual在其父控件中的偏移量,然后你再将返回值的V ...

随机推荐

  1. 学习使用Django2 前台页面展示

    Django  2.1  python 3.7 创建一个虚拟环境 python  -m  venv  虚拟环境名称 进入虚拟环境 下载django pip install  django==2.1 创 ...

  2. Swaks - SMTP界的瑞士军刀

    0x00 安装: kali中自带,或者从作者网页下载 http://www.jetmore.org/john/code/swaks/ 0x01 基本用法: swaks –to <要测试的邮箱&g ...

  3. shell 文本替换 ---出现--- sed:-e 表达式 #1,字符 8:“s”的未知选项

    需要替换的行为: monitor.url=http://192.168.25.100:8443/rest 查询资料得知,报错是因为替换的字符串包含有分隔符/ 所以这行改一下分隔符就可以解决问题了  ( ...

  4. 0016SpringBoot实现RESTFUL形式的增删改查

    1.列表页面如下 <!DOCTYPE html><!-- saved from url=(0052)http://getbootstrap.com/docs/4.0/examples ...

  5. eclipse等编辑器选中列快编辑的方法

    一.eclipse 1.首先按alt+shift+a,开启块选择模式 2.使用鼠标进行块选择 3.再次按Alt+Shift+a即可关闭块选择模式 二.EditPlus 1.菜单:编辑 -> 选择 ...

  6. MySQL远程连接不上的解决方法

    这篇文章主要为大家详细介绍了MySQL远程连接不上的解决方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下   之前遇到过MySQL本地可以连接但是远程连不上的问题,没有记录,今天在云上新申请的服 ...

  7. vuex 随笔

    vuex刷新数据消失问题: 在项目的入口页面(App.vue)里添加监听刷新事件: 或者使用插件:npm install vuex-persistedstate --save

  8. Connecting Graph

    Given n nodes in a graph labeled from 1 to n. There is no edges in the graph at beginning. You need ...

  9. reCaptcha 新版,国内可无障碍使用

    reCaptcha 新版,国内可无障碍使用 蓝小灰 Digital Sign® PKI 创始人/一点安全专栏主编 4 人赞同了该文章 如果你在使用一些网站看到下图,这就是由 Google 提供的 re ...

  10. 四十.创建Redis集群 管理集群

    环境准备 准备 6台(51-56) redis服务器  以默认配置运行redis服务即可  一.创建Redis集群 1.启用集群功能( 51-56 都要配置) ]#  netstat -antupl ...