Android的VideoView方向变化与缓冲视频 [英] Android VideoView orientation change with buffered video

查看:349
本文介绍了Android的VideoView方向变化与缓冲视频的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想基本上复制在Android市场上最新的YouTube应用程序的功能。观看视频时有两个不同的布局,一个在纵向它提供了额外的信息,以及一个景观,它提供了视频的全屏视图。

I'm trying to essentially replicate the functionality of the latest YouTube app in the Android marketplace. When watching a video there's two separate layouts, one in portrait which provides additional info, and one in landscape which provides a full screen view of the video.


在纵向模式下的 YouTupe应用


YouTupe app in portrait mode


在横向模式下的 YouTube应用程序


YouTube app in landscape mode

(很抱歉的照片的随机性,但他们是第一批图片,我能找到实际的布局)

(Sorry for the randomness of the photos, but they were the first pics I could find of the actual layout)

这是pretty的容易做正常 - 只是指定布局,土地备用布局,一切都会好的。该YouTube应用程序确实非常出色的事情(我想要复制)是对的方向变化,视频继续播放,并且没有重新缓冲从此开始。

This is pretty easy to do normally - just specify an alternate layout in layout-land and all will be good. The thing that the YouTube app does really well (and what I'm trying to replicate) is that on orientation change, the video continues playing and doesn't have to re-buffer from the beginning.

我已经想通了,覆盖onConfigurationChange(),并设定新的LayoutParameters可以让我调整视频,而不必强制rebuffer - 但是旋转屏幕多次视频时会随机扩展到不同的宽度/高度。我试着做各种无效的()调用的VideoView,试图父RelativeLayout的容器调用RequestLayout()和只是想尽可能多的不同的事情,我可以,但我似乎无法得到它的正常工作。任何意见将大大AP preciated!

I've figured out that overriding onConfigurationChange() and setting new LayoutParameters will allow me to resize the video without forcing a rebuffer - however the video will randomly scale to different widths/heights when rotating the screen multiple times. I've tried doing all sorts of invalidate() calls on the VideoView, tried calling RequestLayout() on the parent RelativeLayout container and just trying as many different things as I can, but I can't seem to get it to work properly. Any advice would be greatly appreciated!

下面是我的code:

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        questionText.setVisibility(View.GONE);
        respond.setVisibility(View.GONE);
        questionVideo.setLayoutParams(new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
    } else {
        questionText.setVisibility(View.VISIBLE);
        respond.setVisibility(View.VISIBLE);
        Resources r = getResources();
        int height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 150.0f, r.getDisplayMetrics());
        questionVideo.setLayoutParams(new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT, height));
    }
}

编辑:我发现在logcat中,来了的时候,我的视频旋转,这似乎是罪魁祸首一些有趣的输出 - 虽然我不知道如何解决它:

I've discovered in logcat some interesting output that comes up when my video is rotated which seems to be the culprit - although I have no idea how to fix it:

logcat的输出调整适当的时候(占据整个窗口)

注意H = 726

12-13 15:37:35.468  1262  1270 I ActivityManager: Config changed: { scale=1.0 imsi=310/4 loc=en_US touch=3 keys=1/1/2 nav=1/1 orien=2 layout=34 uiMode=17 seq=210}
12-13 15:37:35.561  1262  1268 I TIOverlay: Position/X0/Y76/W480/H225
12-13 15:37:35.561  1262  1268 I TIOverlay: Adjusted Position/X1/Y0/W403/H225
12-13 15:37:35.561  1262  1268 I TIOverlay: Rotation/90
12-13 15:37:35.561  1262  1268 I Overlay : v4l2_overlay_set_position:: w=480 h=224
12-13 15:37:35.561  1262  1268 I Overlay : v4l2_overlay_set_position:: w=402 h=726
12-13 15:37:35.561  1262  1268 I Overlay : dumping driver state:
12-13 15:37:35.561  1262  1268 I Overlay : output pixfmt:
12-13 15:37:35.561  1262  1268 I Overlay : w: 432
12-13 15:37:35.561  1262  1268 I Overlay : h: 240
12-13 15:37:35.561  1262  1268 I Overlay : color: 7
12-13 15:37:35.561  1262  1268 I Overlay : UYVY
12-13 15:37:35.561  1262  1268 I Overlay : v4l2_overlay window:
12-13 15:37:35.561  1262  1268 I Overlay : window l: 1 
12-13 15:37:35.561  1262  1268 I Overlay : window t: 0 
12-13 15:37:35.561  1262  1268 I Overlay : window w: 402 
12-13 15:37:35.561  1262  1268 I Overlay : window h: 726

