- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用 AVAssetWriter 通过委托(delegate)从 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
}
最佳答案
苹果支持的回复:
如果你真的想用 AVAssetWriter 改变电影的帧速率,那么你必须在写出每个视频帧时正确设置时间戳。
一种方法是使用 AVAssetWriterInputPixelBufferAdaptor 对象。例如,您使用 AVAssetWriterInputPixelBufferAdaptor 将打包为 CVPixelBuffer 对象的视频样本附加到单个 AVAssetWriterInput 对象。
初始化代码看起来像这样:
[dictionary setObject:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA] forKey:(NSString*) kCVPixelBufferPixelFormatTypeKey];
...
AVAssetWriterInputPixelBufferAdaptor *avAdaptor = [[AVAssetWriterInputPixelBufferAdaptor alloc] initWithAssetWriterInput:assetWriterInput sourcePixelBufferAttributes:dictionary];
然后,要为新电影指定特定的播放帧速率(例如 15 fps),时间戳(表示为 CMTime 结构)应指定为相隔 1/15 秒。这是一个代码片段:
CMTime frameTime = CMTimeMake(1, 15);
result = [avAdaptor appendPixelBuffer:buffer withPresentationTime:frameTime];
另一种方法是使用 CMSampleBufferCreateCopyWithNewTiming 重新定时缓冲区,然后将它们传递给 AVAssetWriter。这是一个粗略的概述:
CMSampleTimingInfo sampleTimingInfo = {0};
CMSampleBufferRef newBuffer = NULL;
CMSampleBufferGetSampleTimingInfo(existingSampleBuffer, 0, &sampleTimingInfo);
sampleTimingInfo.duration = CMTimeMake(1, 30) // Specify new frame rate.
sampleTimingInfo.presentationTimeStamp = CMTimeAdd(previousPresentationTimeStamp, sampleTimingInfo.duration);
previousPresentationTimeStamp = sampleTimingInfo.presentationTimeStamp;
OSStatus status = CMSampleBufferCreateCopyWithNewTiming(kCFAllocatorDefault, existingSampleBuffer, 1, &sampleTimingInfo, &newBuffer);
if (status == noErr) {
/* Write your newBuffer here */
}
//////////
我尝试使用“CMSampleBufferCreateCopyWithNewTiming”。 FPS 已正确设置。但是得到了慢动作输出。以下是我的代码。
autoreleasepool {
//set FPS
var sampleTimingInfo: CMSampleTimingInfo = CMSampleTimingInfo(duration: kCMTimeInvalid, presentationTimeStamp: CMTime(), decodeTimeStamp: kCMTimeInvalid)
var newBuffer: CMSampleBuffer! = nil
CMSampleBufferGetSampleTimingInfo(sampleBufferMain, 0, &sampleTimingInfo);
sampleTimingInfo.duration = CMTimeMake(1, 15) // Specify new frame rate.
sampleTimingInfo.presentationTimeStamp = CMTimeAdd(self.previousPresentationTimeStamp, sampleTimingInfo.duration)
self.previousPresentationTimeStamp = sampleTimingInfo.presentationTimeStamp
let status: OSStatus = CMSampleBufferCreateCopyWithNewTiming(kCFAllocatorDefault, sampleBufferMain, 1, &sampleTimingInfo, &newBuffer);
if status == noErr {
let appendResult = self.videoWriterInput?.append(newBuffer)
if appendResult == false {
printError("writer status: \(String(describing: self.videoWriter?.status.rawValue))")
printError("writer error: \(self.videoWriter?.error.debugDescription ?? "")")
}
} else {
print("write error")
}
}
关于ios - AVAssetWriter - 设置自定义帧率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54435281/
我使用 QBFC v13 和 Delphi XE6。 目标是从我的应用程序创建 Estimate 并将其参数设置到 QuickBooks 中。 我从 QBFC13 导入类型库并将其添加到我的项目中。
我有一个数据库,其中有很多格式不正确的地址。在这个地址中,我只有一个街道地址或带有城市名称的街道。在我的应用程序中,用户选择一些类别,然后我想在 map 上显示例如 50,100,300 等地址。(不
在大多数软件项目中,缺陷源自需求、设计、编码和缺陷更正。根据我的经验,大多数缺陷都源于编码阶段。 我有兴趣了解软件开发人员使用哪些实用方法来降低缺陷注入(inject)率。 我已经看到以下方法的使用取
我正在使用实时 API 中的标签订阅构建一个应用程序,并且有一个与容量规划相关的问题。我们可能有大量用户同时发布到订阅的主题标签,因此问题是 API 实际发布到我们的订阅处理端点的频率是多少?例如,如
尝试使用 NULLIF 或 IFNULL 函数,但仍收到被零除的消息。 SELECT client_id ,COUNT(distinct CASE WHEN status = 'failed' THE
我目前正在开发一个使用 Django-rest-framework 制作的 API。我必须根据每个用户组设置限制率。 我们目前使用默认配置的 memcached 作为缓存后端,即按站点缓存。 在使用
我认为有时在神经网络(特别是一般对抗网络)训练期间改变丢失率可能是一个好主意,从高丢失率开始,然后线性地将丢失率降低到零。您认为这有意义吗?如果是的话,是否有可能在 tensorflow 中实现这一点
我有一个 Windows Server 2008,Plesk 运行着两个网站。有时服务器运行缓慢,并且有一个 named.exe 进程使 CPU 峰值达到 100%。它持续很短的时间,过一会儿它又来了
我正在使用 scikit-learn 随机森林分类器,我想通过将成功投票所需的树数量从大于 50% 增加到 75% 来降低 FP 率,在阅读文档后我不这样做确定如何做到这一点。有没有人有什么建议。 (
当我连续按下按键事件(字母 k)时,为什么以下按键事件不会减慢 3000 密耳?如果我按住手指,计数会迅速增加,因为 mcount 上没有 setTimeout。这是为什么?每次计数之间应该有延迟,但
我是一名优秀的程序员,十分优秀!