Android VLC編譯後和TextTureView的聯合使用
阿新 • • 發佈:2018-12-25
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(); }
這樣您就可以愉快的開始玩耍了