技术问答 QA1820 如何使用 AVPlayer seekToTime 实现流畅的视频擦除:?
问:我的应用程序允许用户使用滑块控件结合 AVPlayer seekToTime 来擦洗视频文件:但是视频帧的显示存在相当大的延迟。如何实现更顺畅的擦洗?
A: 避免快速连续调用 AVPlayer seekToTime:。这将取消正在进行的查找,导致大量查找而不是大量显示目标帧。相反,使用 AVPlayer seekToTime: 的完成处理程序变体:并等待正在进行的搜索首先完成,然后再发出另一个。清单 1 和清单 2 给出了这种技术的示例(注意:这些示例假设已经创建了一个有效的播放器对象,并且播放器的当前项目状态正在通过键值观察进行维护。有关更多信息,请参阅 AV Foundation 编程指南)。
使用 AVPlayer seekToTime 的完成处理程序变体:用于更平滑的擦洗(Objective-C)。
@import AVFoundation;
@interface MyClass ()
{
AVPlayer player;
BOOL isSeekInProgress;
CMTime chaseTime;
AVPlayerStatus playerCurrentItemStatus; // your player.currentItem.status
...
}
@implementation MyClass
...
- (void)stopPlayingAndSeekSmoothlyToTime:(CMTime)newChaseTime
{
[self->player pause];
if (CMTIME_COMPARE_INLINE(newChaseTime, !=, self->chaseTime))
{
self->chaseTime = newChaseTime;
if (!self->isSeekInProgress)
[self trySeekToChaseTime];
}
}
- (void)trySeekToChaseTime
{
if (playerCurrentItemStatus == AVPlayerItemStatusUnknown)
{
// wait until item becomes ready (KVO player.currentItem.status)
}
else if (playerCurrentItemStatus == AVPlayerItemStatusReadyToPlay)
{
[self actuallySeekToTime];
}
}
- (void)actuallySeekToTime
{
self->isSeekInProgress = YES;
CMTime seekTimeInProgress = self->chaseTime;
[self->player seekToTime:seekTimeInProgress toleranceBefore:kCMTimeZero
toleranceAfter:kCMTimeZero completionHandler:
^(BOOL isFinished)
{
if (CMTIME_COMPARE_INLINE(seekTimeInProgress, ==, self->chaseTime))
self->isSeekInProgress = NO;
else
[self trySeekToChaseTime];
}];
}
@end