引自:http://www.ithao123.cn/content-8733143.html

最近发现视频直播类应用层出不穷,比如233手游直播,蓝鲸直播,微录客等等什么的,连android界大神老罗也在开发手游录制类的应用,这里面的技术含量也是挺高的,需要了解android 系统的UI渲染机制以及很多系统底层的知识,而我最近也在想好好研究研究android 的UI渲染机制并以此作为深入了解android的入口

好了,在讲代码实现之前,我先讲讲TextureView, SurfaceTexture,OpenGL ES都是些什么鬼东西,我又是怎么使用这几个东西来显示一个视频的。

TextureView 顾名思义也就是一个继承了View的一个View控件而已,官网的解释是这样的: 
A TextureView can be used to display a content stream. Such a content stream can for instance be a video or an OpenGL scene. The content stream can come from the application’s process as well as a remote process. 
它能够去显示一个内容流,比如视频流,OpenGL渲染的场景等。这些流可以是本地程序进程也可以是远程进程流,有点绕,我的理解就是,比如既可以是本地视频流,也可以是网络视频流。 
注意的是: TextureView 采用的是硬件加速器去渲染,就类似视频的硬解码跟软解码,一个靠的是GPU解码,一个靠CPU解码。 
那么如何去使用这个TextureView呢? 
OK,现在SurfaceTexture就要上场了,从这两个类的命名我们就知道TextureView重点是View,而SurfaceTexture 重点是Texture它的官网解释: 
Captures frames from an image stream as an OpenGL ES texture.The image stream may come from either camera preview or video decode. 
也就是说它能捕获一个图像流的一帧来作为OpenGL 的texture也就是纹理。这个图片流主要是来自相机的预览或视频的解码。(我想这个特性是不应该可以用来做很多事了)。 
到这儿,texture也有了,那么OpenGL也就可以出来干活了,它能够绑定texture并将其在TextureView上一帧一帧的给绘制出来,就形成了我们所看到视频图像了(具体关于SurfaceTexture、TextureView大家可以参考这里) 
说了这么,是该来点代码来瞧瞧了,好的代码就跟读文学小说一样,那样的优美,并不是说我写的代码很优美啦,这只是追求。。。

代码

先从MainActicity主类开始:

public class MainActivity extends AppCompatActivity implements TextureView.SurfaceTextureListener,
MediaPlayer.OnPreparedListener{
/**本地视频的路径*/
public String videoPath = Environment.getExternalStorageDirectory().getPath()+"/aoa.mkv";
private TextureView textureView;
private MediaPlayer mediaPlayer;
/**
* 视频绘制前的配置就发生在这个对象所在类中.
* 真正的绘制工作则在它的子类中VideoTextureSurfaceRenderer
*/
private TextureSurfaceRenderer videoRenderer;
private int surfaceWidth;
private int surfaceHeight;
private Surface surface; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); textureView = (TextureView) findViewById(R.id.id_textureview);
//注册一个SurfaceTexture,用于监听SurfaceTexure
textureView.setSurfaceTextureListener(this); }
/**
* 播放视频的入口,当SurfaceTexure可得到时被调用
*/
private void playVideo() {
if (mediaPlayer == null) {
videoRenderer = new VideoTextureSurfaceRenderer(this, textureView.getSurfaceTexture(), surfaceWidth, surfaceHeight);
surface = new Surface(videoRenderer.getSurfaceTexture());
initMediaPlayer();
}
} private void initMediaPlayer() {
this.mediaPlayer = new MediaPlayer();
try {
mediaPlayer.setDataSource(videoPath);
mediaPlayer.setSurface(surface);
mediaPlayer.prepareAsync();
mediaPlayer.setOnPreparedListener(this);
mediaPlayer.setLooping(true);
} catch (IllegalArgumentException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (SecurityException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IllegalStateException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
@Override
public void onPrepared(MediaPlayer mp) {
try {
if (mp != null) {
mp.start(); //视频开始播放了
}
} catch (IllegalStateException e) {
e.printStackTrace();
}
} @Override
protected void onResume() {
super.onResume();
if (textureView.isAvailable()) {
playVideo();
}
} @Override
protected void onPause() {
super.onPause();
if (videoRenderer != null) {
videoRenderer.onPause();
}
if (mediaPlayer != null) {
mediaPlayer.release();
mediaPlayer =null;
}
} @Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
surfaceWidth = width;
surfaceHeight = height;
playVideo();
} @Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { } @Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
return false;
} @Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) { } }

这就是程序的入口类,关于Mediaplayer是怎么播放时视频源的,我就在此就不说了,这里面其实还有很多东西的,大家可以自行的查查。有一点我需要说说就是,一般MediaPlayer.setSurface(param)里面的参数param都是SurfaceView.SurfaceHolder,而我这儿直接用的是Surface (关于Surface可以参考这里),我这个视频播放与其它的视频播放的区别就在此。这篇先暂时写在这儿啦,后续核心的绘制工作,就后面有空就再写了。上面写的如果有什么问题希望大家能多多指点,感激不尽!

