5

ビデオ アセットから静止フレームを生成しようとするたびに、0.000.. 秒の時点で生成されます。これは、ログ メッセージから確認できます。良いことは、時間 0.000 の画像を取得して、"myImageView" という UIImageView に表示できることです。問題は AVURLAssetPreferPreciseDurationAndTimingKey が設定されていないことだと思いましたが、その方法を理解した後でもまだ機能しません..

これが私が持っているものです..

time、actualTime、および generate はヘッダーで宣言されています

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 でした

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

どうもありがとうございました.. :)

4

2 に答える 2

23

これを解決するには、requestedTimeToleranceBefore と requestedTimeToleranceAfter を AVAssetImageGenerator の kCMTimeZero に設定するだけです

AVAssetImageGenerator クラス リファレンス

于 2011-11-07T15:19:23.577 に答える
5

昨夜遅く、私はアイデアを思いつき、今朝それが十分に機能したことを確認しました. 基本的には、新しいコンポジション アセットを作成し、ビデオの 1 フレームを 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.120000 フレームで計算されます..

2011-04-29 10:42:24.293 videoTest[29019:207] 合計 45 フレームを作成しました!!

于 2011-04-29T14:50:52.660 に答える