问题
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