Playing a video on Android

Hello,

I’m totally new to Corona.

I’m trying to run an .mp4 video for Android, in my game background. I searched and found out that this is only possible for iPhone.

I can’t play a .gif either.

So my last resort was image sequence put together with movieclip.

Is there any other option?

Hi @fkaktos,

For Android, the “media.playVideo()” API should work for you. Here’s the API documentation on it:

http://docs.coronalabs.com/api/library/media/playVideo.html

Best regards,

Brent Sorrentino

Note this function is asynchronous: any code that follows will
be executed. After that, the application code will continue to run on
iOS devices, but on Android devices the application will be suspended
until the video playback is complete.

This is what I get from the documentation.

What I want to do:

-I wanna loop the video, so that it plays all the time. It is a seamless video so looping it, is fine.

-I want my video to play on the background, while I play my game in the foreground (having buttons, images, other animation etc.)

-I want to manipulate my video like I would with an Image. Maybe store it in a variable, and change at will its position, width, height.

Something like that: http://docs.coronalabs.com/api/library/native/newVideo.html, but it says it is not supported for Android.

I found a workaround with movieclip http://www.coronalabs.com/blog/2010/06/01/improved-movieclip-library/, but I get a black screen, for some seconds before it is played (maybe loading those hundreds of frames? I don’t know). What happens during those seconds of black screen?

Anyone knows another workaround, based on what I wrote?

Hi @fkaktos,

What you describe presents some issues on iOS too. While you can use the more “flexible” native.newVideo() API on iOS, that object is in fact a “native” object, thus it resides above the OpenGL canvas. While you can manipulate it to some degree and even make it a physics-based object, it can’t be placed into the display hierarchy… and in your game description, you need it to reside behind almost everything else while your game plays in the foreground. Some of this might change in the revamped Graphics 2.0 engine that is being rolled out over the next several months, but at this time I don’t know the details in regards to video.

As for the “MovieClip” library, that is very outdated and essentially deprecated. You can still use it, but it’s not very efficient. The several seconds you must wait while it loads is, most likely, caused by the system loading in the hundreds of frames. Not only is that slow, but it will chew up so much texture memory, it might actually crash the app on some devices.

What are the pixel dimensions of this “video” object you want to create? You can make this into a sprite animation using image sheets, which would likely save you a ton of texture memory, but if you have hundreds of frames and the video is “full screen” in size, I fear that approach will be essentially impossible… just too much texture memory consumed.

Best regards,

Brent

What are the pixel dimensions of this “video” object you want to create?
You can make this into a sprite animation using image sheets, which
would likely save you a ton of texture memory, but if you have hundreds
of frames and the video is “full screen” in size, I fear that approach
will be essentially impossible… just too much texture memory consumed.

Sadly, this is the case. I want it to be full screen 480x360. The whole sequence is 1,2 MB big. Do you think that this is too much? I tried to test lowering the quality to 500 KB just to see the response. The black screen wait time is the same.

I will test sprite animation. But I was wondering: Can I have a “loading” screen before I enter my activity (or whatever it is called in Corona Storyboard, I’m still reading tutorials and hasn’t reached activity handling yet), so that at least I have something the user can look at for those few seconds, instead of just a blank screen?

Thank you for your interest commenting on my issue!

Hi @fkaktos,

Sure, you can do a “loading screen”… just build it outside of Storyboard, then clear it when your “core scene” loads.

But what I’m concerned about with your “video” in sprite format (or MovieClip) is texture memory. If you consider each frame at 480x360, that will round UP to the next power-of-two texture size of 512x512. Multiply that by the standard equation…

512×512 (pixels) × 4 (bytes) = 1,048,576 bytes = 1 MB

…and you can see that each frame takes up 1 MB of texture memory. Multiply that by hundreds of frames (let’s just say 200) and you suddenly have 200 MB of texture memory occupied just for the video… that being in addition to any other game artwork and assets. The texture memory varies from device to device, but if you exceed it, the app will usually crash or simply not load at all.

See the section on “Conserving Texture Memory” here:

http://docs.coronalabs.com/guide/basics/optimization/index.html#texturemem

Now, if you pack all of these frames into an image sheet, you’ll save some space… for example, you could put 4 of these frames across a row and 5 rows down, for a total of 20 frames on a sheet, and the dimensions would be:

480 x 4 = 1920 pixels wide

360 x 5 = 1800 pixels high

This would result in an image sheet in the power-of-two range of 2048x2048, which is 16 MB. That’s a tiny savings, since you’re getting “20 frames for the price of 16”, if that makes sense. :slight_smile:  But, it still adds up quickly. And yes, I know you have more than 20 total frames, but you can assemble multiple image sheets and have a single sprite pull frames from them.

