从SwiftiOS视频创建帧

问题描述

有一个视频文件,时长为3秒。我需要创建30帧-UIImages。每隔0.1秒捕获一次图像。 我尝试使用AVAssetImageGenerator和CMTimeMake,但是我总是得到30张相似的图像,或者15张相似的图像,另外15张相似的图像。

请帮助了解如何从该视频中制作这种幻灯片。也许还有更好的方法。

请参见下面的代码:

static func generate_Thumbnails(forVideoWithURL url : URL) -> [UIImage]? {
    let asset = AVAsset(url: url)
    var result: [UIImage] = []
    let assetImgGenerator = AVAssetImageGenerator(asset: asset)
    assetImgGenerator.appliesPreferredTrackTransform = true
    for i in 1...30 {
        let time: CMTime = CMTimeMake(value: Int64(i),timescale: 10)
        do {
            let img: CGImage = try assetImgGenerator.copyCGImage(at: time,actualTime: nil)
            let frameImg: UIImage = UIImage(cgImage: img)
            result.append(frameImg)
        } catch {
            //return nil
        }
    }
    return result
}

解决方法

我还没有阅读AVAssetImageGenerator的文档,但实际上,我每秒只能生成1张图像。因此,您应该能够在1、2和3秒(而不是30秒)上获得图像。这是我用来生成图像的代码,与您的代码非常相似。

private func getPreviewImage(forURL url: URL,atSeconds seconds: Double) -> UIImage? {
        let asset = AVURLAsset(url: url)
        let generator = AVAssetImageGenerator(asset: asset)
        generator.appliesPreferredTrackTransform = true

        let timestamp = CMTime(seconds: seconds,preferredTimescale: 100)

        do {
            let imageRef = try generator.copyCGImage(at: timestamp,actualTime: nil)
            return UIImage(cgImage: imageRef)
        }
        catch let error as NSError
        {
            print("Image generation failed with error \(error)")
            return nil
        }
    }
,

我尝试了Amin Benarieb的解决方案,但似乎可行:

static func toImages(fromVideoUrl url: URL) -> [UIImage]? {
    let asset = AVAsset(url: url)
    guard let reader = try? AVAssetReader(asset: asset) else { return nil }
    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()
    var images = [UIImage]()
    while reader.status == .reading {
        autoreleasepool {
            if let sampleBuffer = trackReaderOutput.copyNextSampleBuffer() {
                if let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) {
                    let ciImage = CIImage(cvImageBuffer: imageBuffer)
                    images.append(UIImage(ciImage: ciImage))
                }
            }
        }
    }
    return images
}

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...