1. 程式人生 > >TextureView SurfaceView和MediaPlayer的視訊播放

TextureView SurfaceView和MediaPlayer的視訊播放

首先看一下SurfaceView和MediaPlayer的使用,直接上程式碼

        holder = surfaceView.getHolder();//拿到surfaceView的holder
        holder.addCallback(new Callback() {//設定監聽
            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {
                if (mMediaPlayer != null && mMediaPlayer.isPlaying()) {
                    mMediaPlayer.stop();
                    mMediapPlayer.release();
                    mMediaPlayer = null
; } } //SurfaceView建立的監聽 @Override public void surfaceCreated(SurfaceHolder holder) { //這裡可以給視訊設定載入背景,避免視訊載入時出現黑屏 relativeLayout.setVisibility(View.GONE); surfaceView.setBackgroundResource(R.drawable.loading); //初始化播放器
initMediaPlayer(); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } }); //初始化播放器 private void initMediaPlayer() { if (null == mMediaPlayer) { mMediaPlayer = new
MediaPlayer(); } mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); //mMediaPlayer.setDisplay(holder); mMediaPlayer.setOnCompletionListener(new OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { LogUtils.d(TAG, "播放完成"); mMediaPlayer.seekTo(0); pause(); } }); mMediaPlayer.reset(); LogUtils.d(TAG, "第一次播放設定路徑path::::::1" + path); mMediaPlayer.setDataSource(path); mMediaPlayer.prepareAsync(); mMediaPlayer.setOnPreparedListener(new OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { LogUtils.d(TAG, "準備完成"); //準備完成後才給視訊播放設定holder mMediaPlayer.setDisplay(holder); mMediaPlayer.start(); mMediaPlayer.seekTo(0); mMediaPlayer .setOnSeekCompleteListener(new OnSeekCompleteListener() { @Override public void onSeekComplete(MediaPlayer mp) { mMediaPlayer.pause(); //當視訊seekTo到0 秒時,去掉載入的背景圖片,顯示暫停在0秒的視訊,避免黑屏 surfaceView.setBackgroundResource(0); relativeLayout.setVisibility(View.VISIBLE); LogUtils.d(TAG, "path::::::2" + path); } }); LogUtils.d(TAG, "準備完成"); } }); }

SurfaceView和MediaPlayer使用要比Android自帶的VideoView使用起來擴充套件性更強,可以顯示視訊載入的圖片,VideoView由於內部封裝好了SurfaceView和MediaPlayer,但是又很少對外暴漏介面,使用起來不方便.
但是SurfaceView和MediaPlayer使用時也會有缺陷:
1.不能隨意更改視訊的顯示大小,也不能旋轉螢幕
2.當在ListView中放置SurfaView+MediaPlayer之後,滑動是,SurfaceView會出現嚴重的抖動,即視訊的上下區域會出現很明顯的黑屏,很不協調.

所以後面考慮了TextureView+MediaPlayer,由於TextureView本身就是一個View,故其功能更強大,也可以避免SurfaceView抖動的黑屏問題,先上程式碼,具體見程式碼註釋.

    textureView.setAlpha(0.5f);//設定透明度
    textureView.setRotation(45);//設定旋轉
    textureView.setMinimumWidth(300);//設定寬度
    textureView.setSurfaceTextureListener(this);
    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture,
            int width, int height) {
        LogUtils.d(TAG, "onSurfaceTextureAvailable:width:height--:" + width
                + "--:" + height);
        mSurface = new Surface(surfaceTexture);
        //在這裡初始化MediaPlayer ,和上面的一樣,
        initMediaPlayer();
    }

    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width,
            int height) {
        LogUtils.d(TAG, "onSurfaceTextureSizeChanged");

    }

    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
        LogUtils.d(TAG, "onSurfaceTextureDestroyed");
        if (null != mMediaPlayer) {
            mMediaPlayer.reset();
        }

        return false;
    }

    @Override
    public void onSurfaceTextureUpdated(SurfaceTexture surface) {
        LogUtils.d(TAG, "onSurfaceTextureUpdated");
    }

但是TextureView本身多了很多API,還可以設定寬高比等等,並且在ListView中展示時候也不會出現抖動黑屏,複用的時候,我們只需要重新設定播放器並將其與TextView的Surface關聯即可.