使用 AVAssetWriter 和 CoreML 的相机上的 FPS 不一致

Posted

技术标签:

【中文标题】使用 AVAssetWriter 和 CoreML 的相机上的 FPS 不一致【英文标题】:FPS not consistent on Camera using AVAssetWriter and CoreML 【发布时间】:2021-12-05 02:19:17 【问题描述】:

我正在尝试创建一个应用程序,该应用程序可以使用 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))")
        
        
        

    

【问题讨论】:

【参考方案1】:

如果您想在每一帧都运行动作分类,那么执行动作分类会非常昂贵,因此它可能会影响应用程序的整体性能(包括视频片段 FPS)。我不知道您需要多久进行一次预测,但我建议您尝试最多每秒运行 2-3 次动作分类器,看看是否有帮助。

每帧运行动作分类器不会对您的分类产生太大影响,因为您只是将一帧添加到分类器动作窗口中,因此无需如此频繁地运行它。

例如,如果您的动作分类器设置为使用 3s 窗口并针对 30fps 视频进行训练,则您的分类基于 3 * 30 = 90 帧。一帧不会有什么不同。

还要确保您的 100fps 与您用于训练动作分类器的素材相匹配。否则,您可能会得到错误的预测,因为运行在 30fps 视频上训练的动作分类器会将 100fps 素材中的 1s 视为超过 3,333s。

【讨论】:

以上是关于使用 AVAssetWriter 和 CoreML 的相机上的 FPS 不一致的主要内容,如果未能解决你的问题,请参考以下文章

为啥使用 AVCaptureSession、AVAssetWriter 和 AVPlayer 录制和回放视频会卡顿?

如何使用 AVAssetReader 和 AVAssetWriter 创建 AAC 文件?

我可以使用 AVAssetWriter 代替 AVExportSession 吗?

使用 AVCaptureSession 和 AVAssetWriter 在翻转相机时无缝录制音频

如何使用 AVAssetWriter 在 ios 中写入 AAC 音频?

从使用 AVAssetWriter 创建的视频生成缩略图