【问题标题】:How to get last frame from video?如何从视频中获取最后一帧?
【发布时间】:2015-08-17 09:49:27
【问题描述】:

我想要最后一帧视频,我的代码如下所示:

let asset : AVURLAsset = AVURLAsset(URL: videoURL, options: nil)
    let generate : AVAssetImageGenerator = AVAssetImageGenerator(asset: asset)
    generate.appliesPreferredTrackTransform = true

    var err : NSError? = nil
    var lastFrameTime = Int64(CMTimeGetSeconds(asset.duration))
    let time : CMTime = CMTimeMake(lastFrameTime, 30)
    let imgRef : CGImageRef = generate.copyCGImageAtTime(time, actualTime: nil, error: &err)
    let img : UIImage = UIImage(CGImage: imgRef)!

但是我没有得到最后一帧,我得到了第一帧,请为此提供解决方案。

【问题讨论】:

    标签: ios swift video


    【解决方案1】:

    我使用 Pooja 的代码作为起点,但它没有得到最后一帧。它得到接近最后一帧的东西。这是我获取实际最后一帧的解决方案。如果帧精度很重要,那么您必须使用:

    imageGenerator.requestedTimeToleranceBefore = kCMTimeZero
    imageGenerator.requestedTimeToleranceAfter = kCMTimeZero
    

    请注意,生成此帧准确的最后一帧可能需要更长的时间,因此您可能希望在后台线程上执行此操作。

    这是我正在使用的代码:

    let imageGenerator = AVAssetImageGenerator(asset: asset!)
    imageGenerator.appliesPreferredTrackTransform = true
    imageGenerator.requestedTimeToleranceAfter = kCMTimeZero
    imageGenerator.requestedTimeToleranceBefore = kCMTimeZero
    
    let composition = AVVideoComposition(propertiesOfAsset: asset!)
    let time = CMTimeMakeWithSeconds(asset!.duration.seconds, composition.frameDuration.timescale)
    
    do {
        let imageRef = try imageGenerator.copyCGImageAtTime(time, actualTime: nil)
    }
    catch let error as NSError {
        print("Image generation failed with error \(error)")
    }
    

    希望这会有所帮助。

    【讨论】:

      【解决方案2】:

      您可以在 Objective-C 中获取视频的最后一帧,如下所述:-

          AVURLAsset *asset = [AVURLAsset URLAssetWithURL:videoURL options:nil];
          AVAssetImageGenerator *generate = [AVAssetImageGenerator assetImageGeneratorWithAsset:asset];
          generate.appliesPreferredTrackTransform = YES;
      
          NSError *error;
      
          int64_t lastFrameTime = CMTimeGetSeconds(asset.duration)*60.0;
          CMTime time = CMTimeMake(lastFrameTime, 2);
          CGImageRef imgRef = [generate copyCGImageAtTime:time actualTime:nil error:&error];
          UIImage *image = [UIImage imageWithCGImage:imgRef];
      

      【讨论】:

      • 请发布 OP 提出的有关 Swift 的问题的相关代码 我看不出客观的 c 代码有什么帮助。
      【解决方案3】:

      我已经解决了这个问题,只从视频中获取最后一帧代码如下:

        let asset : AVURLAsset = AVURLAsset(URL: videoURL, options: nil)
          let generate : AVAssetImageGenerator = AVAssetImageGenerator(asset: asset)
          generate.appliesPreferredTrackTransform = true
      
          var err : NSError? = nil
          var lastFrameTime = Int64(CMTimeGetSeconds(asset.duration)*60.0)
          let time : CMTime = CMTimeMake(lastFrameTime, 2)
          let imgRef : CGImageRef = generate.copyCGImageAtTime(time, actualTime: nil, error: &err)
          let img : UIImage = UIImage(CGImage: imgRef)!
      

      这就是我如何在 img 变量中获取视频的最后一张图片。

      【讨论】:

      • 这里为什么使用preferredTimeScale的硬编码值2?
      • 我还在获取第一帧
      【解决方案4】:

      接受的答案产生第一帧。

      此代码有效(objective-c)

      AVAsset* asset = [AVAsset assetWithURL:videoURL];
      AVAssetImageGenerator *generate = [AVAssetImageGenerator assetImageGeneratorWithAsset:asset];
      generate.requestedTimeToleranceAfter = kCMTimeZero;
      generate.requestedTimeToleranceBefore = kCMTimeZero;
      generate.appliesPreferredTrackTransform = YES;
      
      NSError *error;
      CMTime time = asset.duration;
      CGImageRef imgRef = [generate copyCGImageAtTime:time actualTime:nil error:&error];
      UIImage *image = [UIImage imageWithCGImage:imgRef];
      

      这里的主要内容是:

      generate.requestedTimeToleranceAfter = kCMTimeZero;
      generate.requestedTimeToleranceBefore = kCMTimeZero;
      

      CMTime time = asset.duration;
      

      【讨论】:

        【解决方案5】:

        经过多次尝试,我终于得到了视频的最后一帧。

        let imageGenerator = AVAssetImageGenerator(asset: asset)
        imageGenerator.appliesPreferredTrackTransform = true
        
        // Make sure you set the next two properties. 
        // It didn't work for me without this two parameters!
        imageGenerator.requestedTimeToleranceBefore = .zero
        imageGenerator.requestedTimeToleranceAfter = .positiveInfinity
        
        let lastFrameTime = Int64(CMTimeGetSeconds(asset.duration) * 60)
        time = CMTime(value: lastFrameTime, timescale: 2)
        
        guard let imageRef = try? imageGenerator.copyCGImage(at: time, actualTime: nil) else { 
            return
        }
        
        let thumbnailImage = UIImage(cgImage: imageRef)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-07-20
          • 2013-03-18
          • 2020-06-07
          • 1970-01-01
          相关资源
          最近更新 更多