[英]Seamless audio recording while flipping camera, using AVCaptureSession & AVAssetWriter
[英]FPS not consistent on Camera using AVAssetWriter and CoreML
我正在尝试创建一个应用程序,该应用程序可以使用 AVAssetWriter 以 100 FPS 的速度录制视频,并使用 Create ML 中的 ActionClassifier 检测一个人是否正在执行操作。 但是当我尝试将 2 放在一起时,在记录和检测动作时 FPS 会下降到 30。
如果我自己进行录制,那么它会以 100 FPS 的速度录制。
我可以通过设备配置将相机的 FPS 设置为 100 FPS。
捕获输出功能设置
func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
bufferImage = sampleBuffer
guard let calibrationData = CMGetAttachment(sampleBuffer, key: kCMSampleBufferAttachmentKey_CameraIntrinsicMatrix, attachmentModeOut: nil) as? Data else {
return
}
cameraCalibrationMatrix = calibrationData.withUnsafeBytes { $0.pointee }
if self.isPredictorActivated == true {
do {
let poses = try predictor.processFrame(sampleBuffer)
if (predictor.isReadyToMakePrediction) {
let prediction = try predictor.makePrediction()
let confidence = prediction.confidence * 100
DispatchQueue.main.async {
self.predictionLabel.text = prediction.label + " " + String(confidence.rounded(toPlaces: 0))
if (prediction.label == "HandsUp" && prediction.confidence > 0.85) {
print("Challenging")
self.didChallengeVideo()
}
}
}
} catch {
print(error.localizedDescription)
}
}
let presentationTimeStamp = CMSampleBufferGetPresentationTimeStamp(sampleBuffer)
if assetWriter == nil {
createWriterInput(for: presentationTimeStamp)
} else {
let chunkDuration = CMTimeGetSeconds(CMTimeSubtract(presentationTimeStamp, chunkStartTime))
// print("Challenge\(isChallenging)")
if chunkDuration > 1500 || isChallenging {
assetWriter.endSession(atSourceTime: presentationTimeStamp)
// make a copy, as finishWriting is asynchronous
let newChunkURL = chunkOutputURL!
let chunkAssetWriter = assetWriter!
chunkAssetWriter.finishWriting {
print("finishWriting says: \(chunkAssetWriter.status.rawValue) \(String(describing: chunkAssetWriter.error))")
print("queuing \(newChunkURL)")
print("Chunk Duration: \(chunkDuration)")
let asset = AVAsset(url: newChunkURL)
print("FPS of CHUNK \(asset.tracks.first?.nominalFrameRate)")
if self.isChallenging {
self.challengeVideoProcess(video: asset)
}
self.isChallenging = false
}
createWriterInput(for: presentationTimeStamp)
}
}
if !assetWriterInput.append(sampleBuffer) {
print("append says NO: \(assetWriter.status.rawValue) \(String(describing: assetWriter.error))")
}
}
如果您想每帧都运行它,那么执行动作分类非常昂贵,因此它可能会影响应用程序的整体性能(包括视频片段 FPS)。 我不知道您需要多久进行一次预测,但我建议您尝试每秒最多运行 2-3 次 Action Classifier,看看是否有帮助。
每一帧运行动作分类器不会改变你的分类,因为你只向分类器动作窗口添加了一帧,所以没有必要经常运行它。
例如,如果您的动作分类器设置为窗口 3s 并在 30fps 视频上进行训练,则您的分类基于 3 * 30 = 90 帧。 一帧不会有什么不同。
还要确保您的 100fps 与您用于训练动作分类器的素材相匹配。 否则,您可能会得到错误的预测,因为运行在 30fps 视频上训练的动作分类器会将 100fps 素材的 1 秒视为超过 3,333 秒。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.