【发布时间】:2014-07-31 18:13:27
【问题描述】:
我正在尝试编辑现有电影并在顶部添加效果,因此我需要能够扫描所有电影帧,将它们作为 UIImage 获取,应用效果,然后更新该帧或将其写入新电影。 我发现人们建议使用 AVAssetImageGenerator。以下是我如何做的最终编辑示例:
-(void)processMovie:(NSString*)moviePath {
NSURL* url = [NSURL fileURLWithPath:moviePath];
AVURLAsset *asset=[[AVURLAsset alloc] initWithURL:url options:nil];
float movieTimeInSeconds = CMTimeGetSeconds([movie duration]);
AVAssetImageGenerator *generator = [[AVAssetImageGenerator alloc] initWithAsset:asset];
generator.requestedTimeToleranceBefore = generator.requestedTimeToleranceAfter = kCMTimeZero;
generator.appliesPreferredTrackTransform=TRUE;
[asset release];
// building array of time with steps as 1/10th of second
NSMutableArray* arr = [[[NSMutableArray alloc] init] retain];
for(int i=0; i<movieTimeInSeconds*10; i++) {
[arr addObject:[NSValue valueWithCMTime:CMTimeMake(i,10)]];
}
AVAssetImageGeneratorCompletionHandler handler = ^(CMTime requestedTime, CGImageRef im, CMTime actualTime, AVAssetImageGeneratorResult result, NSError *error){
if (result == AVAssetImageGeneratorSucceeded) {
UIImage* img = [UIImage imageWithCGImage:im];
// use img to apply effect and write it in new movie
// after last frame do [generator release];
}
};
[generator generateCGImagesAsynchronouslyForTimes:arr completionHandler:handler];
}
这种方法的 2 个问题:
- 我需要猜测电影的时间步长,或者在我的示例中假设电影的时间步长为 10FPS。实际时间步长不是均匀分布的,而且有时我们会跳帧。
- 扫描帧很慢。如果以高分辨率录制电影,我大约需要 0.5 秒来检索每一帧的 UIImage。
这似乎不自然。问题:有没有更好的方法来扫描电影的所有原始帧?
【问题讨论】:
-
猜时间步是什么意思?
-
@Daniel 表示电影帧以 20FPS 还是 10FPS 录制。或者有些帧可能不会像 100 毫秒、220 毫秒、300 毫秒那样均匀分布...换句话说,我可以击中同一帧两次(如果 2 个电影帧的间隔比我的时间步长得多)或跳过一些帧(如果我的时间步长比两部电影之间的距离大得多)。
-
您可以从 AVFoundation API 中找到电影的 FPS
标签: ios avfoundation frames movie