如何从视频中获取最后一帧?

时间:2015-08-17 09:49:28

标签: ios swift video

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

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)!

但我没有得到最后一帧,我正在获得第一帧,为我提供解决方案。

5 个答案:

答案 0 :(得分:3)

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

#!/bin/sh
#BSUB -J shrutireddy_project
#BSUB -o Horsepool_output_world
#BSUB -e Horsepool_error
#BSUB -n 1
#BSUB -q ht-10g
#BSUB cwd /home/shrutireddy/
work=/home/shrutireddy/
cd $work
./horse world192.txt "string". --> error at this line.

答案 1 :(得分:2)

我使用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 :(得分:1)

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

  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变量中获取最后一段视频的方法。

答案 3 :(得分:0)

接受的答案产生第一帧。

此代码有效(目标-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;

答案 4 :(得分:0)

经过多次尝试,我终于从视频中获得了最后一帧。

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)