native.newVideo() in full screen, whatever device resolution ?

I’m trying to set a video, called with native.newVideo(), in fullscreen mode. Unfortunately, depending on screen devices, it’s not. On some devices, there are black margin at the top and bottom.

Here’s the code used :

local video = native.newVideo( display.contentCenterX, display.contentCenterY, display.contentWidth, display.contentHeight) video:load("video/introduction.mp4")

So, I’m creating the video object, loading the video. At this point, the video works fine, except I’ve got black margins on some devices. 

Then, I’m trying to resize the video so that it fills everything in height, while space stuffs would be off-screen. That’s why I’m applying …

video.height = display.contentHeight + math.abs(display.screenOriginY)\*2

And then, because I want the video to be resized proportionally, I’m adding this :

video.xScale = video.yScale

… but it doesn’t work. And this does work if it’s applied to an image (for exemple).

So, is it actually possible to resize a video ? 

I’ve just made a new test, because I’m not sure the previous snippet code was right…

My intend is to put an image, resize it so it fills the whole screen, get its dimensions, loading the video and applying to it the image dimensions…

local \_W = display.contentWidth\*0.5 local \_H = display.contentHeight\*0.5 local redRect local yRatio -- Creating an image that's gonna be fullScreen, whatever the device resolution is redRect = display.newImage("images/redrect.png") redRect.x = \_W redRect.y = \_H redRect.height = display.contentHeight + math.abs(display.screenOriginY)\*2 -- I retrieve the "vertical ratio" yRatio = redRect.height/640 --I apply the vertical ratio to the width redRect.xScale = yRatio

The image cover the whole screen space, while some part of it on its side are off-screen. Which is what I do want for the video.

Then, I try to load a video, by applying the dimensions of the previous image. It should work, right ?

-- I create the video object and load the video local video = native.newVideo( display.contentCenterX, display.contentCenterY, redRect.width, redRect.height) video:load("video/introduction.mp4")

Nope, it doesn’t work. The video seems to be at its original ratio, and worst : its y coordinate is not 0 (it should be since I didn’t touch it). The video seems to be set at : 0 - display.screenOriginY.

Does anybody know how I could fix this ?

The video should play at whatever format it was shot at.  If you play a typical 16:9 video on an iPad you’re going to get black letterbox bars on the top and bottom.  Try to play a standard def (4:3) video on a wide screen phone and you’re going to get black bars on the sides.  I don’t believe you have any ability to scale the video and I don’t think your viewers would like part of the video cut off (which would happen if you scaled the video).

Rob

Hi Rob,

I see.  But isn’t native.newVideo() supposed to be used *almost* like any other display object (“that can be moved or rotated”)?

I made a test and I actually managed to set the height  of the video to 20px. It did work : the video was really small. And the thing is that it was actually scaled down proportionally. But there’s maybe a restriction preventing me to “upscale” it ?

Good news ! I eventually managed to do it. In short : yes, it’s possible to change scale property of a native.newVideo() (xScale, and yScale).

So, I started from scratch, to be sure I was doing it right. And because I don’t wanna struggle too much (english is not my native language…), I’ll use some images.

Setting a native.newVideo() to full screen, for every resolutions :

What I intend to get is a video played in fullscreen, stretched so that it fills all the screen space. For every device resolutions. It’s not the best solution, since it means that part of the video will be off-screen. But in my case, it’s not a problem (you just have to produce a video with that in mind). But this can be very usefull if you’re planning to do some “cinematic transitions” in your game.

First, here is what you’ll need :

visuel1.png

The image is used to define the final dimensions of the video (video.mov). Its size must be the same as the video, which is 1136x640 in my case, or at least, have the same format ratio. And in my case, in my config.lua file, I’m setting the scale as “letterbox”. It probably works for “zoomEven” by changing a few lines, but I haven’t tested it.

At first, I just load the image, put it at the center of the screen, and resize it so it fills the whole screen. But instead of just setting its width and height respectively to display.contentWidth and display.contentHeight, I do it proportionnaly so it doesn’t get distorted.

