上一篇我们知道了SurfaceView的基本使用方法,SurfaceView由于使用的是独立的绘图层,并且使用独立的线程去进行绘制,不能进行Transition,Rotation,Scale等变换,这就导致一个问题SurfaceView在滑动的时候,SurfaceView的刷新由于不受主线程控制导致SurfaceView在滑动的时候会出现黑边的情况。
VideoView继承自SurfaceView,也不能像View一样在列表中滑动。
这篇文章介绍了TextureView,并给了效果图
什么是TextureView
TextureView是在4.0(API level 14)引入的,与SurfaceView相比,它不会创建新的窗口来显示内容。它是将内容流直接投放到View中,并且可以和其它普通View一样进行移动,旋转,缩放,动画等变化。TextureView必须在硬件加速的窗口中使用。现在的移动设备基本都有GPU进行硬件加速渲染。
SurfaceTexture
在这篇文章中,我们已经知道了Surface是内存中一段绘图缓冲区
那么SurfaceTexture是什么呢?
SurfaceTexture用来捕获视频流中的图像帧,视频流可以是相机预览或者是视频解码数据。
TextureView可以通过getSurfaceTexture()方法来获取TextureView相应的SurfaceTexture。
因此我们使用TextureView时,首先要获取到用于渲染内容的SurfaceTexture。具体做法是先创建TextureView对象,然后实现SurfaceTextureListener接口
1 | protected void onCreate(Bundle savedInstanceState) { |
Activity implements了SurfaceTextureListener接口因此activity中需要重写如下方法:
1 | @Override |
这篇文章介绍了TextureView基本使用方法
TextureView与MediaPlayer结合
通过上面对SurfaceTexture的介绍,我们可以理解为:
SurfaceTexture是数据通道,把数据源MediaPlayer中获取到的图像帧数据转化为GL外部纹理。
TextureView是显示层,显示图像帧,从而实现视频播放功能。
由于SurfaceTexture的准备就绪、大小变化、销毁、更新等状态变化时都会回调相对应的方法。
所以我们要等到onSurfaceTextureAvailable被调用时,将SurfaceTexture关联MediaPlayer,作为播放视频的图像数据来源
注意
当遇见有声音无图像的情况时,可能是TextureView未创建,初始化,或者是SurfaceTexture未关联到MediaPlayer。有声音说明MediaPlayer数据源存在,无图像说明显示层TextureView未成功初始化或者未关联到MediaPlayer。
小例子
使用的时候注意要配置权限1
<uses-permission android:name="android.permission.INTERNET" />
使用步骤
- 在布局中添加TextureView
- 创建MediaPlayer
- 初始化TextureView,并添加setSurfaceTextureListener() 监听
- 在onSurfaceTextureAvailable后,初始化Surface,初始化medipalyer
- 通过MediaPlayer.setSurface(surface),将MediaPlayer和TextureView关联
1 | @Override |
完整代码
1 | package com.example.com.myapplication; |
布局文件
1 | <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" |
效果: