微信朋友圈短视频控件的实现, TextureView 的基本使用。

4,371 阅读2分钟

我这里简单总结下:

1.TextureView主要用来绘制流内容(比如视频,openGl场景)

2.TextureViewsurfaceView很相似,但是surfaceView是重新创建新窗口,这种方式效率高,但是不支持变化(旋转缩放等)操作,也很难再listview中使用,所以TextureView就弥补了这个缺点。

3.TextureView仅支持硬件加速,是通过GPU来绘制图形的。

TextureView简单用法

实现surfaceTextureListener,通过该接口的方法获得surfaceTexture

surfaceTexture是用来捕获来至cameravideo的图像流,如果获取不到surfaceTexture,那么TextureView就显示不了任何内容

接下来结合MediaPlayer我们来实现短视频控件

以前用surfaceView来播放视频的时候可以获得surfaceHolder对象,然后通过setDisplay方法就可以为mediaplayer指定显示的surfaceview

但是textureview有点不同,他返回的是SurfaceTexture,这里我们需要先将SurfaceTexture转为Surface,然后通过setSurface方法为Mediaplayer指定显示的TextureView

VideoTextureView的代码:

public class VideoTextureView extends TextureView implements TextureView.SurfaceTextureListener {

    private MediaPlayer mediaPlayer;
    private Surface surface;
    private ImageView ivTip;
    private boolean isPlaying = false;
    private boolean isSurfaceTextureAvailable = false;
    private String videoPath;

    public VideoTextureView(Context context) {
        super(context);
        init(context);
    }

    public VideoTextureView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public VideoTextureView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    private void init(Context context) {
        setSurfaceTextureListener(this);
    }

    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i1) {
        surface = new Surface(surfaceTexture);
        isSurfaceTextureAvailable = true;
    }

    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i1) {

    }

    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
        surface=null;
        onVideoTextureViewDestroy();
        return true;
    }

    @Override
    public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {

    }

    public void startMediaPlayer(){
        if(isPlaying || !isSurfaceTextureAvailable)
            return;
        if(TextUtils.isEmpty(videoPath)){
            ToastUtil.showMessage("视频路径异常", Toast.LENGTH_SHORT, true);
            return;
        }
        try {
            if(videoPath.equals(App.videoPath))
                mediaPlayer = MediaPlayer.create(getContext(), R.raw.test);
            else {
                final File file = new File(videoPath);
                if (!file.exists()) {//文件不存在
                    ToastUtil.showMessage("视频不存在", Toast.LENGTH_SHORT, true);
                    return;
                }
                mediaPlayer = new MediaPlayer();
                mediaPlayer.setDataSource(file.getAbsolutePath());
            }
            mediaPlayer.setSurface(surface);
            mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
            mediaPlayer.setVolume(0, 0); //设置左右音道的声音为0
            mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                @Override
                public void onPrepared(MediaPlayer mp){
                    mediaPlayer.start();
                    showIvTip(false);
                    isPlaying = true;
                }
            });
            mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mediaPlayer) {
                    stopMediaPlayer();
                }
            });
            mediaPlayer.prepare();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void showIvTip(boolean show){
        if(ivTip != null){
            int visibility = show?VISIBLE : GONE;
            ivTip.setVisibility(visibility);
        }
    }

    public void stopMediaPlayer(){
        if(mediaPlayer != null && isPlaying) {
            mediaPlayer.stop();
            mediaPlayer.reset();
        }
        showIvTip(true);
        isPlaying = false;
    }

    public void setIvTip(ImageView ivTip){
        this.ivTip = ivTip;
    }

    public boolean getPlayStatus(){
        return isPlaying;
    }

    public void setVideoPath(String path ){
        videoPath = path;
    }

    public void onVideoTextureViewDestroy(){
        isPlaying = false;
        if(mediaPlayer != null){
            stopMediaPlayer();
            mediaPlayer.release();
        }
    }
}

静态效果图

     

源码地址: github.com/zx391324751…   觉得可以的话,恳请各位帮忙给个星星.