1. 程式人生 > >Android VLC編譯後和TextTureView的聯合使用

Android VLC編譯後和TextTureView的聯合使用

vlc,真是一個讓人又愛又恨的播放器。愛,是因為他支援格式多樣,恨,是因為複雜的編譯,編譯過後的使用也是一件讓人頭疼的事。現在就將自己使用過程中遇到的問題簡單做一下記錄。

使用編譯好的vlc和TextTureView,播放視訊,首先會遇到視訊只是小小的一塊兒。這就給自己的使用帶來了很大的麻煩,在網上找了好久提供了一個改變大小的方法:

   private void updateVideoSurfaces() {
        int sw = framelayout.getWidth();
        int sh = framelayout.getHeight();

        // sanity check
        if (sw * sh == 0) {
            return;
        }

        mediaPlayer.getVLCVout().setWindowSize(sw, sh);

        ViewGroup.LayoutParams lp = videoview.getLayoutParams();
        if (mVideoWidth * mVideoHeight == 0) {
            /* Case of OpenGL vouts: handles the placement of the video using MediaPlayer API */
            lp.width = ViewGroup.LayoutParams.MATCH_PARENT;
            lp.height = ViewGroup.LayoutParams.MATCH_PARENT;
            videoview.setLayoutParams(lp);
            lp = framelayout.getLayoutParams();
            lp.width = ViewGroup.LayoutParams.MATCH_PARENT;
            lp.height = ViewGroup.LayoutParams.MATCH_PARENT;
            framelayout.setLayoutParams(lp);
            changeMediaPlayerLayout(sw, sh);
            return;
        }

        if (lp.width == lp.height && lp.width == ViewGroup.LayoutParams.MATCH_PARENT) {
            /* We handle the placement of the video using Android View LayoutParams */
            mediaPlayer.setAspectRatio(null);
            mediaPlayer.setScale(0);
        }

        double dw = sw, dh = sh;
        final boolean isPortrait = getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;

        if (sw > sh && isPortrait || sw < sh && !isPortrait) {
            dw = sh;
            dh = sw;
        }

        // compute the aspect ratio
        double ar, vw;
        if (mVideoSarDen == mVideoSarNum) {
            /* No indication about the density, assuming 1:1 */
            vw = mVideoVisibleWidth;
            ar = (double) mVideoVisibleWidth / (double) mVideoVisibleHeight;
        } else {
            /* Use the specified aspect ratio */
            vw = mVideoVisibleWidth * (double) mVideoSarNum / mVideoSarDen;
            ar = vw / mVideoVisibleHeight;
        }

        // compute the display aspect ratio
        double dar = dw / dh;

        switch (CURRENT_SIZE) {
            case SURFACE_BEST_FIT:
                if (dar < ar)
                    dh = dw / ar;
                else
                    dw = dh * ar;
                break;
            case SURFACE_FIT_SCREEN:
                if (dar >= ar)
                    dh = dw / ar; /* horizontal */
                else
                    dw = dh * ar; /* vertical */
                break;
            case SURFACE_FILL:
                break;
            case SURFACE_16_9:
                ar = 16.0 / 9.0;
                if (dar < ar)
                    dh = dw / ar;
                else
                    dw = dh * ar;
                break;
            case SURFACE_4_3:
                ar = 4.0 / 3.0;
                if (dar < ar)
                    dh = dw / ar;
                else
                    dw = dh * ar;
                break;
            case SURFACE_ORIGINAL:
                dh = mVideoVisibleHeight;
                dw = vw;
                break;
        }

        // set display size
        lp.width = (int) Math.ceil(dw * mVideoWidth / mVideoVisibleWidth);
        lp.height = (int) Math.ceil(dh * mVideoHeight / mVideoVisibleHeight);
        videoview.setLayoutParams(lp);

        // set frame size (crop if necessary)
        lp = framelayout.getLayoutParams();
        lp.width = (int) Math.floor(dw);
        lp.height = (int) Math.floor(dh);
        framelayout.setLayoutParams(lp);

        videoview.invalidate();
    }
private void changeMediaPlayerLayout(int displayW, int displayH) {
    /* Change the video placement using the MediaPlayer API */
    switch (CURRENT_SIZE) {
        case SURFACE_BEST_FIT:
            mediaPlayer.setAspectRatio(null);
            mediaPlayer.setScale(0);
            break;
        case SURFACE_FIT_SCREEN:
        case SURFACE_FILL: {
            Media.VideoTrack vtrack = mediaPlayer.getCurrentVideoTrack();
            if (vtrack == null)
                return;
            final boolean videoSwapped = vtrack.orientation == Media.VideoTrack.Orientation.LeftBottom
                    || vtrack.orientation == Media.VideoTrack.Orientation.RightTop;
            if (CURRENT_SIZE == SURFACE_FIT_SCREEN) {
                int videoW = vtrack.width;
                int videoH = vtrack.height;

                if (videoSwapped) {
                    int swap = videoW;
                    videoW = videoH;
                    videoH = swap;
                }
                if (vtrack.sarNum != vtrack.sarDen)
                    videoW = videoW * vtrack.sarNum / vtrack.sarDen;

                float ar = videoW / (float) videoH;
                float dar = displayW / (float) displayH;

                float scale;
                if (dar >= ar)
                    scale = displayW / (float) videoW; /* horizontal */
                else
                    scale = displayH / (float) videoH; /* vertical */
                mediaPlayer.setScale(scale);
                mediaPlayer.setAspectRatio(null);
            } else {
                mediaPlayer.setScale(0);
                mediaPlayer.setAspectRatio(!videoSwapped ? "" + displayW + ":" + displayH
                        : "" + displayH + ":" + displayW);
            }
            break;
        }
        case SURFACE_16_9:
            mediaPlayer.setAspectRatio("16:9");
            mediaPlayer.setScale(0);
            break;
        case SURFACE_4_3:
            mediaPlayer.setAspectRatio("4:3");
            mediaPlayer.setScale(0);
            break;
        case SURFACE_ORIGINAL:
            mediaPlayer.setAspectRatio(null);
            mediaPlayer.setScale(1);
            break;
    }
}

通過這兩個方法是可以解決在全屏狀態下鋪滿控制元件的畫面。但是當您切換到半屏時,就會出現上下游黑邊的情況,甚是讓人腦殼疼。在經過了多次度孃的幫助後,終於找到了一個既方便又簡潔的實現方式。

在這裡

mediaPlayer.getVLCVout().attachViews(new IVLCVout.OnNewVideoLayoutListener() {
    @Override
    public void onNewVideoLayout(IVLCVout ivlcVout, int i, int i1, int i2, int i3, int i4, int i5) {
        updateVideoSurfaces();
    }
});
private void updateVideoSurfaces() {
    int sw = framelayout1.getWidth();
    int sh = framelayout1.getHeight();
    mediaPlayer.getVLCVout().setWindowSize(sw,sh);
    mediaPlayer.setAspectRatio(sw+":"+sh);
    mediaPlayer.setScale(0);
    videoview.invalidate();
}

這樣您就可以愉快的開始玩耍了