Приостановка видео в AVAssetwriter - PullRequest
0 голосов
/ 20 октября 2019

В моем приложении мне нужно распознать лицо и записать 3 комплекта видео каждые 5 секунд. В основном для передней, левой и правой лица. Я использовал Firebase MLKit, чтобы успешно распознавать лица, и все работает нормально, теперь мне просто нужно записать видео. Таким образом, когда пользователь выбирает функцию записи, у него есть возможность записать видео, поэтому, если передняя грань определена правильно, начинается 5-секундная запись, и через 5 секунд пользователю предлагается изменить направление лица вправо, а затем выполнить запись и то же для левой стороны. Я использую AVAssetWriter для записи. Я могу записать, но проблема в окончательном выводе, который включает полную продолжительность, включая время, когда вторая запись не была начата. Итак, мой текущий конечный результат имеет 5-секундное видео на передней панели, после чего кадр показывается как застрявший на некоторое время, затем воспроизводится следующее 5-секундное видео и так далее. Итак, общая продолжительность теперь показывает более 1 минуты! Похоже, AVAssetWriter не сделал паузу, я новичок в использовании AVAssetWriter, поэтому не уверен, что я делаю не так, ниже приведен мой код для справки. В основном я использую переменную isRecording, и когда запись не активна, я не вызываю метод для записи кадров.

fileprivate var videoWriterInput: AVAssetWriterInput!

func captureOutput(
    _ output: AVCaptureOutput,
    didOutput sampleBuffer: CMSampleBuffer,
    from connection: AVCaptureConnection
) {
    guard let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else {
        print("Failed to get image buffer from sample buffer.")
        return
    }
    if isRecording {
            let writable = canWrite()
            if writable,
                sessionAtSourceTime == nil {
                sessionAtSourceTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer)
                videoWriter.startSession(atSourceTime: sessionAtSourceTime!)
            }

            if writable,
                (videoWriterInput.isReadyForMoreMediaData) {
                videoWriterInput.append(sampleBuffer)
            }
        }

}

func startRecording() {
        guard !isRecording else { return }
        isRecording = true
        sessionAtSourceTime = nil
        setUpWriter()
        startTimer()
    }

func stopRecording() {
        videoWriterInput.markAsFinished()
        videoWriter.finishWriting { [weak self] in
            self?.sessionAtSourceTime = nil
            if self?.videoWriter.status == .writing {
                print("status writing")
            } else if self?.videoWriter.status == .failed {
                print("status failed")
            } else if self?.videoWriter.status == .cancelled {
                print("status cancelled")
            } else if self?.videoWriter.status == .unknown {
                print("status unknown")
            } else {
                print("status completed")
                self?.showVideo()
            }
        }
        captureSession.stopRunning()
    }

func setUpWriter() {
        do {
            outputFileLocation = videoFileLocation()
            videoWriter = try AVAssetWriter(outputURL: outputFileLocation, fileType: AVFileType.mp4)
            let vidSize = getVideoSize()
                videoWriterInput = AVAssetWriterInput(mediaType: AVMediaType.video, outputSettings: [
                    AVVideoCodecKey : AVVideoCodecH264,
                    AVVideoWidthKey : NSNumber(value: Float(vidSize.width)),
                    AVVideoHeightKey : NSNumber(value: Float(vidSize.height)),
                    AVVideoCompressionPropertiesKey : [
                        AVVideoAverageBitRateKey : 2300000,
                    ],
                    ])

            videoWriterInput.expectsMediaDataInRealTime = true
            videoWriterInput.transform = getVideoTransform()

            if videoWriter.canAdd(videoWriterInput) {
                videoWriter.add(videoWriterInput)
                print("video input added")
            } else {
                print("no input added")
            }
            videoWriter.startWriting()
        } catch let error {
            debugPrint(error.localizedDescription)
        }
    }

    func canWrite() -> Bool {
        return isRecording && videoWriter != nil && videoWriter?.status == .writing
    }
...