2016-03-08 2 views
4

Im работает с camera2 и im, показывая предварительный просмотр моей фотографии/видео после longclick в моем миниатюре. Кроме того, im вращает его в зависимости от того, какую ориентацию имела камера, когда изображение было зафиксировано. Например, если я сделал снимок в 90º, мой просмотр также будет повернут на 90º.Поворот видео/MediaPlayer в TextureView

Все работает отлично, я использую customContainer и там im использует onLayout и OnMeasure для создания моего предварительного просмотра в зависимости от размера экрана, соотношения сторон и ориентации. Он отлично работает с фотографиями. Моя проблема возникает, когда я пытаюсь сделать то же самое с видео, они работают только в 0º.

Я попытался повернуть TextureView, который содержит мой MediaPlayer, но после этого мой 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, и я увидел, что его невозможно повернуть текстуру, но я не могу поверить, что могу повернуть изображение так легко и придется бороться во время этого, чтобы повернуть на 90 градусов видео.

Надеюсь, что кто-то сможет найти решение! Хорошего дня!

+0

use 'TextureView # setTransform (Матричное преобразование)' – pskink

+0

@pskink Я уже пытался использовать матрицу с SetTransform, и она ничего не делает. Я попробовал это, прежде чем измерить все, когда я назову поверхность, или когда я выбираю фотографию. Видео не изменяется, оно остается таким же, как и раньше: S –

+1

'setTransform' просто работает, я использовал это много раз, в основном ваша' Matrix' вычисляется неправильно. – pskink

ответ

5

Благодаря @pskink для комментариев в сообщении я нашел решение с ним. наконец, я использовал матрицу для поворота видеоконтейнера (просмотр текстуры). метод, который дает 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 за вашу помощь, я отправил ответ, потому что вы ничего не отправляли, когда я сказал вам сделать это. В любом случае, если вы измените свое мнение, пожалуйста, опубликуйте ответ, и я проверю его правильный.

Надеюсь, это поможет большему количеству людей!

Смежные вопросы