avassetwriter startWriting()崩溃

时间:2016-03-22 11:50:09

标签: ios swift avfoundation avassetwriter

我正在尝试制作ios录音机应用程序,但有时候(非常罕见)我得到了奇怪的崩溃

public func captureOutput(captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, fromConnection connection: AVCaptureConnection!) {

    guard CMSampleBufferDataIsReady(sampleBuffer) else { return }
    if assetWriter == nil                              { return }

    let lastSampleTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer)

    if assetWriter.status == .Unknown {
        if assetWriter.startWriting() {
            assetWriter.startSessionAtSourceTime(lastSampleTime)
        } else {
            print("assetWriter.startWriting error")
            return
        }
    }

    guard assetWriter.status == .Writing else { return }

    if captureOutput == videoOutput && videoInput.readyForMoreMediaData {

        if !videoInput.appendSampleBuffer(sampleBuffer) {
            print("Unable to write to video input")
        }
    } else if captureOutput == audioOutput && audioInput.readyForMoreMediaData {

        if !audioInput.appendSampleBuffer(sampleBuffer) {
            print("Unable to write to audio input")
        }
    }
}

应用程序在assetWriter.startWriting()方法上停止。我得到的错误:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[AVAssetWriterFailedTerminalHelper initWithConfigurationState:terminalError:] invalid parameter not satisfying: terminalError != ((void *)0)'

编辑:您可以在下面看到设置AssetWriter代码:

private func initWriter(url: NSURL) throws {

    do {
        assetWriter = try AVAssetWriter(URL: url, fileType: AVFileTypeMPEG4)

        let videoSettings = videoOutput.recommendedVideoSettingsForAssetWriterWithOutputFileType(AVFileTypeMPEG4) as! [String: AnyObject]

        guard assetWriter.canApplyOutputSettings(videoSettings, forMediaType: AVMediaTypeVideo)
        else {
            throw NSError(domain: "com.conn.VideoKit", code: 0, userInfo: [NSLocalizedDescriptionKey: "Couldn't apply video output settings"])
        }

        videoInput = AVAssetWriterInput(mediaType: AVMediaTypeVideo, outputSettings: videoSettings)
        videoInput.transform = CGAffineTransformIdentity
        videoInput.transform = CGAffineTransformMakeRotation( CGFloat( 270 * M_PI ) / 180.0 )
        videoInput.expectsMediaDataInRealTime = true

        if assetWriter.canAddInput(videoInput) {
            assetWriter.addInput(videoInput)
        } else {
            print("Cannot add video input to asset writer")
        }

        let audioSettings = audioOutput.recommendedAudioSettingsForAssetWriterWithOutputFileType(AVFileTypeMPEG4) as! [String: AnyObject]

        guard assetWriter.canApplyOutputSettings(audioSettings, forMediaType: AVMediaTypeAudio)
        else {
            throw NSError(domain: "com.conn.VideoKit", code: 0, userInfo: [NSLocalizedDescriptionKey: "Couldn't apply audio output settings"])
        }

        audioInput = AVAssetWriterInput(mediaType: AVMediaTypeAudio, outputSettings: audioSettings)
        audioInput.expectsMediaDataInRealTime = true
        if assetWriter.canAddInput(audioInput) {
            assetWriter.addInput(audioInput)
        } else {
            print("Cannot add audio input to asset writer")
        }
    } catch let error { throw error }
}

1 个答案:

答案 0 :(得分:0)

问题在于缓冲。我不得不为视频/音频使用分离的同意队列:

let videoConcurrentQueue = dispatch_queue_create("com.videoConcurrentQueue", DISPATCH_QUEUE_CONCURRENT)
let audioConcurrentQueue = dispatch_queue_create("com.audioConcurrentQueue", DISPATCH_QUEUE_CONCURRENT)
videoOutput.setSampleBufferDelegate(self, queue: videoConcurrentQueue)
audioOutput.setSampleBufferDelegate(self, queue: audioConcurrentQueue)