使用Swift从视频中抓取帧

问题描述 投票:6回答:3

我想在特定时间从视频中抓取帧。我正在调用我的抓帧功能,其时间指定为秒为Float64。问题是它没有抓住当前帧。它似乎忽略了小数。如果我用例如1.22和1.70调用该函数,它将返回相同的帧。对于Swift来说,我是新手,所以我猜我没有把CMTime对象弄好。所以有人能看出这有什么问题吗?

func generateThumnail(url : NSURL, fromTime:Float64) -> UIImage {
    var asset :AVAsset = AVAsset.assetWithURL(url) as! AVAsset
    var assetImgGenerate : AVAssetImageGenerator = AVAssetImageGenerator(asset: asset)
    assetImgGenerate.appliesPreferredTrackTransform = true
    var error       : NSError? = nil
    var time        : CMTime = CMTimeMakeWithSeconds(fromTime, 600)        
    var img         : CGImageRef = assetImgGenerate.copyCGImageAtTime(time, actualTime: nil, error: &error)
    var frameImg    : UIImage = UIImage(CGImage: img)!
    return frameImg
}

var grabTime = 1.22
img = generateThumnail(urlVideo, fromTime: Float64(grabTime)) 
swift video avfoundation
3个回答
12
投票

感谢@ eric-d发现了这篇文章:iOS Take Multiple Screen Shots

我设法找出添加:

    assetImgGenerate.requestedTimeToleranceAfter = kCMTimeZero;
    assetImgGenerate.requestedTimeToleranceBefore = kCMTimeZero;

...我的功能将会做到这一点。

我更新的函数如下所示:

func generateThumnail(url : NSURL, fromTime:Float64) -> UIImage {
    var asset :AVAsset = AVAsset.assetWithURL(url) as! AVAsset
    var assetImgGenerate : AVAssetImageGenerator = AVAssetImageGenerator(asset: asset)
    assetImgGenerate.appliesPreferredTrackTransform = true
    assetImgGenerate.requestedTimeToleranceAfter = kCMTimeZero;
    assetImgGenerate.requestedTimeToleranceBefore = kCMTimeZero;
    var error       : NSError? = nil
    var time        : CMTime = CMTimeMakeWithSeconds(fromTime, 600)        
    var img         : CGImageRef = assetImgGenerate.copyCGImageAtTime(time, actualTime: nil, error: &error)
    var frameImg    : UIImage = UIImage(CGImage: img)!
    return frameImg
}

var grabTime = 1.22
img = generateThumnail(urlVideo, fromTime: Float64(grabTime))

1
投票

我将arpo的答案纳入了我的项目,更新了Swift 3:

fileprivate func generateThumnail(url : URL, fromTime:Float64) -> UIImage? {
    let asset :AVAsset = AVAsset(url: url)
    let assetImgGenerate : AVAssetImageGenerator = AVAssetImageGenerator(asset: asset)
    assetImgGenerate.appliesPreferredTrackTransform = true
    assetImgGenerate.requestedTimeToleranceAfter = kCMTimeZero;
    assetImgGenerate.requestedTimeToleranceBefore = kCMTimeZero;
    let time        : CMTime = CMTimeMakeWithSeconds(fromTime, 600)
    if let img = try? assetImgGenerate.copyCGImage(at:time, actualTime: nil) {
        return UIImage(cgImage: img!)
    } else {
        return nil
    }
}

1
投票

对于swift 4.2

fileprivate func generateThumnail(url : URL, fromTime:Float64) -> UIImage? {
    let asset :AVAsset = AVAsset(url: url)
    let assetImgGenerate : AVAssetImageGenerator = AVAssetImageGenerator(asset: asset)
    assetImgGenerate.appliesPreferredTrackTransform = true
    assetImgGenerate.requestedTimeToleranceAfter = CMTime.zero;
    assetImgGenerate.requestedTimeToleranceBefore = CMTime.zero;
    let time : CMTime = CMTimeMakeWithSeconds(fromTime, preferredTimescale: 600)
    if let img = try? assetImgGenerate.copyCGImage(at:time, actualTime: nil) {
        return UIImage(cgImage: img)
    } else {
        return nil
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.