TextureView+SurfaceTexture+OpenGL ES来播放视频(一)的更多相关文章

  1. TextureView+SurfaceTexture+OpenGL ES来播放视频(三)

    引自:http://www.jianshu.com/p/291ff6ddc164 做好的Demo截图 opengl-video 前言 讲了这么多,可能有人要问了,播放视频用个android封装的Vid ...

  2. TextureView+SurfaceTexture+OpenGL ES来播放视频(二)

    引自:http://www.jianshu.com/p/b2d949ab1a1a 在使用OpenGL ES 绘制前,我先概括下接下来要做的工作:我先借用一个博主kiffa举的的一个栗子,我觉得说的恰到 ...

  3. Android OpenGL 播放视频学习

    1, 初步接触Open GL: http://www.cnblogs.com/TerryBlog/archive/2010/07/09/1774475.html 使用GLSurfaceView和Ren ...

  4. 短视频图像处理 OpenGL ES 实践

    2017年,短视频正以其丰富的内容表现力和时间碎片化的特点,快速崛起,而短视频最具可玩性之处就在支持人脸识别的动态贴图和各种不同效果的美颜.滤镜等.那短视频动态贴纸.滤镜.美颜等功能究竟是如何实现的呢 ...

  5. Android使用TextureView播放视频

    1.引言 如果你想显示一段在线视频或者任意的数据流比如视频或者OpenGL 场景,你可以用android中的TextureView做到. 1).TextureView的兄弟SurfaceView 应用 ...

  6. 一步步实现windows版ijkplayer系列文章之六——SDL2源码分析之OpenGL ES在windows上的渲染过程

    一步步实现windows版ijkplayer系列文章之一--Windows10平台编译ffmpeg 4.0.2,生成ffplay 一步步实现windows版ijkplayer系列文章之二--Ijkpl ...

  7. Android4.2.2启动动画前播放视频

    首先声明測试平台为瑞芯微的rk3168,Android4.2.2,Android版本号非常重要,由于Android4.0和Android4.2.2的代码有些地方就有差别,并不通用! 首先接到任务不知怎 ...

  8. OpenGL ES教程系列(经典合集)

    为了搞透播放器的开发,花了些时间收集这些资料,虽然我已经搞定opengles渲染视频的内容,但是想玩玩opengles,往深里玩,图像处理这块是个好的方向,所以opengles是值得好好学的.   O ...

  9. 笔谈OpenGL ES(一)

    现在图形类.视频类app越来越多,学习OpenGL ES是很有必要的,作为程序员是有必要做技术积累的.现在做播放器开发的工作,正好也涉及这块,那就好好学一学. CSDN上有套教程不错,OpenGL E ...

随机推荐

  1. 基于Bootstrap的炫酷jQuery slider插件

    简要教程 这是一款在原生bootstrap slider的基础上制作效果非常炫酷的jQuery slider插件.该slider插件可以自定义slider的颜色.形状.透明度和tooltip等属性,美 ...

  2. linux文件系统拓展属性

    在研究GlusterFS中,发现GlusterFS使用了文件系统的Extended Attributes,中文可以称之为文件系统扩展属性.由于资料比较少,中文资料更少,因此把记录几点Extended ...

  3. GlusterFS无法启动原因及处理方案

    启动结果: Redirecting to /bin/systemctl status  glusterd.serviceglusterd.service - GlusterFS, a clustere ...

  4. HUST 1404 Hamming Distance(字符串)

    Hamming Distance Description Have you ever heard of the Hamming distance. It is the number of positi ...

  5. webapi中Route标签定义可选参数

    Optional URI Parameters and Default Values You can make a URI parameter optional by adding a questio ...

  6. chapter9_3 协同程序实现迭代器

    将循环迭代器视为"生产者-消费者"模式的一种特例:迭代器产生的数据供循环体消费. 因此,用协同程序写迭代器就理所当然了.因为协同程序可以一改传统调用者与被调用者之间的关系. 有了这 ...

  7. Telnet服务器和域名系统的端口号 Mac OS X

    找到Telnet服务器和域名系统的端口号: lapommedeMacBook-Pro:~ lapomme$ grep telnet /etc/services telnet /udp # Telnet ...

  8. ORACLE小工具:存储过程清空所有表或使所有触发器失效

    清空所有表: CREATE OR REPLACE PROCEDURE CLEAN_TABLES as v_tablename varchar2(256); cursor cur_tablename i ...

  9. lua: Learning Official Doc notes

    dynamically typed vars: basic types: nil, boolean, number, string, function, userdata, thread & ...

  10. 学习笔记——命令模式Command

    命令模式,将具体操作Receiver封在Command中,调用类只需要知道Command即可.