2016-03-08 89 views
4

我使用camera2和im在縮略圖中長按後顯示我的照片/視頻預覽。此外,根據相機在拍攝照片時的方向進行旋轉。例如,如果我在90º拍攝了一張照片,我的預覽也會旋轉90º。在紋理視圖中旋轉視頻/媒體播放器

一切工作正常,即時通訊使用customContainer和即時通訊使用onLayout和OnMeasure創建我的預覽取決於屏幕的大小,縱橫比和方向。它適用於照片。當我嘗試對視頻執行相同操作時,出現問題,它們只能在0º下工作。

我試着旋轉包含我的MediaPlayer的TextureView,但在此之後,我的onLayout變得瘋狂,並且找不到(l,t,r,b)組合來正確測量它。

這裏是我的XML:

<?xml version="1.0" encoding="utf-8"?> 

<com.android.camera.ui.common.ThumbnailContainer xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/preview_container" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:background="@drawable/rounded_rectangle_thumbnail_preview" 
    android:visibility="invisible"> 



<TextureView 
    android:id="@+id/show_video_content" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:visibility="invisible"/> 

<ImageView 
    android:id="@+id/image_container" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:adjustViewBounds="true" 
    android:visibility="invisible" 

/> 
</com.android.camera.ui.common.ThumbnailContainer> 

這裏是我的表面代碼:

@Override 
    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { 
     Log.i(TAG, "InicializoSurface. Width: " + width + " HEIGHT:" + height); 
     Log.i(TAG, "InicializoSurface. Width: " + mVideoView.getMeasuredWidth() + " HEIGHT:" + mVideoView.getMeasuredHeight()); 
     Log.i(TAG, "View transform. Width: " + mVideoView.getWidth() + " HEIGHT:" + mVideoView.getHeight()); 


     mMediaSurface = new Surface(mVideoView.getSurfaceTexture()); 
     initializeMediaPlayer(); 

    } 

    @Override 
    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { 

    } 

    @Override 
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { 

     if (mMediaPlayer != null) { 
      // Make sure we stop video and release resources when activity is destroyed. 
      mMediaPlayer.stop(); 
      mMediaPlayer.release(); 
      mMediaPlayer = null; 
     } 
     return false; 
    } 
    @Override 
    public void onSurfaceTextureUpdated(SurfaceTexture surface) { 

    } 
    ////////// 
    private void initializeMediaPlayer(){ 

     mMediaPlayer = new CustomMediaPlayer(); 
     Uri uri = Uri.parse(mCameraDataAdapter.getList().get(0).getPath()); 

     try { 
      mMediaPlayer.setDataSource(mActivity, uri); 
      mMediaPlayer.setSurface(mMediaSurface); 
      mMediaPlayer.prepareAsync(); 
      mMediaPlayer.setOnPreparedListener(mMediaPlayer); 
      mMediaPlayer.setOnCompletionListener(mMediaPlayer); 


     } catch (IOException e) { 
      e.printStackTrace(); 
     } 


    } 


     /////////// 
     mVideoView.setVisibility(View.VISIBLE); 

//     mVideoView.setTranslationX(-200); 
//     mVideoView.setTranslationY(-200); 
        Log.i(TAG, "X: " + mVideoView.getX() + "Y: " + mVideoView.getY()); 


        if (mVideoView.isAvailable()) { 
         onSurfaceTextureAvailable(mVideoView.getSurfaceTexture(), mVideoView.getWidth(), mVideoView.getHeight()); 
        } 

        if (mMediaPlayer == null) { 
         initializeMediaPlayer(); 
        } 

//     mMediaPlayer.mVideoHolder = mVideoView.getHolder(); 
//     mMediaPlayer.setDisplay(mMediaPlayer.mVideoHolder); 

        if (mMediaPrepared) { 
         Log.i(TAG,"Comienzo Video"); 
         mMediaPlayer.start(); 
        } 

