AVAssetWriter AVVideoExpectedSourceFrameRateKey(帧率)被忽略

AVAssetWriter AVVideoExpectedSourceFrameRateKey (frame rate) ignored

我和我的团队正在尝试通过更改视频帧速率将视频文件重新编码为更 "gify" 的感觉。我们正在为 AVAssetWriterInput 使用以下属性:

let videoSettings:[String:Any] = [
            AVVideoCodecKey: AVVideoCodecH264,
            AVVideoHeightKey: videoTrack.naturalSize.height,
            AVVideoWidthKey: videoTrack.naturalSize.width,
            AVVideoCompressionPropertiesKey: [AVVideoExpectedSourceFrameRateKey: NSNumber(value: 12)]                                         
        ]

但输出视频继续以正常帧率播放(使用 AVPlayer 播放)。

降低视频帧率的正确方法是什么? (例如 12)。

任何正确方向的帮助都将受到高度认可。我们卡住了。 最好的祝福, 投资回报率

您可以使用 CMSampleBufferCreateCopyWithNewTiming 直接控制附加到 AVAssetWriterInput 的每个样本的时间。

您需要在您提供的CMSampleTimingInfo中调整时间。 使用 CMSampleBufferGetOutputSampleTimingInfoArray 检索当前时序信息,遍历每个样本的持续时间并计算正确的持续时间以获得每秒 12 帧,并调整呈现和解码时间戳以匹配这个新的持续时间。 然后你制作你的副本并将其提供给你的作者输入。

假设您有 existingSampleBuffer:

CMSampleBufferRef sampleBufferToWrite = NULL;
CMSampleTimingInfo sampleTimingInfo = {0};

CMSampleBufferGetSampleTimingInfo(existingSampleBuffer, 0, &sampleTimingInfo);

// modify duration & presentationTimeStamp
sampleTimingInfo.duration = CMTimeMake(1, 12) // or whatever frame rate you desire
sampleTimingInfo.presentationTimeStamp = CMTimeAdd(previousPresentationTimeStamp, sampleTimingInfo.duration);
previousPresentationTimeStamp = sampleTimingInfo.presentationTimeStamp; // should be initialised before passing here the first time

OSStatus status = CMSampleBufferCreateCopyWithNewTiming(kCFAllocatorDefault, existingSampleBuffer, 1, &sampleTimingInfo, &sampleBufferToWrite);

if (status == noErr) {
    // you can write sampleBufferToWrite
}

我在这段代码中做了一些假设:

  • SampleBuffer 只包含一个样本
  • SampleBuffer 包含未压缩的视频(否则,您还需要处理 decodeTimeStamp)