gpt4 book ai didi

ios - 使用 AVAssetWriter/AVAssetReader 设置视频帧率的问题

转载 作者:行者123 更新时间:2023-12-04 05:02:53 43 4
gpt4 key购买 nike

情况:
我正在尝试使用一些参数导出视频,例如视频比特率、音频比特率、帧速率、更改视频分辨率等。请注意,我让用户以分数设置视频帧速率;喜欢用户可以设置视频帧速率,比如 23.98。
我用 AVAssetWriter AVAssetReader 对于这个操作。我用 AVAssetWriterInputPixelBufferAdaptor用于写入样本缓冲区。
除了 之外,其他一切都很好。视频帧率 .
我试过的:

  • 设置 AVAssetWriter.movi​​eTimeScale 根据建议 here .这确实会改变视频帧速率,但也会使视频变慢。 ( gist here )
  • 设置 AVVideoExpectedSourceFrameRateKey .这没有帮助。 ( gist here )
  • 设置 AVAssetWriterInput.mediaTimeScale .同样,它会更改视频帧速率,但会像 AVAssetWriter.movi​​eTimeScale 一样使视频变慢。该视频在某些时候显示不同的帧,有时它会粘住并再次恢复。 ( gist here )
  • 使用 AVAssetReaderVideoCompositionOutput 和设置 AVMutableVideoComposition.frameDuration ;就像 SDAVAssetExportSession做。具有讽刺意味的是,使用 SDAVAssetExportSession 代码,视频正在以我想要的正确帧速率导出,但它在我的代码中不起作用。 gist here

  • 我不确定为什么它不适用于我的代码。这种方法的问题是它总是从 AVAssetReaderVideoCompositionOutput.copyNextSampleBuffer() 返回 nil。
  • 使用 手动更改帧的时间戳CMSampleTimingInfo ,如建议 here类似:
  • var sampleTimingInfo = CMSampleTimingInfo()
    var sampleBufferToWrite: CMSampleBuffer?

    CMSampleBufferGetSampleTimingInfo(vBuffer, at: 0, timingInfoOut: &sampleTimingInfo)

    sampleTimingInfo.duration = CMTimeMake(value: 100, timescale: Int32(videoConfig.videoFrameRate * 100))

    sampleTimingInfo.presentationTimeStamp = CMTimeAdd(previousPresentationTimeStamp, sampleTimingInfo.duration)

    previousPresentationTimeStamp = sampleTimingInfo.presentationTimeStamp

    let status = CMSampleBufferCreateCopyWithNewTiming(allocator: kCFAllocatorDefault, sampleBuffer: vBuffer,sampleTimingEntryCount: 1, sampleTimingArray: &sampleTimingInfo, sampleBufferOut: &sampleBufferToWrite)
    使用这种方法,我确实可以将帧速率设置得恰到好处,但它会增加视频持续时间(如该问题答案的评论中所述)。我认为在某些时候我可能不得不丢弃一些帧(如果目标帧速率较低;在大多数情况下我需要降低帧速率)。
    如果我知道如果我想要 30fps,并且我当前的帧速率是 60fps,那么很容易丢弃每一秒帧并相应地设置 SampleBuffer 时间。
    如果我采用这种方法(即设置 23.98 fps),我如何决定丢弃哪个帧,如果目标帧速率更高,复制哪个帧?提醒:帧速率可以是分数。

    最佳答案

    这是一个选择框架的想法。假设源视频的fps是F,目标fps是TF。率 = TF/F
    启动一个变量 n 等于 -rate 并每次添加 rate,
    当 n 的整数部分改变时,选择框架。

    e.g. rate = 0.3
    n: -0.3 0 0.3 0.6 0.9 1.2 1.5 1.8 2.1
    ^ ^ ^
    frame index: 0 1 2 3 4 5 6 7
    select 0 4 7
    float rate = 0.39999f; // TF/F 
    float n = -rate; // to make sure first frame will be selected
    for (int i = 0; i < 100; ++i, n += rate) { // i stands for frame index, take a video with 100 frames as an example
    int m = floor(n);
    int tmp = n+rate;
    // if rate > 1.0 repeat i
    // if rate < 1.0 some of the frames will be dropped
    for (int j = 0; m+j < tmp; ++j) {
    // Use this frame
    printf("%d ", i);
    }
    }

    关于ios - 使用 AVAssetWriter/AVAssetReader 设置视频帧率的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56613335/

    43 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com