Я не могу получить точный CMTime для генерации неподвижного изображения из 1,8-секундного видео - PullRequest
5 голосов
/ 29 апреля 2011

Каждый раз, когда я пытаюсь сгенерировать стоп-кадр из моего видео актива, он генерируется за время 0,000 .. секунд.Я могу видеть это из моего сообщения журнала.Хорошо, что я могу получить изображение в момент времени 0,000 .. для отображения в UIImageView, называемом «myImageView».Я думал, что проблема была в том, что AVURLAssetPreferPreciseDurationAndTimingKey не был установлен, но даже после того, как я понял, как это сделать, он все еще не функционируетФактическое время и генерируются объявляются в заголовке

NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"Documents/videoTest4.m4v"]];
//UISaveVideoAtPathToSavedPhotosAlbum(path, self, @selector(video:didFinishSavingWithError:contextInfo:), nil);
NSURL *url = [NSURL fileURLWithPath:path];

NSDictionary *options = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:AVURLAssetPreferPreciseDurationAndTimingKey];
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:url options:options];

Float64 durationSeconds = CMTimeGetSeconds([asset duration]);

generate = [[AVAssetImageGenerator alloc] initWithAsset:asset];
NSError *err = nil;

time = CMTimeMake(600,600.0);
CGImageRef imgRef = [generate copyCGImageAtTime:time actualTime:&actualTime error:&err];
UIImage *currentImg = [[UIImage alloc] initWithCGImage:imgRef];
myImageView.image = currentImg;

NSLog(@"The total Video Duration is %f",durationSeconds);
NSLog(@"The time I want my image is %f",CMTimeGetSeconds(time));
NSLog(@"The actual time my image was take was %f",CMTimeGetSeconds(actualTime));

И моя консоль читает ..

2011-04-28 18: 49: 59.062 videoTest [26553: 207] Общая продолжительность видео1.880000

2011-04-28 18: 49: 59.064 videoTest [26553: 207] Время, когда я хочу, чтобы мое изображение было 1.000000

2011-04-28 18: 49: 59.064 videoTest [26553: 207] Фактическое время съемки моего изображения было 0,000000

..........................

Большое спасибо заранее, ребята ..:)

Ответы [ 2 ]

22 голосов
/ 07 ноября 2011

Для решения этой проблемы вам просто нужно установить requiredTimeToleranceBefore и requiredTimeToleranceAfter в kCMTimeZero для AVAssetImageGenerator.

Описание класса AVAssetImageGenerator

5 голосов
/ 29 апреля 2011

Поздно вечером у меня была идея, и, конечно же, она сработала сегодня утром.По сути, я просто создаю новый Composition Asset, а затем создаю временной диапазон, который представляет один кадр для видео со скоростью 24 кадра в секунду.Создав эти композиции, я просто беру первый кадр каждого компа.Я делаю это для каждого кадра и создаю массив, содержащий все мои кадры.Вот что я сделал ..

NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"Documents/videoTest4.m4v"]];
//UISaveVideoAtPathToSavedPhotosAlbum(path, self, @selector(video:didFinishSavingWithError:contextInfo:), nil);
NSURL *url = [NSURL fileURLWithPath:path];

NSDictionary *options = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:AVURLAssetPreferPreciseDurationAndTimingKey];
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:url options:options];

Float64 durationFrames = CMTimeGetSeconds([asset duration]) * 24.0;

AVMutableComposition *myComp = [AVMutableComposition composition];

AVMutableCompositionTrack *compositionVideoTrack = [myComp addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];

NSError *error = nil;
BOOL ok = NO;

NSMutableArray* frameArray = [[NSMutableArray alloc] init];

generate = [[AVAssetImageGenerator alloc] initWithAsset:myComp];
NSError *err = nil;

for (int i = 0; i < floor(durationFrames); i++) {

    CMTime startTime = CMTimeMake(i, 24);
    CMTime endTime = CMTimeMake(i+1, 24);

    CMTimeRange myRange = CMTimeRangeMake(startTime, endTime);

    AVAssetTrack *sourceVideoTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
    ok = [compositionVideoTrack insertTimeRange:myRange ofTrack:sourceVideoTrack atTime:kCMTimeZero error:&error];
    if (!ok) {
        // Deal with the error.
    }

    time = CMTimeMake(0,1);
    CGImageRef imgRef = [generate copyCGImageAtTime:time actualTime:&actualTime error:&err];
    UIImage *currentImg = [[UIImage alloc] initWithCGImage:imgRef];
    [frameArray addObject:currentImg];

    [currentImg release];

}

NSLog(@"This video is calculated at %f Frames..",durationFrames);
NSLog(@"You made a total of %i Frames!!",[frameArray count]);

Затем консоль читает ..

2011-04-29 10: 42: 24.292 videoTest [29019: 207] Это видео рассчитано на 45.120000Frames ..

2011-04-29 10: 42: 24.293 videoTest [29019: 207] Вы сделали 45 кадров !!

...