微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用 AVAssetReader 读取视频文件时,由于内存利用率高,应用程序崩溃

如何解决使用 AVAssetReader 读取视频文件时,由于内存利用率高,应用程序崩溃

我正在尝试使用此问题中已接受答案中的方法读取视频帧:Accesing Individual Frames using AV Player

然后我尝试在 MetalKit MKTView 上按顺序显示这些帧(我尝试了常规 UIImage 视图,但视频根本不呈现)。问题是这只能工作几秒钟(视频的大约 400 帧),之后应用崩溃并且视频停止播放。

这是视图控制器中的代码

class MetalRenderViewController: UIViewController {
    var MetalView: MetalRenderView!
    
    var videoFileReader: VideoFileReader?
    var videoUrl: URL!
    override func viewDidLoad() {
        super.viewDidLoad()
        MetalView = MetalRenderView(frame: view.bounds,device: MTLCreateSystemDefaultDevice())
        view.addSubview(MetalView)
        videoFileReader = VideoFileReader(videoUrl: videoUrl) { (image) in
            guard let image = image else {return}
            self.MetalView.image = image

        }
        videoFileReader?.beginReadingAsset()
    }
    
}

这是 videoFileReader 中的相关代码

guard let track = asset.tracks(withMediaType: .video).first else {return}
let reader = try! AVAssetReader(asset: asset)
let output = AVAssetReaderTrackOutput(track: track,outputSettings: settings)
reader.add(output)
reader.startReading()

while let sampleBuffer = output.copyNextSampleBuffer() {
            guard let imageBuffer = CMSampleBufferGetimageBuffer(sampleBuffer) else { return }
            dispatchQueue.main.async {
                let image = CIImage(cvImageBuffer: imageBuffer)
                self.callback(image)
                
            }
        }

我怀疑该问题可能与内存使用率高有关,因为在调试器中内存使用率飙升至约 1.5 GB,然后在崩溃后下降,尽管我没有看到任何内存警告。

错误日志如下:

2021-06-28 16:13:22.491431-0400 WorkoutApp[10844:2837856] [xpc] xpc error talking to pkd: Connection interrupted
2021-06-28 16:13:22.773817-0400 WorkoutApp[10844:2837835] [ServicesDaemonManager] interruptionHandler is called. -[FontServicesDaemonManager connection]_block_invoke
2021-06-28 16:13:28.057141-0400 WorkoutApp[10844:2837857] [lifecycle] [u 5485F2DA-5C8A-40DD-91A5-F248E652AA58:m (null)] [com.apple.mobileslideshow.photo-picker(1.0)] Connection to plugin interrupted while in use.
2021-06-28 16:13:28.075489-0400 WorkoutApp[10844:2838140] [lifecycle] [u 5485F2DA-5C8A-40DD-91A5-F248E652AA58:m (null)] [com.apple.mobileslideshow.photo-picker(1.0)] Connection to plugin invalidated while in use.

如果有人可以帮助我降低内存使用率,或者提出一种更好的方法来完全做到这一点,我们将不胜感激。

编辑

更新标题以更具体地说明错误删除金属渲染类,这是一个红鲱鱼。

解决方法

通过确认删除 ViewController 和 Metal 渲染类后问题仍然存在,我能够将此问题与 VideoFileReader 类中的 while 循环隔离。通过计算崩溃前读取的帧数并与调试器中的内存使用增长进行比较,我还能够确认崩溃确实是由于内存使用率过高造成的。

最终解决问题的是将 while 循环体包装在 autoreleasepool 块中。似乎正在创建图像缓冲区而不是释放图像缓冲区,这就是内存峰值和随后崩溃的原因。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。