-- Create the image, memorize its original width & height, set it at the center local image = display.newImage("image.png") local originalWidth = image.width local originalHeight = image.height image.x = display.contentWidth\*0.5 image.y = display.contentHeight\*0.5 -- Since the scaling is set to "letterbox", we first set the height to fill the vertical space, -- and then we apply the same horizontal scale as the vertical scale image.height = display.contentHeight + math.abs(display.screenOriginY)\*2 local ratio = originalHeight/originalWidth image.xScale = ratio

As you can see, I’m setting the image heights so that it takes the whole content area. But because we’re using the “letterbox” scaling, and because of the video format, we also have to add the content area, from the bottom AND the top (which is math.abs(display.screenOrigin)*2).

visuel3.png

As you can see, the image is now covering the whole screen. We’re gonna use the picture dimensions to do the same thing to the video. I don’t know why, but I didn’t manage to do it directly without this image (although in theory, it should be the same thing).

-- Creating the new video object local video = native.newVideo(\_W, \_H, image.width, image.height) video:load("video.mov")

visuel4.png

-- Setting the final video size video.xScale = image.xScale video.yScale = image.yScale 

… And that’s it. Using native.newVideo(_W, _H, image.xScale, image.yScale) should work, but in my case it didn’t work. Or at least, because I tested several ways to do it, I’m not sure what was causing me trouble anymore.

And so it is, we’ve got a video, in full screen, cropped if needed !

visuel5.png

Notes :

  • native.newVdeo() : from what I’ve tested, you can change several properties : x, y, xScale, yScale for sure. anchorX and anchorY seemed to have some effect, but it looked buggy. I may have done something wrong. As written in the docs, rotation doesn’t work on Android. You can even use transition.to() on a native.newVideo. It doesn’t seem to use a lot of resources !
  • If your video format is “portrait” and not “landscape”, you should probably set the image.width first, then get the ratio, and apply it to its height then.
  • There’s a bug caused by Android Lolipop : when you use the multitask function, your app gets minimized (it seems to use some kind of internal mask). The video seems to “move” and stays shifted if you go back to your app. I haven’t tried to simply put it back at the center yet (setting its x and y to _W and _H) once the app resumes.

Final disclaimer :

I’m definitely not a pro ! I’m still learning and I’ve written this just in case anyone else wanted to do the same thing. I may have written wrong stuff, so, test yourself and if I’m wrong, feel free to correct me ! It might even be easier if you manage to get rid of the image reference. I’m using it because… it’s easier for me (I’m more a “visual guy”).

I’ve just made a new test, because I’m not sure the previous snippet code was right…

My intend is to put an image, resize it so it fills the whole screen, get its dimensions, loading the video and applying to it the image dimensions…

local \_W = display.contentWidth\*0.5 local \_H = display.contentHeight\*0.5 local redRect local yRatio -- Creating an image that's gonna be fullScreen, whatever the device resolution is redRect = display.newImage("images/redrect.png") redRect.x = \_W redRect.y = \_H redRect.height = display.contentHeight + math.abs(display.screenOriginY)\*2 -- I retrieve the "vertical ratio" yRatio = redRect.height/640 --I apply the vertical ratio to the width redRect.xScale = yRatio

The image cover the whole screen space, while some part of it on its side are off-screen. Which is what I do want for the video.

Then, I try to load a video, by applying the dimensions of the previous image. It should work, right ?

-- I create the video object and load the video local video = native.newVideo( display.contentCenterX, display.contentCenterY, redRect.width, redRect.height) video:load("video/introduction.mp4")

Nope, it doesn’t work. The video seems to be at its original ratio, and worst : its y coordinate is not 0 (it should be since I didn’t touch it). The video seems to be set at : 0 - display.screenOriginY.

Does anybody know how I could fix this ?

The video should play at whatever format it was shot at.  If you play a typical 16:9 video on an iPad you’re going to get black letterbox bars on the top and bottom.  Try to play a standard def (4:3) video on a wide screen phone and you’re going to get black bars on the sides.  I don’t believe you have any ability to scale the video and I don’t think your viewers would like part of the video cut off (which would happen if you scaled the video).

