安卓系统支持视频缩放吗?

30

在Android中,使用VideoView播放视频,默认情况下视频会按照其编码分辨率来自适应地调整大小。是否可以通过设置缩放因子来强制Android将视频渲染为更小或更大的矩形?

7个回答

59

(我知道这是一个非常古老的问题,但有另一种控制尺寸的方式没有在这里描述,也许会对某些人有所帮助。)

您可以在布局中声明自己的MyVideoView类并编写自己的onMeasure()方法,以控制尺寸。以下是如何将视频拉伸到原始视图的尺寸:


public class MyVideoView extends VideoView {
 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  int width = getDefaultSize(0, widthMeasureSpec);
  int height = getDefaultSize(0, heightMeasureSpec);

  setMeasuredDimension(width, height);
 }
}

漂亮的干净解决方案,而且这是唯一一个真正有效的。 - Oliver Hausler
1
对我没用,我有720 * 480的视频,我试图在一个正方形视图上显示它,但视频长度被“压缩”了。 - Roee

12

如果要为VideoView设置"centerCrop"比例类型,则您的onMeasure()layout()方法可能如下所示:


public class CenterCropVideoView extends VideoView {
    private int leftAdjustment;
    private int topAdjustment;

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

        int videoWidth = getMeasuredWidth();
        int videoHeight = getMeasuredHeight();

        int viewWidth = getDefaultSize(0, widthMeasureSpec);
        int viewHeight = getDefaultSize(0, heightMeasureSpec);

        leftAdjustment = 0;
        topAdjustment = 0;
        if (videoWidth == viewWidth) {
            int newWidth = (int) ((float) videoWidth / videoHeight * viewHeight);
            setMeasuredDimension(newWidth, viewHeight);
            leftAdjustment = -(newWidth - viewWidth) / 2;
        } else {
            int newHeight = (int) ((float) videoHeight / videoWidth * viewWidth);
            setMeasuredDimension(viewWidth, newHeight);
            topAdjustment = -(newHeight - viewHeight) / 2;

        }
    }

    @Override
    public void layout(int l, int t, int r, int b) {
        super.layout(l + leftAdjustment, t + topAdjustment, r + leftAdjustment, b + topAdjustment);
    }
}

我在尝试播放视频时遇到了问题,VideoView首先缩放宽度以获取左侧调整,然后再缩放高度,因此原始的左侧调整设置为0。我通过将变量的初始化从类中删除并从方法内部删除leftAdjustment = 0; topAdjustment = 0;来解决了这个问题。感谢您提供的解决方案,这是一种很好的裁剪视频的方法,而不必使用TextureView API 14并失去兼容性。 - AntPachon
你应该将布局方法的行改为super.layout(l + leftAdjustment, t + topAdjustment, r - leftAdjustment, b - topAdjustment);。否则,它只会移动你的 vidoView,而不改变它的大小。 - rstk
我认为缩放是通过onMeasure()中的setMeasuredDimension()实现的。我在https://play.google.com/store/apps/details?id=ru.zenrus.android中使用了该代码,并且它有效。你有检查过你的建议吗? - FeelGood
这对我不起作用。我的VideoView只占屏幕的一半,我需要对视频进行缩放裁剪,但是这个解决方案只是最大化了视图,而没有裁剪视频。 - Konstantin Konopko

11
默认情况下,视频视图会自适应视频编码分辨率的大小。
在布局中,VideoView(或与MediaPlayer一起使用的SurfaceView)的尺寸将按您设置的大小显示。视频将以最大可能的尺寸播放,同时保持纵横比,在该空间内播放。
可以:将VideoView设置为所需的大小,Android将缩放以适合VideoView的尺寸。

1
厉害了,你知道有什么方法可以打破纵横比吗? - haseman
2
我应该补充说明,并非所有平台都能正确地执行此操作。例如,Droid Eris似乎会将视频缩放到其本机分辨率,随着视图的扩大而扩大。平台碎片化啊!! - haseman
我还发现,我可以打破视频视图的纵横比。我只需要等待视频开始播放,一旦视频视图重新调整大小,我就可以使用布局来修改视图大小。此时,我可以给它任何大小,它都会拉伸到所需的高度/宽度。 - haseman
1
@haseman:我发现HTC Desire 2.1版本也不能缩放视频(至少使用当前的代码),但其他设备如Nexus One,三星Galaxy S等都可以正常运行 - 这些设备同样也是运行在2.1版本上。 - Mathias Conradt

11

我发现当一个VideoView被放置在RelativeLayout中时,视频会拉伸高度和宽度以适应VideoView指定的高度和宽度(而不考虑视频的宽高比)。然而,当我将VideoView放置在FrameLayout中时,视频会拉伸高度和宽度直到匹配VideoView指定的高度或宽度之一(即不破坏宽高比)。很奇怪,但这就是我发现的情况!


3

我也在尝试实现这个目标,到目前为止这个方法还可以。思路是使用setLayoutParams来设置视频视图的大小。这只是一个简单的片段,但它提供了这个想法。请检查LayoutParams的行。

VideoView mVideoView = new VideoView(this);

//intermediate code

mVideoView.setVideoPath("/sdcard/VIDEO0007.3gp");
MediaController mController = new MediaController(this);
mVideoView.setMediaController(mController);
mController.setOnTouchListener(new View.OnTouchListener() {

public boolean onTouch(View v, MotionEvent event) {
    int width = mVideoView.getMeasuredWidth();
    int height = mVideoView.getMeasuredHeight();
    //we add 10 pixels to the current size of the video view every time you touch     
    //the media controller.
    LayoutParams params = new LinearLayout.LayoutParams(width+10, height+10);
    mVideoView.setLayoutParams(params);

    return true;
}
});

mVideoView.requestFocus();
mVideoView.start();

3

对于 FeelGoods 的答复。

如果没有 layout() 方法,“centerCrop” 比例类型更好,但是 VideoView 必须位于 FrameLayout 中。

@Override
public void layout(int l, int t, int r, int b) {
    super.layout(l + leftAdjustment, t + topAdjustment, r + leftAdjustment, b + topAdjustment);
}

0
大家好,我有一个想法,可以通过扩展VideoView来创建自己的VideoView类,这样你就可以随心所欲地进行操作。你需要在你的VideoView中创建一些方法。
public void setDimensions(int w, int h) {
    this.mForceHeight = h;
    this.mForceWidth = w;

}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    setMeasuredDimension(mForceWidth, mForceHeight);
}

为您的VideoView类创建自己的构造函数,并确保这些方法在您自己的videoview类中,然后将其用作Android默认videoview一样在xml和class文件中使用。

希望能帮到您。


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