And*_*i V 5 frames movie avfoundation ios
我试图在顶部添加效果来编辑现有的电影,因此我需要能够扫描所有电影帧,将它们作为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];
}
Run Code Online (Sandbox Code Playgroud)
这种方法存在两个问题:
这似乎不自然.问题:是否有更好的方法来扫描电影的所有原始帧?
终于找到了我要找的东西。下面是我的代码,用于扫描电影中的所有样本。顺便说一句,使用 AVAssetImageGenerator 可以工作,但速度非常慢。这种方法很快。
inputUrl = [NSURL fileURLWithPath:filePath];
AVURLAsset* movie = [AVURLAsset URLAssetWithURL:inputUrl options:nil];
NSArray* tracks = [movie tracksWithMediaType:AVMediaTypeVideo];
AVAssetTrack* track = [tracks firstObject];
NSError* error = nil;
AVAssetReader* areader = [[AVAssetReader alloc] initWithAsset:movie error:&error];
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:kCVPixelFormatType_32ARGB], kCVPixelBufferPixelFormatTypeKey,
nil];
AVAssetReaderTrackOutput* rout = [[AVAssetReaderTrackOutput alloc] initWithTrack:track outputSettings:options];
[areader addOutput:rout];
[areader startReading];
while ([areader status] == AVAssetReaderStatusReading) {
CMSampleBufferRef sbuff = [rout copyNextSampleBuffer];
if (sbuff) {
dispatch_sync(dispatch_get_main_queue(), ^{
[self writeFrame:sbuff];
});
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1645 次 |
| 最近记录: |