小编典典

AVAssetWriter AVVideoExpectedSourceFrameRateKey(帧频)已忽略

swift

我和我的团队正在尝试通过更改视频帧频来对视频文件进行重新编码,以使其更具“格调”感。我们将以下属性用于AVAssetWriterInput

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

但是输出视频仍以正常帧频播放(使用播放AVPlayer)。

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

朝着正确方向的任何帮助都将受到高度重视。 我们卡住了。此致Roi


阅读 876

收藏
2020-07-07

共1个答案

小编典典

您可以控制附加到每个样品的时间AVAssetWriterInput直接CMSampleBufferCreateCopyWithNewTiming

您需要在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)
2020-07-07