我正在使用 AVAssetWriter 使用委托从 ARSession 写入视频帧。
func session(_ session: ARSession, didUpdate frame: ARFrame)
请参阅下面用于编写图像的代码。
如何根据我们的需要设置自定义帧速率,如 24、30 或 60 等。
在输出设置中,为 AVVideoExpectedSourceFrameRateKey 提供的值为 30。但是我们为它提供的任何值,在使用 VLC 播放器 -> 媒体信息 -> 编解码器详细信息时,始终将“帧速率”设为 60
我应该进行哪些更改来设置所需的帧速率?提前致谢。
func writeImage(_ image: CVPixelBuffer, thisTimestamp: TimeInterval) {
guard let videoDirector = videoWriter else { return }
serialQueue.async(execute: {
let scale = CMTimeScale(NSEC_PER_SEC)
if (!self.seenTimestamps.contains(thisTimestamp)) {
self.seenTimestamps.append(thisTimestamp)
let pts = CMTime(value: CMTimeValue((thisTimestamp) * Double(scale)),
timescale: scale)
var timingInfo = CMSampleTimingInfo(duration: kCMTimeInvalid,
presentationTimeStamp: pts,
decodeTimeStamp: kCMTimeInvalid)
var vidInfo:CMVideoFormatDescription! = nil
CMVideoFormatDescriptionCreateForImageBuffer(kCFAllocatorDefault, image, &vidInfo)
var sampleBuffer:CMSampleBuffer! = nil
CMSampleBufferCreateForImageBuffer(kCFAllocatorDefault, image, true, nil, nil, vidInfo, &timingInfo, &sampleBuffer)
let imageBuffer: CVPixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)!
if self.videoWriterInput == nil {
let width = CVPixelBufferGetWidth(imageBuffer)
let height = CVPixelBufferGetHeight(imageBuffer)
let numPixels: Double = Double(width * height);
let bitsPerPixel = 11.4;
let bitsPerSecond = Int(numPixels * bitsPerPixel)
// add video input
let outputSettings: [String: Any] = [
AVVideoCodecKey : AVVideoCodecType.h264,
AVVideoWidthKey : width,
AVVideoHeightKey : height,
AVVideoCompressionPropertiesKey : [
AVVideoExpectedSourceFrameRateKey: 30,
AVVideoAverageBitRateKey : bitsPerSecond,
AVVideoMaxKeyFrameIntervalKey : 1
]
]
self.videoWriterInput = AVAssetWriterInput(mediaType: AVMediaType.video, outputSettings: outputSettings)
self.videoWriterInput?.expectsMediaDataInRealTime = true
guard let input = self.videoWriterInput else { return }
if videoDirector.canAdd(input) {
videoDirector.add(input)
}
videoDirector.startWriting()
}
let writable = self.canWrite()
if writable, self.sessionAtSourceTime == nil {
let timeStamp = CMSampleBufferGetPresentationTimeStamp(sampleBuffer)
self.sessionAtSourceTime = timeStamp
videoDirector.startSession(atSourceTime: timeStamp)
}
if self.videoWriterInput?.isReadyForMoreMediaData == true {
let appendResult = self.videoWriterInput?.append(sampleBuffer)
if appendResult == false {
printDebug("writer status: \(videoDirector.status.rawValue)")
printDebug("writer error: \(videoDirector.error.debugDescription)")
}
}
}
})
}
func canWrite() -> Bool {
return isRecording && videoWriter?.status == .writing
}