在我的应用中,我需要检测脸部并记录每5秒持续时间的3组视频。基本上用于前,左和右脸。我已经使用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
}