Still, the texture memory is a definite concern. However, if you can cleverly compact these onto image sheets, and maybe make the frames 80-90% of your intended size (and then scale them up in the app, which probably wouldn’t result in too much loss in quality), you might be able to pull this off.

Any other questions, just let me know.

Brent

I made a sprite sheet with my video frames being 120x90, and rescaled it to 480x360 within my man.lua. The wait time was solved, now it opens instantly. Also the quality of the scaled up sequence is not that bad.

So, I mark this thread as solved, but I have one extra question:

Do I have to always think about texture memory as PoT? Meaning that what matters is the resolution of the file and not the disk memory it occupies? Does lower image file size on disk, has an impact at all on texure memory? And what about the trasparency in a .png? Do transparent pixels have 4 channels as well?

Hi @fkaktos,

Yes, it’s really important to keep texture memory in mind. While the sheer “file size” of images will impact the size of your compiled app, it’s texture memory that will impact performance if you get near to the limit (it will either perform intolerably slow, or crash/fail to load outright). Transparency still matters, because each “bit” is 4-depth (R,G,B,A).

So, long story short, it’s very important to mind texture memory, and if you have large images that might just exceed a high PoT value like 2048, it’s smart to scale them down (in the core image) to 2048 or less, then scale them back up 5-10% in your code… that will save you 4x the texture memory for that object, and the visual difference to the end user is probably minimal.

Also, remember to always re-use textures if possible. Corona allows you to tint objects using “setFillColor()”, so you can presumably make a “white apple” graphic and tint it to green, red, blue, purple, etc. in code. You can also apply blend modes to images (additive, multiply, screen) for nice effects, and there are more modes coming in Graphics 2.0.

http://www.coronalabs.com/blog/2012/10/30/creative-effects-using-blend-modes/

Finally, if you’re working on big characters/sprites, consider assembling them from several small pieces instead of making a giant sprite with dozens of full-size frames. Or, consider animating just the necessary part, like “eyes blinking” as a separate sprite overlaying a “face” image. There are many tricks/tactics like this which will help you stay below the crucial limit of texture memory.

Brent

Hi @fkaktos,

For Android, the “media.playVideo()” API should work for you. Here’s the API documentation on it:

http://docs.coronalabs.com/api/library/media/playVideo.html

Best regards,

Brent Sorrentino

Note this function is asynchronous: any code that follows will
be executed. After that, the application code will continue to run on
iOS devices, but on Android devices the application will be suspended
until the video playback is complete.

This is what I get from the documentation.

What I want to do:

-I wanna loop the video, so that it plays all the time. It is a seamless video so looping it, is fine.

-I want my video to play on the background, while I play my game in the foreground (having buttons, images, other animation etc.)

-I want to manipulate my video like I would with an Image. Maybe store it in a variable, and change at will its position, width, height.

Something like that: http://docs.coronalabs.com/api/library/native/newVideo.html, but it says it is not supported for Android.

I found a workaround with movieclip http://www.coronalabs.com/blog/2010/06/01/improved-movieclip-library/, but I get a black screen, for some seconds before it is played (maybe loading those hundreds of frames? I don’t know). What happens during those seconds of black screen?

Anyone knows another workaround, based on what I wrote?

Hi @fkaktos,

What you describe presents some issues on iOS too. While you can use the more “flexible” native.newVideo() API on iOS, that object is in fact a “native” object, thus it resides above the OpenGL canvas. While you can manipulate it to some degree and even make it a physics-based object, it can’t be placed into the display hierarchy… and in your game description, you need it to reside behind almost everything else while your game plays in the foreground. Some of this might change in the revamped Graphics 2.0 engine that is being rolled out over the next several months, but at this time I don’t know the details in regards to video.

As for the “MovieClip” library, that is very outdated and essentially deprecated. You can still use it, but it’s not very efficient. The several seconds you must wait while it loads is, most likely, caused by the system loading in the hundreds of frames. Not only is that slow, but it will chew up so much texture memory, it might actually crash the app on some devices.

What are the pixel dimensions of this “video” object you want to create? You can make this into a sprite animation using image sheets, which would likely save you a ton of texture memory, but if you have hundreds of frames and the video is “full screen” in size, I fear that approach will be essentially impossible… just too much texture memory consumed.

Best regards,

Brent

What are the pixel dimensions of this “video” object you want to create?
You can make this into a sprite animation using image sheets, which
would likely save you a ton of texture memory, but if you have hundreds
of frames and the video is “full screen” in size, I fear that approach
will be essentially impossible… just too much texture memory consumed.

Sadly, this is the case. I want it to be full screen 480x360. The whole sequence is 1,2 MB big. Do you think that this is too much? I tried to test lowering the quality to 500 KB just to see the response. The black screen wait time is the same.

