2016-06-20 9 views
2

Ich versuche, 2 Videos mit swift zusammenzuführen. Allerdings erhalte ich eine Speicherwarnung und manchmal einen Absturz, wenn ich versuche, diesen Code auszuführen.Speicherwarnung beim Versuch, mehrere Videodateien in swift zusammenzuführen

Meine Ahnung ist, dass ich die Dispatch_group aus irgendeinem Grund früh verlassen und den Writer beenden.

Allerdings habe ich auch festgestellt, dass ich manchmal nicht so weit komme.

Ich habe auch bemerkt, dass mein Samples.count manchmal massiv ist, was seltsam erscheint, da die Videos nicht mehr als 30 Sekunden lang sind.

Ich bin fest, wo zu Beginn dieses Problem tbh zu lösen. Alle Hinweise geschätzt.

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") 
      }) 
     }) 

Antwort

2

Im Allgemeinen können Sie alle Bilder eines Video-Assets in dem Speicher auf einem iOS-Gerät nicht passen, oder auch auf einem Desktop-Rechner:

var samples:[CMSampleBuffer] = [] 

Nicht einmal, wenn die Videos 30s lange. z.B. Bei 30 Bildern pro Sekunde würde ein Video mit 720p und 30 Sekunden, das als BGRA decodiert wurde, 30 * 30 * 1280 * 720 * 4 bytes = 3.2GB des Speichers erfordern. Jeder Rahmen ist 3.5MB! Schlimmer, wenn Sie 1080p oder eine höhere Bildrate verwenden.

Sie müssen Ihre Dateien Schritt für Schritt zusammenführen und dabei möglichst wenige Frames im Speicher behalten.

Für eine Operation so einfach wie eine Zusammenführung, sollten Sie nicht mit den Frames selbst umgehen müssen. Sie könnten eine AVMutableComposition erstellen, die individuelle AVAsset s anhängen und dann die zusammengeführte Datei mit AVAssetExportSession exportieren.

+0

Dank Ich hatte den AVAssetExport angeschaut, aber ich muss auch einige Bilder irgendwann zusammenführen. Also warum ich diese Route stattdessen gegangen bin. – Dinalli

+1

Sie können das mit 'AVMutableVideoCompositionLayerInstruction' machen, obwohl es manchmal einfacher erscheint, die Frames direkt zu ändern. –