ios - 使用 AVAssetImageGenerator 为长视频获取视频中的所有帧时应用程序崩溃

标签 ios iphone swift

我已经成功地从视频中提取了所有帧,它对于较小的视频工作正常,但是当我尝试从超过 60 秒的视频中提取帧时,应用程序在设备上崩溃了。

我每秒从视频中提取 30 帧。

以下是我编写的代码:-

var  videoSec = Float64(0)

 func startImageConversion(){
        let filePath = NSURL.fileURLWithPath(self.savedVideoURL)
        videoSec = self.getVideoTime(filePath)
        videoImagesArray =  self.getImagesArrayFromVideo(filePath)
        print("Images Count \(videoImagesArray.count)")
    }

//MARK: - 视频编辑器功能

    func getImagesArrayFromVideo(filePath:NSURL) -> NSMutableArray
    {
        let imageArray = NSMutableArray()
        print("Video Sec is ",videoSec)
        let vidSec = Float64(videoSec)

        let theOpts = [
            AVURLAssetPreferPreciseDurationAndTimingKey : true,
            AVURLAssetReferenceRestrictionsKey : 0 // AVAssetReferenceRestrictions.RestrictionForbidNone
        ]
        let asset = AVURLAsset(URL: filePath, options: theOpts)
        let generator = AVAssetImageGenerator(asset: asset)
        generator.maximumSize = CGSize(width: Double(self.view.frame.size.width),
                                       height: Double(self.view.frame.size.height))

        generator.appliesPreferredTrackTransform = false
        generator.requestedTimeToleranceBefore = kCMTimeZero
        generator.requestedTimeToleranceAfter = kCMTimeZero
        let vid_length:CMTime = asset.duration
        let fps = vid_length.timescale
        print("Video Lenght :- \(vid_length) FPS is :- \(fps)")


        let mainValue = Float64(vid_length.value)

        let divide = vidSec*30
        let byVal = mainValue/divide


        for i in 0.stride(through: Float64(vid_length.value), by: byVal)
        {

            var image:CGImage!//UIImage()
            let divident = Float64(i)
//            let mileSec = Float64(divident / 1000)
//            print(Sec)
            image  = self.generateVideoThumbs(filePath, second: divident,
                                              thumbWidth: Double(self.view.frame.size.width),
                                              generator : generator,
                                              fps : fps
            )

            if image != nil {

                imageArray.addObject(image)

            }
        }

        print("value of Array is ",imageArray.count)

        return imageArray

    }



 private func getVideoTime(url: NSURL) -> Float64
    {
        let videoTime = AVURLAsset(URL: url, options: nil)
        print("videoTime.preferredRate = \(videoTime.preferredRate)")
        return CMTimeGetSeconds(videoTime.duration)
    }



 private func generateVideoThumbs(url: NSURL, second: Float64, thumbWidth: Double, generator:AVAssetImageGenerator, fps: CMTimeScale) -> CGImage! {
        let thumbTime = CMTimeMake(Int64(second), fps)
        var actualTime : CMTime = CMTimeMake(0, 0)
        print("thumbTime - \(thumbTime)")
        do {
            let ref = try generator.copyCGImageAtTime(thumbTime, actualTime: &actualTime)
            print("actualTime - \(actualTime)")
            return ref//UIImage(CGImage: ref)
        }catch {
            print(error)
            return nil
        }
     }

如果视频少于 60 秒左右,一切正常。 它在模拟器上也能正常工作,但会在没有任何警告或错误的情况下断开设备。 enter image description here 任何帮助将不胜感激,谢谢

最佳答案

autoreleasepool{
if image != nil {
var newImage:UIImage = UIImage(CGImage: cgImage)
                imageArray.addObject(image)
            }
}

在上面的回答中,dive 提到了它的内存问题。 只需使用此代码。我已经对其进行了测试,它运行良好。

关于ios - 使用 AVAssetImageGenerator 为长视频获取视频中的所有帧时应用程序崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40609944/

相关文章:

ios - 如何在我的网络服务中显示加载 View Controller

ios - 为什么通知会自动从 iOS 通知中心删除?

swift - Vapor 主线程不起作用

swift - 如何使用 AWSS3TransferUtility 将带有用户元数据的音频文件上传到 S3

iphone - 释放UIView会自动调用removeFromSuperView吗?

ios - 不在事件 View Controller 上时如何执行 segue "behind the scenes"?

ios - 更改 MKMapView 用户位置注释

ios - NSString 到带有希腊字符的 char*

ios - 如何比较 2 个 UIColor 对象,它们是日志中的 kCGColorSpaceModelRGB 和 UIExtendedSRGBColorSpace 实例?

ios - Iphone App Store 批准时间 公司 vs. 个人