Codename One - Zoom, center and crop a video to force it to occupy all the screen

人走茶凉 提交于 2019-12-23 02:21:19

问题


I have an intro video in the center of a BorderLayout with the option BorderLayout.CENTER_BEHAVIOR_TOTAL_BELOW. In the top I have a logo, in the south I have login buttons.

I write code similar to the following one, that chooses the right video according the rotation of the device. I tested that the video will be automatically zoomed to the available space: in the smartphones that I tested (Android and iPhone models), the video covers all the screen area (because the video length and height are proportional to the screen length and height). That's good, it's exactly what I want.

However, probably there are smartphones with different screen size ratio from the ones that I tested. Moreover, all the tablets have different screen size ratio from the smartphones.

I need that the video will ALWAYS occupy all the screen area. If necessary, it should be automatically zoomed, centered and cropped to occupy all the screen.

I didn't find in the Codename One API what I need to implement this use case. What code can I use? My target devices are Android and iOS devices (smartphones and tablets).

Example of code:

    Form hi = new Form("Hi World", new BorderLayout(BorderLayout.CENTER_BEHAVIOR_TOTAL_BELOW));

    disableToolbar(hi);

    introVideoMP4 = "/intro-landscape.mp4";
    if (Display.getInstance().isPortrait()) {
        introVideoMP4 = "/intro-portrait.mp4";
    }
    MediaPlayer introVideo = new MediaPlayer();
    try {
        InputStream videoInputStream = Display.getInstance().getResourceAsStream(getClass(), introVideoMP4);
        introVideo.setDataSource(videoInputStream, "video/mp4", () -> {
            introVideo.getMedia().setTime(0);
            introVideo.getMedia().play();
        });
        introVideo.setHideNativeVideoControls(true);
        introVideo.hideControls();
        introVideo.setAutoplay(true);
        hi.add(BorderLayout.CENTER, introVideo);
    } catch (Exception err) {
        Log.e(err);
    }

    hi.addOrientationListener(l -> {
        introVideoMP4 = "/intro-landscape.mp4";
        if (Display.getInstance().isPortrait()) {
            introVideoMP4 = "/intro-portrait.mp4";
        }
        try {
            InputStream videoInputStream = Display.getInstance().getResourceAsStream(getClass(), introVideoMP4);
            introVideo.setDataSource(videoInputStream, "video/mp4", () -> {
                introVideo.getMedia().setTime(0);
                introVideo.getMedia().play();
            });
        } catch (Exception err) {
            Log.e(err);
        }
    });
    hi.add(BorderLayout.NORTH, new Label("My App"));
    Button myButton = new Button("Tap me!");
    myButton.addActionListener(l -> {
        Log.p("myButton tapped");
    });
    hi.add(BorderLayout.SOUTH, myButton);
    hi.show();

回答1:


Usually sites generate video downloads/streams based on the device proportions on the server (using tools such as ffmpeg. Then deliver a video with the right aspect ratio, bitrate & format.

There is no builtin functionality for cropping the video similar to "fit" scale in Codename One.

However, if you are OK with the sides or top being cropped then you can probably create your own layout manager for the video component and position/size it based on your knowledge of the video dimensions and screen dimensions. Creating a layout manager is really easy, it's mostly just the work of implementing the layoutContainer method where you can set the X/Y/Width/Height of the component. See https://www.codenameone.com/blog/map-layout-update.html



来源:https://stackoverflow.com/questions/49311206/codename-one-zoom-center-and-crop-a-video-to-force-it-to-occupy-all-the-scree

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!