S.J
S.J

Reputation: 3071

Need assistance regarding CMTimeMakeWithSeconds

I am trying to fetch all frames of video and converting and storing them as individual images. I am using this code in AV Foundation Programming Guide.

the code for getting multiple images is

CMTime firstThird = CMTimeMakeWithSeconds(durationSeconds/3.0, 600);
CMTime secondThird = CMTimeMakeWithSeconds(durationSeconds*2.0/3.0, 600);
CMTime end = CMTimeMakeWithSeconds(durationSeconds, 600);

this is hard coded, but I want to convert whole video. I know I can use for loop but what to do with this durationsecond means how can I use from begging to end to get all frames?

here is my attempt

for(float f=0.0; f<=durationSeconds; f++) {
        [times addObject:[NSValue valueWithCMTime:CMTimeMakeWithSeconds(durationSeconds, 600)]];
}

Upvotes: 0

Views: 2881

Answers (1)

nhgrif
nhgrif

Reputation: 62052

Any time you're about to write hundreds of lines of nearly identical code is probably a time where you need to be using a loop of some sort:

for (int currentFrame = 0; currentFrame < durationSeconds; ++currentFrame) {
    CMTime currentTime = CMTimeMakeWithSeconds(i, 600);
    // the rest of the code you need to create the image or whatever
}

That snippet will grab one frame per second. If you wanted to grab 30 frames per second, it'd look more like this:

const CGFloat framesPerSecond = 30.0;

for (int currentFrame = 0; currentFrame < (durationSeconds * framesPerSecond); ++currentFrame) {
    CMTime currentTime = CMTimeMakeWithSeconds(currentFrame/framesPerSecond, 600);
    // again, the code you need to create the image from this time
}

Just set the value of framesPerSecond to however many frames per second you want to capture.


As a disclaimer, I'm not completely familiar with this stuff, so a <= might be appropriate in the conditional statements here.


ADDENDUM: The code I've posted is only going to grab the timestamp for which to grab an image. The rest of the code should look something like this:

AVAsset *myAsset = // your asset here
AVAssetImageGenerator *imageGenerator = [[AVAssetImageGenerator alloc] initWithAsset:myAsset];

NSError *error;
CMTime actualTime;

CGImageRef currentImage = [imageGenerator copyCGImageAtTime:currentTime 
                                                 actualTime:&actualTime 
                                                      error:&error];

if (!error) {
    [someMutableArray addObject:[[UIImage alloc] initWithCGImage:currentImage]];
}

Upvotes: 1

Related Questions