2016-08-20 18 views
1

私は私のアプリケーションで動的にサイズを変更したいVideoViewを持っています。 VideoViewクラスを拡張することで、videoViewとvideoViewの両方のサイズを正しく変更することに成功しました。しかし、私は2つのサイズの間をより緩やかに移行したいと考えています。どうやってやるの?スケーリングアニメーションを試しましたが、VideoViewレイアウトのサイズが変更されても、ビデオ自体は拡大縮小されません。思考?すべてのヘルプははるかに高く評価されてVideoViewのサイズを変更するにはどうすればいいですか?

Animation scaling = new ScaleAnimation(1.0f, 0.2f, 1.0f, 0.2f); 
scaling.setDuration(2000); 
startAnimation(scaling); 

public class MyVideoView extends VideoView { 

    private int mForceHeight,mForceWidth; 
    private int mOrigWidth, mOrigHeight, mMinWidth, mMinHeight; 


    public MyVideoView(Context context) { 
     super(context); 
    } 

    /* Will cause inflator errors if not present */ 
    public MyVideoView(Context context, AttributeSet attrs){ 
     super(context, attrs); 
    } 

    public void setDimensions(int w, int h) { 
     this.mForceHeight = h; 
     this.mForceWidth = w; 
    } 

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

     if (mForceHeight != 0) 
      setMeasuredDimension(mForceWidth, mForceHeight); 
     else 
      super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
    } 


    public void setOrigDimens(int width, int height) { 
     mOrigWidth = width; 
     mOrigHeight = height; 

     mMinWidth = width/4; // My own decision for the small size 
     mMinHeight = height/4; 
    } 


    public void setSmallView() { 
     setNewViewSize(mMinWidth, mMinHeight); 
    } 


    public void setNormalView() { 
     setNewViewSize(mOrigWidth, mOrigHeight); 
    } 


    /* RESIZES THE VIEW */ 
    public void setNewViewSize(int width, int height) { 
     mForceWidth = width; 
     mForceHeight = height; 
     setDimensions(width, height); 
     getHolder().setFixedSize(width, height); 
    } 
} 

ここに私が試したスケーリングコードは次のとおりです。

は、ここに私のビデオクラスです!

答えて

0

最良の答えは、単に代わりにSurfaceView(VideoViewは、デフォルトでSurfaceViewを継承する)のTextureViewを使用することです。これを行うには、使用するコードは次のように:

activity_main.xmlであなたのTextureViewを定義します。

<TextureView 
    android:id="@+id/videoTexture" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent /> 

をごMainActivity.javaでは、以下の変数を宣言:あなたのonCreate()方法で次に

private MediaPlayer mMediaPlayer; 
private TextureView mVideoTextureView; 
private float mDisplayWidth; 
private float mDisplayHeight; 

を、それらを初期化します

mVideoTextureView =(TextureView) rootview.findViewById(R.id.videoTexture); 
mVideoTextureView.setSurfaceTextureListener(this); 

mMediaPlayer = new MediaPlayer(); 
loadNewMovie(); 

は、次のコードを使用し、MediaPlayerのに映画をロードするには:

private void updateTextureViewSize(int viewWidth, int viewHeight) { 

    RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(viewWidth,viewHeight); 

    // ANY OTHER RULES...EXAMPLE: 
    // params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); 

    mVideoTextureView.setLayoutParams(params); 
} 

それとも、このような変更をアニメーション化することができます

private void loadNewMovie() { 

    AssetFileDescriptor afd = this.getResources().openRawResourceFd(ID_OF_YOUR_MOVIE); 

    try { 

     // Set source 

     mMediaPlayer.reset(); 
     mMediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getDeclaredLength()); 
     mMediaPlayer.prepare(); 

     /* 
     // Gets the Height/Width of the video but does NOT include space 
     // taken up by black bars if the dimensions don't exactly fit the screen. 

     MediaMetadataRetriever metaRetriever = new MediaMetadataRetriever(); 
     metaRetriever.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength()); 
     String height = metaRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT); 
     String width = metaRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH); 
     mVideoHeight = Float.parseFloat(height); 
     mVideoWidth = Float.parseFloat(width); 
     */ 

     // Gets the size of the display in pixels (used for scaling) 

     Display display = getWindowManager().getDefaultDisplay(); 
     Point size = new Point(); 
     display.getSize(size); 

     mDisplayWidth = size.x; 
     mDisplayHeight = size.y; 

     // Play movie 

     if (currState == State.PLAYING) 
      mMediaPlayer.start(); 

     afd.close(); 
    } 
    catch (Exception e) { 
     Log.e("ERROR", "loadNewMovie: " + e.getMessage(), e); 
    } 

    mMediaPlayer.seekTo(DEFAULT_VIDEO_INIT_POSITION); 
} 

最後に、あなたのビデオは、次のコードを使用して瞬時に調整することができます。上記のコードで

private void animateTextureViewScaling(final float startScaleX, final float startScaleY, 
             final float endScaleX, final float endScaleY, 
             int duration) { 

    // Note: Can't just use .scaleX and .scaleY directly because it will only scale 
    // the video, not it's holder 

    mVideoTextureView.animate().setDuration(duration) 
     .setUpdateListener(new AnimatorUpdateListener() { 

      float value, scalingX, scalingY; 
      float changeXScale = startScaleX - endScaleX; 
      float changeYScale = startScaleY - endScaleY; 

      @Override 
      public void onAnimationUpdate(ValueAnimator animation) { 
       value = (Float) animation.getAnimatedValue(); 

       scalingX = (float) (startScaleX - changeXScale*value); 
       scalingY = (float) (startScaleX - changeYScale*value); 

       RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
         (int) (mDisplayWidth*scalingX), (int) (mDisplayHeight*scalingY)); 

       // ANY OTHER RULES...EXAMPLE: 
       // params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); 

       mVideoTextureView.setLayoutParams(params); 
      } 

     }).start(); 
} 

、私は私のビデオの元のサイズとしてmDisplayWidthloadNewVideo()で設定)を使用します。あなたは何でも好きなものを使うことができます。この

利点はTextureViewは(SurfaceViewができない)、アニメーション形質転換し、スケーリングすることができることです。

consは、TextureViewはハードウェア加速ウィンドウでのみ使用でき、SurfaceViewよりもはるかに多くのメモリ(約30%)を使用します。 1〜3フレームのレイテンシが発生することもあります。

+0

あなたはこのコードに欠かせない部分があります。(私は思う)。また、TextureViewを使用するようにMediaPlayerを設定する必要があります。おそらくSurfaceTextureListenerのonSurfaceTextureAvailableメソッドにあります。 –

1

私が見つけた1つの解決策は、ValueAnimatorを使用してサイズの比率を変更し、次にビデオを実際にサイズを変更するように更新リスナーを使用することです。しかし、それは非常に神経質だ:

ValueAnimator scaleDown = ValueAnimator.ofFloat(1, 0.25f); 
    scaleDown.setDuration(1000); 

    scaleDown.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 
     public void onAnimationUpdate(ValueAnimator animation) { 
      Float value = (Float) animation.getAnimatedValue(); 
      setNewViewSize(mOrigWidth*value, mOrigHeight*value); 
     } 
    }); 

    scaleDown.start(); 
関連する問題