I will test sprite animation. But I was wondering: Can I have a “loading” screen before I enter my activity (or whatever it is called in Corona Storyboard, I’m still reading tutorials and hasn’t reached activity handling yet), so that at least I have something the user can look at for those few seconds, instead of just a blank screen?

Thank you for your interest commenting on my issue!

Hi @fkaktos,

Sure, you can do a “loading screen”… just build it outside of Storyboard, then clear it when your “core scene” loads.

But what I’m concerned about with your “video” in sprite format (or MovieClip) is texture memory. If you consider each frame at 480x360, that will round UP to the next power-of-two texture size of 512x512. Multiply that by the standard equation…

512×512 (pixels) × 4 (bytes) = 1,048,576 bytes = 1 MB

…and you can see that each frame takes up 1 MB of texture memory. Multiply that by hundreds of frames (let’s just say 200) and you suddenly have 200 MB of texture memory occupied just for the video… that being in addition to any other game artwork and assets. The texture memory varies from device to device, but if you exceed it, the app will usually crash or simply not load at all.

See the section on “Conserving Texture Memory” here:

http://docs.coronalabs.com/guide/basics/optimization/index.html#texturemem

Now, if you pack all of these frames into an image sheet, you’ll save some space… for example, you could put 4 of these frames across a row and 5 rows down, for a total of 20 frames on a sheet, and the dimensions would be:

480 x 4 = 1920 pixels wide

360 x 5 = 1800 pixels high

This would result in an image sheet in the power-of-two range of 2048x2048, which is 16 MB. That’s a tiny savings, since you’re getting “20 frames for the price of 16”, if that makes sense. :slight_smile:  But, it still adds up quickly. And yes, I know you have more than 20 total frames, but you can assemble multiple image sheets and have a single sprite pull frames from them.

Still, the texture memory is a definite concern. However, if you can cleverly compact these onto image sheets, and maybe make the frames 80-90% of your intended size (and then scale them up in the app, which probably wouldn’t result in too much loss in quality), you might be able to pull this off.

Any other questions, just let me know.

Brent

I made a sprite sheet with my video frames being 120x90, and rescaled it to 480x360 within my man.lua. The wait time was solved, now it opens instantly. Also the quality of the scaled up sequence is not that bad.

So, I mark this thread as solved, but I have one extra question:

Do I have to always think about texture memory as PoT? Meaning that what matters is the resolution of the file and not the disk memory it occupies? Does lower image file size on disk, has an impact at all on texure memory? And what about the trasparency in a .png? Do transparent pixels have 4 channels as well?

Hi @fkaktos,

Yes, it’s really important to keep texture memory in mind. While the sheer “file size” of images will impact the size of your compiled app, it’s texture memory that will impact performance if you get near to the limit (it will either perform intolerably slow, or crash/fail to load outright). Transparency still matters, because each “bit” is 4-depth (R,G,B,A).

So, long story short, it’s very important to mind texture memory, and if you have large images that might just exceed a high PoT value like 2048, it’s smart to scale them down (in the core image) to 2048 or less, then scale them back up 5-10% in your code… that will save you 4x the texture memory for that object, and the visual difference to the end user is probably minimal.

Also, remember to always re-use textures if possible. Corona allows you to tint objects using “setFillColor()”, so you can presumably make a “white apple” graphic and tint it to green, red, blue, purple, etc. in code. You can also apply blend modes to images (additive, multiply, screen) for nice effects, and there are more modes coming in Graphics 2.0.

http://www.coronalabs.com/blog/2012/10/30/creative-effects-using-blend-modes/

Finally, if you’re working on big characters/sprites, consider assembling them from several small pieces instead of making a giant sprite with dozens of full-size frames. Or, consider animating just the necessary part, like “eyes blinking” as a separate sprite overlaying a “face” image. There are many tricks/tactics like this which will help you stay below the crucial limit of texture memory.

Brent

I’m looking into Corona for an e-book project similar to Morris Lessmore, which uses lots of video clips. The native video api would do exactly what I want, but it’s not supported on Android. Should I expect the Android implementation to catch up to iOS in, say, the next year?

gladstein - yes, in the next year we will definitely catch up on Android video. I hesitate to use the word “definitely” because you never know what can happen, but I’m using it here because this is an important feature and we do intend to cover it.

I’m looking into Corona for an e-book project similar to Morris Lessmore, which uses lots of video clips. The native video api would do exactly what I want, but it’s not supported on Android. Should I expect the Android implementation to catch up to iOS in, say, the next year?

gladstein - yes, in the next year we will definitely catch up on Android video. I hesitate to use the word “definitely” because you never know what can happen, but I’m using it here because this is an important feature and we do intend to cover it.