1

我试图了解视频文件中 CMTime 和 fps 的功能。我正在尝试使用 for 循环在 AVPlayer 中呈现视频的每一帧。我知道使用 AVPlayer 的播放方法可以轻松完成此任务。但我想知道帧是如何显示的。我创建了一个 for 循环,并尝试通过不断更新 AVPlayer 的 seekToTime 方法来一一呈现每一帧。我能够开发一个解决方案,但它没有显示所有帧并且视频看起来很生涩。

这是我的代码:

for(float t=0; t < asset.duration.value; t++)
{
    CMTime tt = CMTimeMake(t, asset.duration.timescale);
    [self.player seekToTime:tt];
    NSLog(@"%lld, %d",tt.value, tt.timescale);
}

在这里,player 是 AVPlayer 的实例,asset 是我要呈现的帧的视频资源。我也尝试过使用 CMTimeMakeSeconds(t,asset.duration.timescale),但没有奏效。

请给出你的建议。谢谢你。

4

1 回答 1

0

每秒帧数在视频文件中通常不是常数 - 帧在发生时发生。如果你想知道那是什么时候,你可以使用AVAssetReaderAVAssetReaderTrackOutput类检查帧的表示时间戳:

let reader = try! AVAssetReader(asset: asset)

let videoTrack = asset.tracksWithMediaType(AVMediaTypeVideo)[0]
let trackReaderOutput = AVAssetReaderTrackOutput(track: videoTrack, outputSettings:nil)

reader.addOutput(trackReaderOutput)
reader.startReading()

while let sampleBuffer = trackReaderOutput.copyNextSampleBuffer() {
    // pts shows when this frame is presented
    // relative to the start of the video file
    let pts = CMSampleBufferGetPresentationTimeStamp(sampleBuffer)
}

在您的代码中,您错误地对视频时间线进行采样。以下是您如何以 30 fps 对其进行采样(如上所述,这可能与实际帧边界不对应):

for (CMTime t = kCMTimeZero; CMTimeCompare(t, asset.duration) < 0;  t = CMTimeAdd(t, CMTimeMake(1, 30))) {
    [player seekToTime:t];
}
于 2016-09-24T23:42:01.363 回答