• TextureView SurfaceView 简介 案例 MD


    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱
    MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina.com

    目录

    TextureView 简介

    Android普通窗口的视图绘制机制是一层一层的,任何一个子元素或者是局部的刷新都会导致整个视图结构全部重绘一次,因此效率相对较低。

    视频或者opengl内容往往是显示在SurfaceView中的,SurfaceView的工作方式是:创建一个置于应用窗口之后的新窗口。因为SurfaceView窗口刷新的时候不需要重绘应用程序的窗口,所以这种方式的效率非常高。

    但是SurfaceView也有一些非常不便的限制,因为SurfaceView的内容不在应用窗口上,所以不能使用平移、缩放、旋转等变换操作,也难以放在ListView或者ScrollView中,同样不能使用UI控件的一些特性,比如View.setAlpha()。

    为了解决这个问题,Android 4.0 中引入了TextureView,与SurfaceView相比,TextureView并没有创建一个单独的 Surface 用来绘制,这使得它可以像一般的View一样执行一些变换操作,设置透明度等

    TextureView的使用非常简单,你唯一要做的就是获取用于渲染内容的SurfaceTexture。

    Textureview必须在硬件加速开启的窗口中。

    官方文档

    Class Overview
    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.

    TextureView can only be used in a hardware accelerated硬件加速 window. When rendered in呈现在 software, TextureView will draw nothing.

    Unlike SurfaceView, TextureView does not create a separate单独的 window but behaves as a regular像平常的 View. This key核心的 difference allows a TextureView to be moved, transformed, animated动画, etc. For instance, you can make a TextureView semi-translucent半透明 by calling myView.setAlpha(0.5f).

    Using a TextureView is simple: all you need to do is get its SurfaceTexture. The SurfaceTexture can then be used to render展示 content. The following example demonstrates how to render the camera preview into a TextureView:

    A TextureView's SurfaceTexture can be obtained获得 either by invoking引用 getSurfaceTexture() or by using a TextureView.SurfaceTextureListener. It is important to know that a SurfaceTexture is available only after the TextureView is attached to a window (and onAttachedToWindow() has been invoked.) It is therefore highly recommended推荐 you use a listener to be notified when the SurfaceTexture becomes available.

    It is important to note that only one producer制片人 can use the TextureView. For instance, if you use a TextureView to display the camera preview, you cannot use lockCanvas() to draw onto the TextureView at the same time.

    案例:使用TextureView和MediaPlayer播放视频

    Activity

    public class TextureViewTestActivity extends Activity implements TextureView.SurfaceTextureListener {
    
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);//取消状态栏
            TextureView textureView = new TextureView(this);
            textureView.setSurfaceTextureListener(this);
            textureView.setRotation(45.0f);//可以像普通View一样使用平移、缩放、旋转等变换操作
            textureView.setAlpha(0.5f);
            setContentView(textureView);
        }
    
        @Override
        public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
            Log.i("bqt", "onSurfaceTextureAvailable");// SurfaceTexture准备就绪
            if (new Random().nextBoolean()) {
                String path = "http://ozvd186ua.bkt.clouddn.com/douyin.mp4";
                MediaPlayerManager.getInstance().playUrlMedia(new Surface(surface), path);
            } else {
                try {
                    MediaPlayerManager.getInstance().playAssetMedia(new Surface(surface), getAssets().openFd("douyin.mp4"));
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    
        @Override
        public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
            Log.i("bqt", "onSurfaceTextureSizeChanged");// SurfaceTexture缓冲大小变化
    
        }
    
        @Override
        public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
            Log.i("bqt", "onSurfaceTextureDestroyed");// SurfaceTexture即将被销毁
            MediaPlayerManager.getInstance().stopMedia();
            return true;
        }
    
        @Override
        public void onSurfaceTextureUpdated(SurfaceTexture surface) {
            //Log.i("bqt", "onSurfaceTextureUpdated");// SurfaceTexture通过updateImage更新
        }
    }

    MediaPlayerManager

    public class MediaPlayerManager {
    
        private MediaPlayer mPlayer;
    
        private static MediaPlayerManager instance = new MediaPlayerManager();
    
        private MediaPlayerManager() {//构造方法私有
        }
    
        public static MediaPlayerManager getInstance() {
            return instance;
        }
    
        /**
         * 播放网络或本地中的Media资源
         */
        public void playUrlMedia(Surface surface, String mediaPath) {
            try {
                if (mPlayer == null) {
                    mPlayer = new MediaPlayer();
                    mPlayer.setDataSource(mediaPath);
                } else {
                    if (mPlayer.isPlaying()) {
                        mPlayer.stop();
                    }
                    mPlayer.reset();
                    mPlayer.setDataSource(mediaPath);
                }
                mPlayer.setSurface(surface);
                mPlayer.setVolume(0.5f, 0.5f);
                mPlayer.setLooping(true);
                mPlayer.prepareAsync();
                mPlayer.setOnPreparedListener(MediaPlayer::start);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 播放Asset中的Media资源
         */
        public void playAssetMedia(Surface surface, AssetFileDescriptor fileDescriptor) {
            try {
                if (mPlayer == null) {
                    mPlayer = new MediaPlayer();
                    mPlayer.setDataSource(fileDescriptor.getFileDescriptor(), fileDescriptor.getStartOffset(), fileDescriptor.getDeclaredLength());
                } else {
                    if (mPlayer.isPlaying()) {
                        mPlayer.stop();
                    }
                    mPlayer.reset();
                    mPlayer.setDataSource(fileDescriptor.getFileDescriptor(), fileDescriptor.getStartOffset(), fileDescriptor.getDeclaredLength());
                }
                mPlayer.setSurface(surface);
                mPlayer.setVolume(0.5f, 0.5f);
                mPlayer.setLooping(true);
                mPlayer.prepareAsync();
                mPlayer.setOnPreparedListener(MediaPlayer::start);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 停止播放Media
         */
        public void stopMedia() {
            try {
                if (mPlayer != null) {
                    if (mPlayer.isPlaying()) {
                        mPlayer.stop();
                    }
                    mPlayer.release();
                    mPlayer = null;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    案例:使用TextureView和Camera预览拍照

    public class TextureViewTestActivity extends Activity implements TextureView.SurfaceTextureListener {
        private Camera mCamera;//权限【android.permission.CAMERA】
    
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);//取消状态栏
            TextureView mTextureView = new TextureView(this);
            mTextureView.setSurfaceTextureListener(this);
            mTextureView.setRotation(45.0f);//可以像普通View一样使用平移、缩放、旋转等变换操作
            mTextureView.setAlpha(0.5f);
            setContentView(mTextureView);
        }
    
        @Override
        public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
            Log.i("bqt", "onSurfaceTextureAvailable");// SurfaceTexture准备就绪
            try {
                mCamera = Camera.open();//如果提示【Fail to connect to camera service】很可能是没申请权限,或申请权限了单用户没有给你权限
                mCamera.setPreviewTexture(surface);
                mCamera.startPreview();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        @Override
        public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
            Log.i("bqt", "onSurfaceTextureSizeChanged");// SurfaceTexture缓冲大小变化
    
        }
    
        @Override
        public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
            Log.i("bqt", "onSurfaceTextureDestroyed");// SurfaceTexture即将被销毁
            mCamera.stopPreview();
            mCamera.release();
            return true;
        }
    
        @Override
        public void onSurfaceTextureUpdated(SurfaceTexture surface) {
            //Log.i("bqt", "onSurfaceTextureUpdated");// SurfaceTexture通过updateImage更新
        }
    }

    2018-5-23

  • 相关阅读:
    记录:将图片数据生成 tfrecords 文件并在训练使用时读取
    记录:EM 算法估计混合高斯模型参数
    记录:Ubuntu 18.04 安装 tensorflow-gpu 版本
    记录:tf.saved_model 模块的简单使用(TensorFlow 模型存储与恢复)
    记录:TensorFlow 中的 padding 方式
    mybatis list映射
    idea使用插件mybatis-generator-plus生成mapper文件(mysql亲测可用)
    Element-UI树形表格
    Mysql5.7版本ERROR 1055问题
    为DISTINCT、GROUP BY和ORDER BY效率问题提提速
  • 原文地址:https://www.cnblogs.com/baiqiantao/p/299570dc16f00c0ad12de306613e449f.html
Copyright © 2020-2023  润新知