iOS generating a video in the background task
Asked Answered
S

1

3

How would you go on creating a long video from images? It takes pretty long and the user will get bored to wait for it, so i'm thinking to generate the movie in background and notify the user after it finishes.

My app structure is like this, i have a UINavigationController that holds one controller with the simulated movie, just some images moving with CoreAnimation. Then i push a new controller that generates the movie. in controller2 i send request to controller1 to send me images with the frames to write on the movie (i generate images with CoreGraphics). This is almost blocking everything as it takes a lot of time and is continuous.

I read about background tasks and seems the only solution, but they do not last very long and might stop in the middle, generating 30sec of video takes about 6mins. I also can't declare my app as running in the background because it's not VoIP or other supported type.

Thanks for ideas.

Shig answered 23/4, 2013 at 7:25 Comment(2)
but this will burn battery fast, as this involves a lot of computations and RAM I/O.Knighthood
If the resulting movie worths they'll use it, if not no. Maybe some improvements on speed can be done, right now is processing an image few times for each frame.Hokku
T
4

To my understanding you can do that, although your App will only be running for a limited amount of time, but depending on he size of your video it can be sufficient. In fact I do exactly this on my animation authoring app idAnimate - Animating on the iPad with the touch of a finger. To my knowledge the app will be granted something around 10 minutes to complete the task, which can be sufficient. Should you app require additional time, you might want to look into how to optimise your video rendering algorithm, reduce the video quality or something.

Anyway here is a bit of code of how I do this assuming you use AVAssetWriter to generate the video: First you have to make the call to get a background permission, and to provide a block for what to do when your time is complete (background task expiration handler):

UIApplication *app = [UIApplication sharedApplication];

_backgroundRenderingID = [app beginBackgroundTaskWithExpirationHandler:^{
    [app endBackgroundTask:_backgroundRenderingID];
    _backgroundRenderingID = UIBackgroundTaskInvalid;
}];

After that you can start rendering your video:

videoWriter = [[AVAssetWriter alloc] initWithURL:
               [NSURL fileURLWithPath:self.moviePath] fileType:AVFileTypeMPEG4
                                           error:&error];
NSParameterAssert(videoWriter);
...

And when you are done make sure you let the OS know that your task legible for the background is completed:

 [[UIApplication sharedApplication] endBackgroundTask:_backgroundRenderingID];

I hope that helped.

Triceps answered 23/4, 2013 at 9:1 Comment(4)
Thanks, yes this works. Just need to see what i'll do if the process takes more than 10mins, maybe to put it on pause.Hokku
Dont forget to accept the answer if it worked for you, so that the next person that searches for it can know right away that its a good solution.Triceps
Yes. Btw, i tried your app just to compare the speed, i think you need to work more on the user interface, i hardly knew what to do and couldn't find the export function anyway. Today i just finished my app and found some ways to improve speed, instead of generating images, resizing, flipping, layering and all that stuffs, i just captured the resulting image displayed in a UIView and is much faster, almost realtime. The problem of the allowed 10mins to run in the background is still a problem, i hope none wants to create videos so long.Hokku
Thanks for the feedback, I'm glad you found a way to optimise your code.Triceps

© 2022 - 2024 — McMap. All rights reserved.