安卓VideoView等比例缩放

22

在Android的VideoView中,是否有办法实现与ImageView.ScaleType.CENTER_CROP相同的效果?
也就是说,我希望我的VideoView播放视频时填充整个屏幕而不会失真。如果视频的宽高比和屏幕不完全匹配,则应进行裁剪而不是失真。
以下解决方案可以填充屏幕,但不能保持视频的宽高比: https://stackoverflow.com/a/6927300/1068656 而这个解决方案可以保持视频的宽高比,但无法填满整个屏幕(视频被缩放直到较长的一侧接触屏幕边缘,从而在两侧引入黑边): https://dev59.com/6W445IYBdhLWcg3w7urD#4855315

不,你需要手动设置它,你需要对你的SurfaceView和VideoView进行一些数学计算来调整预览大小。 - Daud Arfin
1
如果您的应用程序仅支持API 14及以上版本,则可以使用TextureView,然后使用此库-https://github.com/dmytrodanylyk/video-crop。 - oznus
此解决方案适用于CENTER_CROP或CENTER_INSIDE。https://dev59.com/6W445IYBdhLWcg3w7urD#53641686 - Carlitos
4个回答

16

在Android的VideoView中,有一种简单易行的方法可以实现与ImageView.ScaleType.CENTER_CROP相同的效果。

XML

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">

    <VideoView
        android:id="@+id/videoView"
        android:layout_width="@dimen/dimen_0dp"
        android:layout_height="@dimen/dimen_0dp"
        android:visibility="gone"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
在 Kotlin 中:
videoView.setOnPreparedListener { mediaPlayer ->
    val videoRatio = mediaPlayer.videoWidth / mediaPlayer.videoHeight.toFloat()
    val screenRatio = videoView.width / videoView.height.toFloat()
    val scaleX = videoRatio / screenRatio
    if (scaleX >= 1f) {
        videoView.scaleX = scaleX
    } else {
        videoView.scaleY = 1f / scaleX
    }
}

在JAVA中:

videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
      float videoRatio = mp.getVideoWidth() / (float) mp.getVideoHeight();
      float screenRatio = videoView.getWidth() / (float) 
      videoView.getHeight();
      float scaleX = videoRatio / screenRatio;
      if (scaleX >= 1f) {
          videoView.setScaleX(scaleX);
      } else {
          videoView.setScaleY(1f / scale);
      }
   }
});

这对我有用。希望这能帮助到别人。


15

虽然现在已经晚了,但是可能会对寻找同样问题的其他人有所帮助。以下答案保持了视频比例(videoProportion)。手机视图将裁剪掉videoview的额外部分。

private void setDimension() {
     // Adjust the size of the video
     // so it fits on the screen
     float videoProportion = getVideoProportion();
     int screenWidth = getResources().getDisplayMetrics().widthPixels;
     int screenHeight = getResources().getDisplayMetrics().heightPixels;
     float screenProportion = (float) screenHeight / (float) screenWidth;
     android.view.ViewGroup.LayoutParams lp = videoView.getLayoutParams();

     if (videoProportion < screenProportion) {
         lp.height= screenHeight;
         lp.width = (int) ((float) screenHeight / videoProportion);
     } else {
         lp.width = screenWidth;
         lp.height = (int) ((float) screenWidth * videoProportion);
     }
     videoView.setLayoutParams(lp);
 }

// This method gets the proportion of the video that you want to display.
// I already know this ratio since my video is hardcoded, you can get the  
// height and width of your video and appropriately generate  the proportion  
//    as :height/width 
private float getVideoProportion(){
  return 1.5f;
}

真的很好用,不需要再找其他的代码了。谢谢 Negi。 - parik dhakan
这个解决方案中存在一个问题 - 当在ViewPager中使用时,调整大小的视图会“溢出”到下一页,因为在竖屏模式下,横向视频会将VideoView设置为极宽。是否有一种方法可以在调整大小后进行中心裁剪? - galaxigirl
你可以将VideoView包装在一个具有页面尺寸的View中。 - Deepak Negi
这导致视频只显示左/上部分,不符合我的需求。为了显示中心部分,我添加了以下代码:videoView.translationX = -(lp.width - screenWidth) / 2f videoView.translationY = -(lp.height - screenHeight) / 2f - Sam Liddle

3

ConstraintLayout有一个名为app:layout_constraintDimensionRatio的属性,用于此目的。

<androidx.constraintlayout.widget.ConstraintLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <VideoView
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintDimensionRatio="4:3" <!-- w:h -->
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</ConstraintLayout>

请查看官方文档以获取更多详细信息。 点击此处

1

这里是根据视频大小调整视频 UI 的代码

 <androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_centerInParent="true"
    android:layout_marginStart="10dp"
    android:layout_marginTop="10dp"
    android:layout_marginEnd="10dp"
    android:layout_marginBottom="10dp">
    <VideoView
        android:id="@+id/videoPlayer"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        />
</androidx.constraintlayout.widget.ConstraintLayout>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接