如何解决使用 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 举报,一经查实,本站将立刻删除。