调整不正确时 logcat的输出(占据全屏的小部分)

注意H = 480

12-13 15:43:00.085  1262  1270 I ActivityManager: Config changed: { scale=1.0 imsi=310/4 loc=en_US touch=3 keys=1/1/2 nav=1/1 orien=2 layout=34 uiMode=17 seq=216}
12-13 15:43:00.171  1262  1268 I TIOverlay: Position/X0/Y76/W480/H225
12-13 15:43:00.171  1262  1268 I TIOverlay: Adjusted Position/X138/Y0/W266/H225
12-13 15:43:00.171  1262  1268 I TIOverlay: Rotation/90
12-13 15:43:00.179  1262  1268 I Overlay : v4l2_overlay_set_position:: w=480 h=224
12-13 15:43:00.179  1262  1268 I Overlay : v4l2_overlay_set_position:: w=266 h=480
12-13 15:43:00.179  1262  1268 I Overlay : dumping driver state:
12-13 15:43:00.179  1262  1268 I Overlay : output pixfmt:
12-13 15:43:00.179  1262  1268 I Overlay : w: 432
12-13 15:43:00.179  1262  1268 I Overlay : h: 240
12-13 15:43:00.179  1262  1268 I Overlay : color: 7
12-13 15:43:00.179  1262  1268 I Overlay : UYVY
12-13 15:43:00.179  1262  1268 I Overlay : v4l2_overlay window:
12-13 15:43:00.179  1262  1268 I Overlay : window l: 138 
12-13 15:43:00.179  1262  1268 I Overlay : window t: 0 
12-13 15:43:00.179  1262  1268 I Overlay : window w: 266 
12-13 15:43:00.179  1262  1268 I Overlay : window h: 480

也许有人知道'覆盖'是,为什么它没有得到正确的高度值?

Maybe someone knows what 'Overlay' is and why it's not getting the correct height value?

推荐答案

我能够缩小问题在VideoView类onMeasure功能。通过创建一个子类并覆盖onMeasure功能,我能得到所期望的功能。

I was able to narrow down the problem to the onMeasure function in the VideoView class. By creating a child class and overriding the onMeasure function, I was able to get the desired functionality.

public class VideoViewCustom extends VideoView {

    private int mForceHeight = 0;
    private int mForceWidth = 0;
    public VideoViewCustom(Context context) {
        super(context);
    }

    public VideoViewCustom(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public VideoViewCustom(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

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

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        Log.i("@@@@", "onMeasure");

        setMeasuredDimension(mForceWidth, mForceHeight);
    }
}

然后,我的活动里面我只是做了以下内容:

Then inside my Activity I just did the following:

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);

    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

        questionVideo.setDimensions(displayHeight, displayWidth);
        questionVideo.getHolder().setFixedSize(displayHeight, displayWidth);

    } else {
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN, WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);

        questionVideo.setDimensions(displayWidth, smallHeight);
        questionVideo.getHolder().setFixedSize(displayWidth, smallHeight);

    }
}

该行:

questionVideo.getHolder().setFixedSize(displayWidth, smallHeight);

是为了使这项工作的关键。如果你的setDimensions称没有这个人,视频仍然不会调整。

is key in order to make this work. If you do the setDimensions call without this guy, the video still will not resize.

您需要做的唯一的另一件事是确保你调用setDimensions()中的onCreate()方法内以及和您的视频不会启动缓冲的视频不会被设置为利用任意大小的表面

The only other thing you need to do is ensure that you call setDimensions() inside the onCreate() method as well or your video will not start buffering as the video won't be set to draw on a surface of any size.

// onCreate()
questionVideo.setDimensions(initialWidth, initialHeight); 

最后一个的一部分 - 如果你发现自己想知道为什么VideoView不调整轮换,你需要确保你调整大小的尺寸为完全等于可见区域或小于它。我有我在那里的VideoView的宽/高设置到整个显示器大小的时候我仍然在屏幕上的通知栏/标题栏一个真正的大问题,这是不调整的VideoView的。只需去除通知栏和标题栏解决了问题。

One last key part - if you ever find yourself wondering why the VideoView isn't resizing on rotation, you need to ensure the dimensions you're resizing to are either exactly equal to the visible area or less than it. I had a really big problem where I was setting the VideoView's width/height to the entire display size when I still had the notification bar/title bar on the screen and it was not resizing the VideoView at all. Simply removing the notification bar and title bar fixed the problem.

希望这可以帮助别人的未来!

Hopefully this helps someone in the future!

这篇关于Android的VideoView方向变化与缓冲视频的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