最後,這裏是我onMeasure/OnLayout從我CustomView

 @Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 

     int width; 
     int height; 
     int wantedWidth = 0; 
     int wantedHeight = 0; 

     if(mWidth == 0 && mHeight == 0){ 
      mWidth = MeasureSpec.getSize(widthMeasureSpec); 
      mHeight =MeasureSpec.getSize(heightMeasureSpec); 
     } 

     width = mWidth; 
     height = mHeight; 





     if (mOrientation == 0 || mOrientation == 180) { 

      wantedWidth = width - (int)(mMargin * 2); 

      mVideo.measure(MeasureSpec.makeMeasureSpec(wantedWidth, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec((int) (wantedWidth * mVideoAspectRatio), MeasureSpec.EXACTLY)); 
      wantedHeight = (mViewTop.getLayoutParams().height) * 2 + (int) (wantedWidth * mAspectRatio); 

     } else { 
      Log.e(TAG, "Real Width = " + width + " real Height = " + height); 

      wantedHeight = width - 2 * mViewTop.getLayoutParams().height - (int)(mMargin * 2); 

      mVideo.measure(MeasureSpec.makeMeasureSpec(wantedHeight, MeasureSpec.EXACTLY),MeasureSpec.makeMeasureSpec((int) (wantedHeight * mAspectRatio), MeasureSpec.EXACTLY)); 
//   
      wantedWidth =(int) (wantedHeight * mAspectRatio) ; 
      wantedHeight = width - (int)(mMargin * 2); 


     } 

     Log.e(TAG, "onMeasure: " + wantedWidth + "x" + wantedHeight); 
     setMeasuredDimension(MeasureSpec.makeMeasureSpec(wantedWidth, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(wantedHeight, MeasureSpec.EXACTLY)); 
    } 

    @Override 
    protected void onLayout(boolean changed, int l, int t, int r, int b) { 
     int w = getMeasuredWidth(); 
     int h = getMeasuredHeight(); 

     int viewHeight = mViewBottom.getMeasuredHeight(); 
     int imageViewHeight = mImage.getMeasuredHeight(); 

     int wantedHeight = 0; 
//  w = w - (int) (2 * mMargin); 
     if (mOrientation == 0 || mOrientation == 180) { 

      mVideo.layout(0,wantedHeight,w,wantedHeight + imageViewHeight); 


     }else{    
      mVideo.layout(viewHeight,0,r-viewHeight - (int) mMargin,w); 
     } 
    } 

我已經工作在試圖解決這個最後的日子,但我沒有得到任何方法來解決它,我一直在尋找其他職位Android MediaRecorder making rotated video,我看到它不可能旋轉textureView,但我不能相信我可以旋轉一個形象如此輕鬆,在這期間必須爭取將90度視頻旋轉..

希望有人能夠找到解決方案!祝你有美好的一天!

+0

使用'TextureView#setTransform(矩陣變換)' – pskink

+0

@pskink我已經嘗試過使用Matrix和SetTransform,它什麼也不做。在測量所有內容之前,當我調用Surface或我選擇照片時,我嘗試了它。視頻不會改變,它保持與以前完全一樣:S –

+1

'setTransform'正常工作,我使用過很多次,基本上你的'Matrix'是以錯誤的方式計算的 – pskink

回答

5

感謝@pskink在帖子中的評論,我找到了解決方案。最後我使用了Matrix來旋轉視頻容器(紋理視圖)。 pskink給我的方法是下一個:

private void setupMatrix(int width, int height, int degrees, boolean isHorizontal) { 
    Log.d(TAG, "setupMatrix for " + degrees + " degrees"); 
    Matrix matrix = new Matrix(); 
    //The video will be streched if the aspect ratio is in 1,5(recording at 480) 
    RectF src; 
    if (isHorizontal) 
//In my case, I changed this line, cause with my onMeasure() and onLayout() methods my container view is already rotated and scaled, so I need to sent the inverted params to the src. 
     src = new RectF(0, 0,mThumbnailContainer.getmWidth(), mThumbnailContainer.getmHeight()); 
     else 
     src = new RectF(0, 0, mThumbnailContainer.getmWidth(),mThumbnailContainer.getmHeight()); 
    RectF dst = new RectF(0, 0, width, height); 
    RectF screen = new RectF(dst); 
    Log.d(TAG, "Matrix: " + width + "x" + height); 
    Log.d(TAG, "Matrix: " + mThumbnailContainer.getmWidth() + "x" + mThumbnailContainer.getmHeight()); 
    matrix.postRotate(degrees, screen.centerX(), screen.centerY()); 
    matrix.mapRect(dst); 

    matrix.setRectToRect(src, dst, Matrix.ScaleToFit.CENTER); 
    matrix.mapRect(src); 

    matrix.setRectToRect(screen, src, Matrix.ScaleToFit.FILL); 
    matrix.postRotate(degrees, screen.centerX(), screen.centerY()); 

    mVideoView.setTransform(matrix); 
} 

最後它的工作,它看起來非常棒^^。通過此功能,我可以完全旋轉和縮放任何視頻,具體取決於我的設備屏幕和用於錄製視頻或拍攝照片的長寬比。

非常感謝你Pskink的幫助,我發佈了答案,因爲你沒有發佈任何東西,當我告訴你這樣做。無論如何,如果你改變你的意見,請發表一個答案,我會檢查它是否正確。

希望這會幫助更多的人!