Grab frames from video using Swift

亡梦爱人 提交于 2019-12-17 18:58:56

问题


I want to grab frames from a video at a specific time. I'm calling my grab-frame-function with a time specified as seconds as a Float64. The problem is that it doesn't grab the current frame. It seems to ignore the decimals. If I call the function with for example 1.22 and 1.70 it will return the same frame. I'm quite new when it comes to Swift so I guess I don't get the CMTime object right. So can anyone see what's wrong with this?

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

回答1:


Thanks to @eric-d who found this post: iOS Take Multiple Screen Shots

I manage to find out that adding:

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

...to my function will do the trick.

My updated function looks like this:

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



回答2:


I incorporated arpo's answer into my project, updated for 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
    }
}



回答3:


For 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
    }
}


来源:https://stackoverflow.com/questions/32286320/grab-frames-from-video-using-swift

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!