【问题标题】:Memory warning while trying to merge multiple video files in swift尝试快速合并多个视频文件时出现内存警告
【发布时间】:2016-06-20 17:19:31
【问题描述】:

我正在尝试使用 swift 将 2 个视频合并在一起。但是,当我尝试运行此代码时,我会收到内存警告,有时还会崩溃。

我的预感是我出于某种原因提前退出了 dispatch_group 并完成了编写器。

但我也注意到,有时我并没有走那么远。

我还注意到我的 samples.count 有时非常庞大,这看起来很奇怪,因为每个视频的长度不超过 30 秒。

我不知道从哪里开始解决这个问题。任何指针表示赞赏。

 dispatch_group_enter(self.videoProcessingGroup)               
                asset.requestContentEditingInputWithOptions(options, completionHandler: {(contentEditingInput: PHContentEditingInput?, info: [NSObject : AnyObject]) -> Void in

                    let avAsset = contentEditingInput?.audiovisualAsset


                    let reader = try! AVAssetReader.init(asset: avAsset!)
                    let videoTrack = avAsset?.tracksWithMediaType(AVMediaTypeVideo).first

                    let readerOutputSettings: [String:Int] = [kCVPixelBufferPixelFormatTypeKey as String: Int(kCVPixelFormatType_32BGRA)]

                    let readerOutput = AVAssetReaderTrackOutput(track: videoTrack!, outputSettings: readerOutputSettings)
                    reader.addOutput(readerOutput)
                    reader.startReading()

                    //Create the samples
                    var samples:[CMSampleBuffer] = []

                    var sample: CMSampleBufferRef?

                    sample = readerOutput.copyNextSampleBuffer()

                    while (sample != nil)
                    {
                        autoreleasepool {
                            samples.append(sample!)
                            sample = readerOutput.copyNextSampleBuffer()
                        }
                    }

                    for i in 0...samples.count - 1 {
                        // Get the presentation time for the frame

                        var append_ok:Bool = false

                        autoreleasepool {
                            if  let pixelBufferPool = adaptor.pixelBufferPool {
                                let pixelBufferPointer = UnsafeMutablePointer<CVPixelBuffer?>.alloc(1)
                                let status: CVReturn = CVPixelBufferPoolCreatePixelBuffer(
                                    kCFAllocatorDefault,
                                    pixelBufferPool,
                                    pixelBufferPointer
                                )

                                let frameTime = CMTimeMake(Int64(frameCount), 30)

                                if var buffer = pixelBufferPointer.memory where status == 0 {
                                    buffer = CMSampleBufferGetImageBuffer(samples[i])!
                                    append_ok = adaptor.appendPixelBuffer(buffer, withPresentationTime: frameTime)
                                    pixelBufferPointer.destroy()
                                } else {
                                    NSLog("Error: Failed to allocate pixel buffer from pool")
                                }

                                pixelBufferPointer.dealloc(1)
                                dispatch_group_leave(self.videoProcessingGroup)
                            }
                        }

                    }
                })




        //Finish the session:
        dispatch_group_notify(videoProcessingGroup, dispatch_get_main_queue(), {
            videoWriterInput.markAsFinished()
            videoWriter.finishWritingWithCompletionHandler({
                print("Write Ended")

                // Return writer
                print("Created asset writer for \(size.width)x\(size.height) video")
            })
        })

【问题讨论】:

    标签: ios swift memory-management avfoundation


    【解决方案1】:

    通常,您无法将视频资产的所有帧都放入 iOS 设备甚至台式机的内存中:

    var samples:[CMSampleBuffer] = []
    

    即使视频长达 30 秒也不行。例如在每秒 30 帧的情况下,一个 720p、30 秒的视频,解码为 BGRA 需要30 * 30 * 1280 * 720 * 4 bytes = 3.2GB 的内存。每一帧都是3.5MB!如果您使用 1080p 或更高的帧速率,情况会更糟。

    您需要逐帧逐步合并文件,在任何给定时间在内存中保持尽可能少的帧。

    但是,对于像合并这样简单的操作,您不需要自己处理帧。您可以创建一个AVMutableComposition,附加单个AVAssets,然后使用AVAssetExportSession 导出合并的文件。

    【讨论】:

    • 谢谢我看过 AVAssetExport 但我也需要在某些时候合并一些图像。所以我为什么选择这条路。
    • 您可以使用AVMutableVideoCompositionLayerInstructions 来做到这一点,尽管有时直接修改框架似乎更容易。
    猜你喜欢
    • 2015-12-13
    • 1970-01-01
    • 1970-01-01
    • 2013-10-10
    • 1970-01-01
    • 2012-03-12
    • 2021-11-08
    • 2017-11-07
    • 1970-01-01
    相关资源
    最近更新 更多