Rob

Hi Rob,

I see.  But isn’t native.newVideo() supposed to be used *almost* like any other display object (“that can be moved or rotated”)?

I made a test and I actually managed to set the height  of the video to 20px. It did work : the video was really small. And the thing is that it was actually scaled down proportionally. But there’s maybe a restriction preventing me to “upscale” it ?

Good news ! I eventually managed to do it. In short : yes, it’s possible to change scale property of a native.newVideo() (xScale, and yScale).

So, I started from scratch, to be sure I was doing it right. And because I don’t wanna struggle too much (english is not my native language…), I’ll use some images.

Setting a native.newVideo() to full screen, for every resolutions :

What I intend to get is a video played in fullscreen, stretched so that it fills all the screen space. For every device resolutions. It’s not the best solution, since it means that part of the video will be off-screen. But in my case, it’s not a problem (you just have to produce a video with that in mind). But this can be very usefull if you’re planning to do some “cinematic transitions” in your game.

First, here is what you’ll need :

visuel1.png

The image is used to define the final dimensions of the video (video.mov). Its size must be the same as the video, which is 1136x640 in my case, or at least, have the same format ratio. And in my case, in my config.lua file, I’m setting the scale as “letterbox”. It probably works for “zoomEven” by changing a few lines, but I haven’t tested it.

At first, I just load the image, put it at the center of the screen, and resize it so it fills the whole screen. But instead of just setting its width and height respectively to display.contentWidth and display.contentHeight, I do it proportionnaly so it doesn’t get distorted.

-- Create the image, memorize its original width & height, set it at the center local image = display.newImage("image.png") local originalWidth = image.width local originalHeight = image.height image.x = display.contentWidth\*0.5 image.y = display.contentHeight\*0.5 -- Since the scaling is set to "letterbox", we first set the height to fill the vertical space, -- and then we apply the same horizontal scale as the vertical scale image.height = display.contentHeight + math.abs(display.screenOriginY)\*2 local ratio = originalHeight/originalWidth image.xScale = ratio

As you can see, I’m setting the image heights so that it takes the whole content area. But because we’re using the “letterbox” scaling, and because of the video format, we also have to add the content area, from the bottom AND the top (which is math.abs(display.screenOrigin)*2).

visuel3.png

As you can see, the image is now covering the whole screen. We’re gonna use the picture dimensions to do the same thing to the video. I don’t know why, but I didn’t manage to do it directly without this image (although in theory, it should be the same thing).

-- Creating the new video object local video = native.newVideo(\_W, \_H, image.width, image.height) video:load("video.mov")

visuel4.png

-- Setting the final video size video.xScale = image.xScale video.yScale = image.yScale 

… And that’s it. Using native.newVideo(_W, _H, image.xScale, image.yScale) should work, but in my case it didn’t work. Or at least, because I tested several ways to do it, I’m not sure what was causing me trouble anymore.

And so it is, we’ve got a video, in full screen, cropped if needed !

visuel5.png

Notes :

  • native.newVdeo() : from what I’ve tested, you can change several properties : x, y, xScale, yScale for sure. anchorX and anchorY seemed to have some effect, but it looked buggy. I may have done something wrong. As written in the docs, rotation doesn’t work on Android. You can even use transition.to() on a native.newVideo. It doesn’t seem to use a lot of resources !
  • If your video format is “portrait” and not “landscape”, you should probably set the image.width first, then get the ratio, and apply it to its height then.
  • There’s a bug caused by Android Lolipop : when you use the multitask function, your app gets minimized (it seems to use some kind of internal mask). The video seems to “move” and stays shifted if you go back to your app. I haven’t tried to simply put it back at the center yet (setting its x and y to _W and _H) once the app resumes.

Final disclaimer :

I’m definitely not a pro ! I’m still learning and I’ve written this just in case anyone else wanted to do the same thing. I may have written wrong stuff, so, test yourself and if I’m wrong, feel free to correct me ! It might even be easier if you manage to get rid of the image reference. I’m using it because… it’s easier for me (I’m more a “visual guy”).