2016-06-20 4 views
2

すぐに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") 
      }) 
     }) 

答えて

2

、あなたは、iOSデバイス上の、あるいはデスクトップ・マシン上のメモリにビデオ資産のすべてのフレームに合うことができません:ビデオは30代です

var samples:[CMSampleBuffer] = [] 

ない場合でも、長いです。例えば毎秒30フレームで、BGRAとしてデコードされた720p、30秒のビデオは、メモリの30 * 30 * 1280 * 720 * 4 bytes = 3.2GBを必要とするでしょう。各フレームは3.5MBです! 1080p以上のフレームレートを使用していると悪いことです。

ファイルをフレーム単位でマージする必要があります。できるだけ少ない数のフレームをメモリに保存してください。

ただし、マージなどの簡単な操作では、フレームを自分で処理する必要はありません。 AVMutableCompositionを作成し、AVAssetを追加してから、AVAssetExportSessionを使用してマージしたファイルをエクスポートすることができます。

+0

私はAVAssetExportを見てきましたが、いくつかの点でもいくつかの画像をマージする必要があります。ですから、なぜ私はこのルートに行ったのですか? – Dinalli

+1

'AVMutableVideoCompositionLayerInstruction'sでそれを行うことはできますが、フレームを直接変更する方が簡単かもしれません。 –

関連する問題