AVAssetWriter错误:结束会话后无法附加媒体数据

时间:2017-01-14 06:15:00

标签: swift avfoundation avassetwriter avasset

使用AVAssetWriter捕获视频时会发生此错误。但是,在finishWriting内部调用AVAssetWriter endVideoCapture之后,又没有再次开始写入的调用,为什么会出现这种情况呢?

正如您在委托函数captureOutput中看到的那样,我们在尝试附加到资产编写者之前检查记录状态。 endVideoCapture.

中的录制状态设置为false
  

可选(错误域= AVFoundationErrorDomain代码= -11862"不能   在结束会议后附加媒体数据"   UserInfo = {NSLocalizedFailureReason =应用程序遇到了   编程错误。,NSLocalizedDescription =操作不是   允许,NSDebugDesc

func startVideoCapture() {
    // Get capture resolution
    let resolution = getCaptureResolution()

    // Return if capture resolution not set
    if resolution.width == 0 || resolution.height == 0 {
        printError("Error starting capture because resolution invalid")
        return
    }

    // If here, start capture
    assetWriter = createAssetWriter(Int(resolution.width), outputHeight: Int(resolution.height))
    let recordingClock = captureSession.masterClock
    assetWriter!.startWriting()
    assetWriter!.startSession(atSourceTime: CMClockGetTime(recordingClock!))

    // Update time stamp
    startTime = CACurrentMediaTime()

    // Update <recording> flag & notify delegate
    recording = true
    delegate?.cameraDidStartVideoCapture()
}


func createAssetWriter(_ outputWidth: Int, outputHeight: Int) -> AVAssetWriter? {
    // Update <outputURL> with temp file to hold video
    let tempPath = gFile.getUniqueTempPath(gFile.MP4File)
    outputURL = URL(fileURLWithPath: tempPath)

    // Return new asset writer or nil
    do {
        // Create asset writer
        let newWriter = try AVAssetWriter(outputURL: outputURL, fileType: AVFileTypeMPEG4)

        // Define video settings
        let videoSettings: [String : AnyObject] = [
            AVVideoCodecKey  : AVVideoCodecH264 as AnyObject,
            AVVideoWidthKey  : outputWidth as AnyObject,
            AVVideoHeightKey : outputHeight as AnyObject,
        ]

        // Add video input to writer
        assetWriterVideoInput = AVAssetWriterInput(mediaType: AVMediaTypeVideo, outputSettings: videoSettings)
        assetWriterVideoInput!.expectsMediaDataInRealTime = true
        newWriter.add(assetWriterVideoInput!)

        // Define audio settings
        let audioSettings : [String : AnyObject] = [
            AVFormatIDKey : NSInteger(kAudioFormatMPEG4AAC) as AnyObject,
            AVNumberOfChannelsKey : 2 as AnyObject,
            AVSampleRateKey : NSNumber(value: 44100.0 as Double)
        ]

        // Add audio input to writer
        assetWriterAudioInput = AVAssetWriterInput(mediaType: AVMediaTypeAudio, outputSettings: audioSettings)
        assetWriterAudioInput!.expectsMediaDataInRealTime = true
        newWriter.add(assetWriterAudioInput!)

        // Return writer
        print("Created asset writer for \(outputWidth)x\(outputHeight) video")
        return newWriter
    } catch {
        printError("Error creating asset writer: \(error)")
        return nil
    }
}


func endVideoCapture() {
    // Update flag to stop data capture
    recording = false

    // Return if asset writer undefined
    if assetWriter == nil {
        return
    }

    // If here, end capture
    // -- Mark inputs as done
    assetWriterVideoInput!.markAsFinished()
    assetWriterAudioInput!.markAsFinished()

    // -- Finish writing
    assetWriter!.finishWriting() {
        self.assetWriterDidFinish()
    }
}

func assetWriterDidFinish() {
    print("Asset writer finished with status: \(getAssetWriterStatus())")

    // Return early on error & tell delegate
    if assetWriter!.error != nil {
        printError("Error finishing asset writer: \(assetWriter!.error)")
        delegate?.panabeeCameraDidEndVideoCapture(videoURL: nil, videoDur: 0, error: assetWriter!.error)
        logEvent("Asset Writer Finish Error", userData: ["Error" : assetWriter!.error.debugDescription])
        return
    }

    // If here, no error so extract video properties & tell delegate
    let videoAsset = AVURLAsset(url: outputURL, options: nil)
    let videoDur = CMTimeGetSeconds(videoAsset.duration)
    let videoTrack = videoAsset.tracks(withMediaType: AVMediaTypeVideo)[0]
    print("Camera created video. Duration: \(videoDur). Size: \(videoTrack.naturalSize). Transform: \(videoTrack.preferredTransform). URL: \(outputURL).")

    // Tell delegate
    delegate?.cameraDidEndVideoCapture(videoURL: outputURL.path, videoDur: videoDur, error: assetWriter!.error)

    // Reset <assetWriter> to nil
    assetWriter = nil
}

func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) {
    // Return if not recording
    if !recording {
        return
    }

    // If here, capture data
    // Write video data?
    if captureOutput == videoOutput && assetWriterVideoInput!.isReadyForMoreMediaData {
        assetWriterVideoQueue!.async {
            self.assetWriterVideoInput!.append(sampleBuffer)
        }
    }

    // No, write audio data?
    if captureOutput == audioOutput && assetWriterAudioInput!.isReadyForMoreMediaData {
        assetWriterAudioQueue!.async {
            self.assetWriterAudioInput!.append(sampleBuffer)
        }
    }
}

0 个答案:

没有答案