在 iOS 中不使用播放方法显示视频帧
Showing video frames without using play method in iOS
我想了解视频文件中 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),但没有用。
请提出您的建议。
谢谢。
每秒帧数在视频文件中通常不是一个常量 - 帧数在发生时发生。如果您想知道那是什么时候,您可以使用 AVAssetReader
和 AVAssetReaderTrackOutput
类 检查帧的显示时间戳:
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];
}
我想了解视频文件中 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),但没有用。
请提出您的建议。 谢谢。
每秒帧数在视频文件中通常不是一个常量 - 帧数在发生时发生。如果您想知道那是什么时候,您可以使用 AVAssetReader
和 AVAssetReaderTrackOutput
类 检查帧的显示时间戳:
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];
}