访问iOS中所有电影帧的最佳方式 [英] Best way to access all movie frames in iOS

查看:107
本文介绍了访问iOS中所有电影帧的最佳方式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在顶部添加效果来编辑现有的电影,因此我需要能够扫描所有电影帧,将它们作为UIImage,应用效果,然后更新该帧或将其写入新电影。
我发现人们建议使用AVAssetImageGenerator。下面是我最后编辑的样本:我是怎么做的:

Im trying to edit existing movie with added effects on top thus I need ability to scan all movie frames, get them as UIImage, apply effect and then either update that frame or write it into new movie. What I found is people suggesting to use AVAssetImageGenerator. Below is my final edited sample of how Im doing it:

-(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个问题:


  1. 我需要猜测电影的时间步长,或者在我的例子中假设电影的10FPS。实际的时间步长不是均匀间隔加上有时候我们跳过了帧。

  2. 扫描帧很慢。如果以高分辨率录制电影,我会在0.5秒左右为每帧检索UIImage。

看起来不自然。问题:是否有更好的方法来扫描电影的所有原始帧?

It seems unnatural. Question: is there better way to scan all original frames of the movie?

推荐答案

终于找到了我想要的东西。下面是我扫描电影中所有样本的代码。 BTW使用AVAssetImageGenerator工作但很慢。这种方法很快。

Finally found what I was looking for. Below is my code that scans all samples in the movie. BTW using AVAssetImageGenerator was working but was very slow. This approach is fast.

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];
        });
    }
}

这篇关于访问iOS中所有电影帧的最佳方式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