Проблема с получением буфера сэмпла с помощью copyNextSampleBuffer () - PullRequest
0 голосов
/ 28 июня 2019

Я пытаюсь обработать каждый кадр видео AVAsset с помощью AVAssetReader и AVAssetWriter.Тем не менее, я получаю странную ошибку, и похоже, что я уже сделал то, что просит сделать ошибка.Вот ошибка:

Завершение приложения из-за необработанного исключения «NSInternalInconsistencyException», причина: «- [AVAssetReaderTrackOutput copyNextSampleBuffer] не может скопировать следующий пример буфера до добавления этого вывода в экземпляр AVAssetReader (используя -addOutput :) и вызывая -startReading для этого средства чтения ресурсов '

Я использую Xcode 11 beta 2 ... это может вызвать проблемы?

Будет лиочень ценю любые идеи / помощь.

    //MAKE WRITER
    var writer: AVAssetWriter
    do {
        writer = try AVAssetWriter(outputURL: url, fileType: .mov)
    } catch {
        Helper.problem(error.localizedDescription, #line)
        return
    }

    //MAKE READER
    var reader: AVAssetReader
    do {
        reader = try AVAssetReader(asset: composition)
    } catch {
        Helper.problem(error.localizedDescription, #line)
        return
    }

    //READER OUTPUTS
    guard let videoAssetTrack = composition.tracks(withMediaType: .video).first else { return }
    let videoTrackOutput = AVAssetReaderTrackOutput(track: videoAssetTrack, outputSettings: [String(kCVPixelBufferPixelFormatTypeKey): NSNumber(value: kCVPixelFormatType_32BGRA)])
    videoTrackOutput.alwaysCopiesSampleData = false

    guard let audioAssetTrack = composition.tracks(withMediaType: .audio).first else { return }
    let audioTrackOutput = AVAssetReaderTrackOutput(track: audioAssetTrack, outputSettings: nil)
    audioTrackOutput.alwaysCopiesSampleData = false


    //WRITER INPUTS
    let audioWriterInput = AVAssetWriterInput(mediaType: .audio, outputSettings: nil)
    audioWriterInput.expectsMediaDataInRealTime = true

    let videoWriterInput = AVAssetWriterInput(mediaType: .video, outputSettings: [AVVideoCodecKey: AVVideoCodecType.hevc, AVVideoWidthKey: 1080, AVVideoHeightKey: 1920])
    videoWriterInput.expectsMediaDataInRealTime = true


    if writer.canAdd(videoWriterInput) && writer.canAdd(audioWriterInput) && reader.canAdd(videoTrackOutput) && reader.canAdd(audioTrackOutput) {
        writer.add(videoWriterInput)
        writer.add(audioWriterInput)
        reader.add(videoTrackOutput)
        reader.add(audioTrackOutput)


        writer.startWriting()
        reader.startReading()
        writer.startSession(atSourceTime: .zero)


        let mediaQueue = DispatchQueue(label: "mediaInputQueue")

        let dispatchGroup = DispatchGroup()

        dispatchGroup.enter()
        audioWriterInput.requestMediaDataWhenReady(on: mediaQueue) {
            while audioWriterInput.isReadyForMoreMediaData {
                let nextSampleBuffer = audioTrackOutput.copyNextSampleBuffer()

                if let nextSampleBuffer = nextSampleBuffer {
                    audioWriterInput.append(nextSampleBuffer)
                } else {
                    audioWriterInput.markAsFinished()
                    dispatchGroup.leave()
                    break
                }
            }
        }

        dispatchGroup.enter()
        videoWriterInput.requestMediaDataWhenReady(on: mediaQueue) {
            while videoWriterInput.isReadyForMoreMediaData {
                let nextSampleBuffer = videoTrackOutput.copyNextSampleBuffer()

                if let nextSampleBuffer = nextSampleBuffer {
                    videoWriterInput.append(nextSampleBuffer)
                } else {
                    videoWriterInput.markAsFinished()
                    dispatchGroup.leave()
                    break
                }
            }
        }



        dispatchGroup.notify(queue: mediaQueue) {
            print("finished writing!")
            completion(url)
        }
    }
...