使用 AVAssetWriter 在保持相同 Length/Duration 的同时降低视频帧率
Reduce Video Frame Rate While Keeping Same Length/Duration Using AVAssetWriter
我们将从一个基本示例开始:假设我们有一个时长为 6 秒、帧率为 30 FPS(总共 180 帧)的视频。我想在保持视频 6 秒的同时将 FPS 降低到 15。这意味着我需要 remove/drop 视频帧(6 秒 * 15 FPS = 90 帧)。
我和我的团队可以使用 AVAssetWriter
更改视频帧速率,但这只会让视频变长。我们尝试跳过以下帧:
while(videoInput.isReadyForMoreMediaData){
let sample = assetReaderVideoOutput.copyNextSampleBuffer()
if (sample != nil){
if counter % 2 == 0 {
continue // skip frame
}
videoInput.append(sampleBufferToWrite!)
}
但是不行。作者强制初始样本计数,即使我们跳过它也是如此。
最重要的是,如何在保持相同时长的同时降低视频帧率(我们正在尝试创建 GIFY 视频感觉)?
如有任何帮助,我们将不胜感激!
此致,Roi
对于每个丢失的帧,您需要通过将要编写的示例的持续时间加倍来进行补偿。
while(videoInput.isReadyForMoreMediaData){
if let sample = assetReaderVideoOutput.copyNextSampleBuffer() {
if counter % 2 == 0 {
let timingInfo = UnsafeMutablePointer<CMSampleTimingInfo>.allocate(capacity: 1)
let newSample = UnsafeMutablePointer<CMSampleBuffer?>.allocate(capacity: 1)
// Should check call succeeded
CMSampleBufferGetSampleTimingInfo(sample, 0, timingInfo)
timingInfo.pointee.duration = CMTimeMultiply(timingInfo.pointee.duration, 2)
// Again, should check call succeeded
CMSampleBufferCreateCopyWithNewTiming(nil, sample, 1, timingInfo, newSample)
videoInput.append(newSample.pointee!)
}
counter = counter + 1
}
}
我们将从一个基本示例开始:假设我们有一个时长为 6 秒、帧率为 30 FPS(总共 180 帧)的视频。我想在保持视频 6 秒的同时将 FPS 降低到 15。这意味着我需要 remove/drop 视频帧(6 秒 * 15 FPS = 90 帧)。
我和我的团队可以使用 AVAssetWriter
更改视频帧速率,但这只会让视频变长。我们尝试跳过以下帧:
while(videoInput.isReadyForMoreMediaData){
let sample = assetReaderVideoOutput.copyNextSampleBuffer()
if (sample != nil){
if counter % 2 == 0 {
continue // skip frame
}
videoInput.append(sampleBufferToWrite!)
}
但是不行。作者强制初始样本计数,即使我们跳过它也是如此。
最重要的是,如何在保持相同时长的同时降低视频帧率(我们正在尝试创建 GIFY 视频感觉)?
如有任何帮助,我们将不胜感激!
此致,Roi
对于每个丢失的帧,您需要通过将要编写的示例的持续时间加倍来进行补偿。
while(videoInput.isReadyForMoreMediaData){
if let sample = assetReaderVideoOutput.copyNextSampleBuffer() {
if counter % 2 == 0 {
let timingInfo = UnsafeMutablePointer<CMSampleTimingInfo>.allocate(capacity: 1)
let newSample = UnsafeMutablePointer<CMSampleBuffer?>.allocate(capacity: 1)
// Should check call succeeded
CMSampleBufferGetSampleTimingInfo(sample, 0, timingInfo)
timingInfo.pointee.duration = CMTimeMultiply(timingInfo.pointee.duration, 2)
// Again, should check call succeeded
CMSampleBufferCreateCopyWithNewTiming(nil, sample, 1, timingInfo, newSample)
videoInput.append(newSample.pointee!)
}
counter = counter + 1
}
}