【问题标题】:Processing all frames in an AVAsset处理 AVAsset 中的所有帧
【发布时间】:2014-10-28 04:37:22
【问题描述】:

我正在尝试遍历AVAsset 中的每一帧,并将每一帧当作图像处理。我无法从搜索中找到任何内容。

我要完成的任务在伪代码中看起来像这样

for each frame in asset

      take the frame as an image and convert to a cvMat
      Process and store data of center points
      Store center points in array

该伪代码中唯一我不知道如何编写的部分是遍历每一帧并将其捕获到图像中。

谁能帮忙?

【问题讨论】:

    标签: ios objective-c avfoundation avasset


    【解决方案1】:

    一个答案是使用AVAssetImageGenerator

    1) 将电影文件加载到AVAsset 对象中。
    2) 创建一个AVAssetImageGenerator 对象。
    3) 传入您想要从电影中获取图像的帧的估计时间。

    AVAssetImageGenerator 对象上的requestedTimeToleranceBeforerequestedTimeToleranceAfter 2 个属性设置为kCMTimeZero 将增加获取单个帧的能力,但会增加处理时间。

    但是这种方法很慢,我还没有找到更快的方法。

    //Load the Movie from a URL
    self.movieAsset = [AVAsset assetWithURL:self.movieURL];
    NSArray *movieTracks = [self.movieAsset tracksWithMediaType:AVMediaTypeVideo];
    AVAssetTrack *movieTrack = [movieTracks objectAtIndex:0];
    
    //Make the image Generator    
    AVAssetImageGenerator *imageGenerator = [[AVAssetImageGenerator alloc] initWithAsset:self.movieAsset];
    
    //Create a variables for the time estimation
    Float64 durationSeconds = CMTimeGetSeconds(self.movieAsset.duration);
    Float64 timePerFrame = 1.0 / (Float64)movieTrack.nominalFrameRate;
    Float64 totalFrames = durationSeconds * movieTrack.nominalFrameRate;
    
    //Step through the frames
    for (int counter = 0; counter <= totalFrames; counter++){
        CMTime actualTime;
        Float64 secondsIn = ((float)counter/totalFrames)*durationSeconds;
        CMTime imageTimeEstimate = CMTimeMakeWithSeconds(secondsIn, 600);
        NSError *error;
        CGImageRef image = [imageGenerator copyCGImageAtTime:imageTimeEstimate actualTime:&actualTime error:&error];
    
        ...Do some processing on the image
    
        CGImageRelease(image);    
    }
    

    【讨论】:

    • 我得到的结果总是对齐到 0s 1s 2s 3s can't get middle frame
    【解决方案2】:

    您可以简单地使用 AVAssetReaderTrackOutput 生成每一帧:

                let asset = AVAsset(url: inputUrl)
                let reader = try! AVAssetReader(asset: asset)
                let videoTrack = asset.tracks(withMediaType: .video).first!
                let outputSettings = [String(kCVPixelBufferPixelFormatTypeKey): NSNumber(value: kCVPixelFormatType_32BGRA)]
                let trackReaderOutput = AVAssetReaderTrackOutput(track: videoTrack,
                                                                 outputSettings: outputSettings)
    
                reader.add(trackReaderOutput)
                reader.startReading()
    
                while let sampleBuffer = trackReaderOutput.copyNextSampleBuffer() {
                    if let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) {
                        // do what you want
                    }
                }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-03-21
      • 2015-07-16
      • 2019-04-25
      • 1970-01-01
      • 2015-12-15
      • 2011-03-29
      • 2017-10-15
      相关资源
      最近更新 更多