`

TextureView+SurfaceTexture+OpenGL ES来播放视频(一)

 
阅读更多
文/子雷(简书作者)
原文链接:http://www.jianshu.com/p/d3d3186eefcb
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

最近发现视频直播类应用层出不穷,比如233手游直播,蓝鲸直播,微录客等等什么的,连android界大神老罗也在开发手游录制类的应用,这里面的技术含量也是挺高的,需要了解android 系统的UI渲染机制以及很多系统底层的知识,而我最近也在想好好研究研究android 的UI渲染机制并以此作为深入了解android的入口。
前段时间看到杰伦都进入了游戏圈,代言起来了LOL,艾玛让我对LOL稍稍增加了一丝好感。还有各大游戏主播集体跳槽也是比较热门的事件,游戏圈都快赶上娱乐圈了。听说那几个知名游戏主播的都是拿着千万的年薪了,只想说一句,我伙呆啊!

正题

好了,在讲代码实现之前,我先讲讲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来播放视频(二)

分享到:
评论

相关推荐

    TextureView+Mediaplayer实现本地视频播放

    本篇将深入探讨如何使用`TextureView`结合`MediaPlayer`来实现在Android应用中播放本地视频。`TextureView`提供了一个高效且灵活的方式显示图像数据,而`MediaPlayer`是Android系统提供的多媒体播放器,支持多种格式...

    AndroidOpenGLVideoDemo:在其上使用TextureView和OpenGL渲染视频的演示

    TextureView视频播放演示这是一个使用OpenGL将视频渲染到TextureView的演示。 这样,您就可以在播放期间将OpenGL着色器用于视频效果。 重要文件: TextureSurfaceRenderer.java与GLSurfaceView类似,它在TextureView...

    Android使用FFmpeg+Opengles来解码播放视频

    在Android平台上,开发一款能够播放视频的应用通常涉及多个关键技术,其中最核心的两个是FFmpeg和OpenGL ES。FFmpeg是一个强大的多媒体处理库,而OpenGL ES则是一种用于2D和3D图形渲染的标准。本篇文章将深入探讨...

    TextureView+MediaPlayer播放本地视频(MVC+MVP双模式播放案例)

    在Android开发中,播放本地视频是一项常见的需求。本案例通过TextureView和MediaPlayer的结合,提供了两种不同的架构模式——MVC(Model-View-Controller)和MVP(Model-View-Presenter)来实现这一功能。接下来,...

    TextureView播放视频

    TextureView是一个可以显示OpenGL纹理的View,它在后台创建了一个SurfaceTexture对象,允许开发者直接将OpenGL ES纹理数据绘制到视图上。这种特性使得TextureView非常适合于与硬件加速的图形和视频处理相结合。 在...

    OpenGL_PBR+IBL+Specular+Texture1

    OpenGL_PBR+IBL+Specular+Texture.rar OpenGL_PBR+IBL+Specular+Texture.rar OpenGL_PBR+IBL+Specular+Texture.rar

    Android中使用SurfaceTexture自定义相机

    SurfaceTexture是一个抽象接口,它与OpenGL ES纹理绑定,允许将硬件图形缓冲区的像素数据同步到GPU纹理。在相机应用中,我们可以设置SurfaceTexture作为相机预览的输出目标,这样相机捕获的每一帧图像都会自动更新到...

    Qt+openglEs2加载3D模型,平移、旋转、拾取模型

    Qt+openglEs2加载3D模型Qt+openglEs2加载3D模型Qt+openglEs2加载3D模型Qt+openglEs2加载3D模型Qt+openglEs2加载3D模型Qt+openglEs2加载3D模型Qt+openglEs2加载3D模型Qt+openglEs2加载3D模型Qt+openglEs2加载3D模型Qt...

    OpenGLES渲染播放Sdcard中的视频资源

    1、案例运行注意事项: 案例源码运行前,需向Sdcard如下路径存入测试视频:/sdcard/Android/data/...e、通过 MediaPlayer 解封装视频,并最终通过OpenGL ES渲染解封装后的视频图像,同时播放视频的声音;

    android 通过surfacetexture绘制Bitmap

    android 通过surfacetexture绘制Bitmap,使用ISurfaceComposerClient创建新图层

    基于Android平台音视频编解码项目+Kotlin+MediaCodeC+OpenGL高效解决音视频编解码问题+源码+开发文档

    基于Android平台音视频编解码项目+Kotlin+MediaCodeC+OpenGL高效解决音视频编解码问题+源码+开发文档,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用~ 基于Android...

    OpenGL+qt抗锯齿OpenGL+qt抗锯齿

    OpenGL+qt抗锯齿OpenGL+qt抗锯齿OpenGL+qt抗锯齿OpenGL+qt抗锯齿OpenGL+qt抗锯齿OpenGL+qt抗锯齿OpenGL+qt抗锯齿OpenGL+qt抗锯齿OpenGL+qt抗锯齿OpenGL+qt抗锯齿OpenGL+qt抗锯齿OpenGL+qt抗锯齿OpenGL+qt抗锯齿...

    java自定义 camera + camera2+ opengles + 各种系统相机操作.zip

    在提供的压缩包"java自定义 camera + camera2+ opengles + 各种系统相机操作"中,应该包含了一些示例代码和教程,帮助你理解和实践这些技术。通过深入研究这些资源,你将能够掌握如何在Android平台上构建自定义相机...

    Camera2GLPreview,使用camera2 api和opengl es的android相机预览应用程序.zip

    Camera2GLPreview是一款基于Android平台的应用程序,它利用了Android的高级相机接口——Camera2 API,同时结合OpenGL ES进行实时的图像渲染。这个开源项目旨在为开发者提供一个平台,了解如何将高性能的图形处理与...

    OPENGL ES 2.0 播放视频

    基于OpenGL ES 2.0 实现纹理渲染,建立立方体模型,在模型表面播放视频。包括部分转换视频代码

    opengl+qt加载模型

    opengl+qt加载模型opengl+qt加载模型opengl+qt加载模型opengl+qt加载模型opengl+qt加载模型opengl+qt加载模型opengl+qt加载模型opengl+qt加载模型opengl+qt加载模型opengl+qt加载模型opengl+qt加载模型opengl+qt加载...

    TextureView实现自定义相机预览、拍照

    在Android开发中,TextureView是一种可以显示视频流或者2D图形的视图组件,它非常适合用来实现自定义相机预览和拍照功能。本篇文章将详细探讨如何利用TextureView来实现这些功能,以及如何处理图像变形等问题。 ...

    opengl+qt实现鼠标选中模型

    opengl+qt实现鼠标选中模型opengl+qt实现鼠标选中模型opengl+qt实现鼠标选中模型opengl+qt实现鼠标选中模型opengl+qt实现鼠标选中模型opengl+qt实现鼠标选中模型opengl+qt实现鼠标选中模型opengl+qt实现鼠标选中模型...

    OpenGL ES + Android

    1.Android开发之OpenGL+ES教程 2.Android下Opengl+ES导引 3.OpenGL_ES_Programming_Guide_v1.0.2part1 4.OpenGL_ES_Programming_Guide_v1.0.2Part2 5.OpenGL + es + 2.0 + demo 6.OpenGL + ES + three + books 7....

    ExoPlayer 使用GLSurfaceView播放视频

    本篇文章将详细讲解如何使用ExoPlayer结合GLSurfaceView来播放视频,并利用OpenGL ES进行渲染。 首先,GLSurfaceView是Android系统提供的一种用于在视图上显示OpenGL ES图形的组件。OpenGL ES是OpenGL的一个子集,...

Global site tag (gtag.js) - Google Analytics