В моем приложении мне нужно распознать лицо и записать 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
}