zoukankan      html  css  js  c++  java
  • TextureView实现视频播放

    TextureView在4.0(API level 14)中引入。它可以将内容流直接投影到View中,可以用于实现Live preview等功能。和SurfaceView不同,它不会在WMS中单独创建窗口,而是作为View hierachy中的一个普通View,因此可以和其它普通View一样进行移动,旋转,缩放,动画等变化。值得注意的是TextureView必须在硬件加速的窗口中。它显示的内容流数据可以来自App进程或是远端进程。从类图中可以看到,TextureView继承自View,它与其它的View一样在View hierachy中管理与绘制。TextureView重载了draw()方法,其中主要把SurfaceTexture中收到的图像数据作为纹理更新到对应的HardwareLayer中。SurfaceTexture.OnFrameAvailableListener用于通知TextureView内容流有新图像到来。SurfaceTextureListener接口用于让TextureView的使用者知道SurfaceTexture已准备好,这样就可以把SurfaceTexture交给相应的内容源。Surface为BufferQueue的Producer接口实现类,使生产者可以通过它的软件或硬件渲染接口为SurfaceTexture内部的BufferQueue提供graphic buffer。

    结构类图如下

    这里不啰嗦解释,具体看官方API文档

    Textureview API

    MainView

    自定义一个view,注意TextureView中的draw方法和onDraw方法都是被定义成final的,不能被子类覆盖。所以必须可以通过实现TextureView.SurfaceTextureListener 接口,然后重写onSurfaceTextureAvailable方法,把你想添加的功能加到这个方法里即可,这里加入播放视频的功能

    package com.test.xingliu.texturesample;
    
    import android.content.Context;
    import android.graphics.SurfaceTexture;
    import android.media.MediaPlayer;
    import android.view.Surface;
    import android.view.TextureView;
    
    import java.io.IOException;
    
    /**
     * Created by Xingliu on 2016/12/5.
     */
    public class MainView extends TextureView implements TextureView.SurfaceTextureListener {
        private static final String FILE_NAME = "rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov";
    
        private MediaPlayer mMediaPlayer;
    
    
        public MainView(Context context) {
            super(context);
            initView();
    
        }
    
        public void stopPlay() {
            if (mMediaPlayer != null) {
                mMediaPlayer.stop();
                mMediaPlayer.release();
                mMediaPlayer = null;
            }
    
        }
    
        private void initView() {
            setSurfaceTextureListener(this);
    
        }
    
        @Override
        public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i2) {
    
            Surface surface = new Surface(surfaceTexture);
            try {
    
                mMediaPlayer = new MediaPlayer();
                mMediaPlayer.setDataSource(FILE_NAME);
                mMediaPlayer.setSurface(surface);
                mMediaPlayer.prepareAsync();
                mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                    @Override
                    public void onPrepared(MediaPlayer mp) {
                        mMediaPlayer.start();
                    }
                });
    
            } catch (Exception e) {
                e.printStackTrace();
            }
    
        }
    
        @Override
        public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i2) {
        }
    
        @Override
        public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
            return true;
        }
    
        @Override
        public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
        }
    }
    

    对应的activity_main.xml

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="176dp"
        android:paddingTop="@dimen/activity_vertical_margin"
        tools:context=".MainActivity">
    
        <com.test.xingliu.texturesample.MainView
            android:id="@+id/textureView"
            android:layout_width="match_parent"
            android:layout_height="176dp"
            android:orientation="vertical"
            android:paddingBottom="@dimen/activity_vertical_margin"
            android:paddingLeft="@dimen/activity_horizontal_margin"
            android:paddingRight="@dimen/activity_horizontal_margin" />
    
    
    </LinearLayout>
    

    MainActivity

    package com.test.xingliu.texturesample;
    
    import android.app.Activity;
    import android.os.Bundle;
    
    public class MainActivity extends Activity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(new MainView(this));
        }
    
        @Override
        protected void onDestroy() {
            new MainView(this).stopPlay();
            super.onDestroy();
        }
    
    
    }
    

    mainifest文件

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.test.xingliu.texturesample">
    
        <uses-permission android:name="android.permission.INTERNET" />
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
        <application
            android:allowBackup="true"
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
            <activity android:name=".MainActivity">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
        </application>
    
    </manifest>

    效果图如下,由于资源是网络上的,需要联网才能播放

    这里写图片描述

    需要注意到是在硬件加速的情况下,TextureView是用GPU渲染的,软件上的Canvas是不能进行处理的,而TextureView必须在硬件加速的窗口中,可以调用lockcanvas()方法来获取canvas

  • 相关阅读:
    sun.misc.Unsafe
    一个普通Java程序包含哪些线程??
    类加载-类加载器
    类加载-类的生命周期
    类加载-初始化的触发
    Java语法糖
    Java线程池
    Java线程池之ThreadPoolExecutor
    【结构型】- 适配器模式
    数据结构与算法之排序(3)插入排序 ——in dart
  • 原文地址:https://www.cnblogs.com/ainima/p/6331769.html
Copyright © 2011-2022 走看看