Apples文档提到了它,但是如何为AVPlayerItem的loadedTimeRanges属性设置键值观察?该属性是一个不会改变的NSArray,所以你不能只使用playerItem addObserver:self forKeyPath:@"loadedTimeRanges ...
还是有其他方法可以在发生变化时收到通知或更新吗?
答案 0 :(得分:7)
实际上,我正在使用KVO for loadedTimeRanges而没有任何麻烦。也许你只是没有设置正确的选项?以下是对Apple AVPlayerDemo中某些代码的轻微修改,它对我来说非常好。
//somewhere near the top of the file
NSString * const kLoadedTimeRangesKey = @"loadedTimeRanges";
static void *AudioControllerBufferingObservationContext = &AudioControllerBufferingObservationContext;
- (void)someFunction
{
// ...
//somewhere after somePlayerItem has been initialized
[somePlayerItem addObserver:self
forKeyPath:kLoadedTimeRangesKey
options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
context:AudioControllerBufferingObservationContext];
// ...
}
- (void)observeValueForKeyPath:(NSString*) path
ofObject:(id)object
change:(NSDictionary*)change
context:(void*)context
{
if (context == AudioControllerBufferingObservationContext)
{
NSLog(@"Buffering status: %@", [object loadedTimeRanges]);
}
}
答案 1 :(得分:2)
右。 loadedTimeRanges不会更改,但其中的对象会更改。您可以设置计时器每秒运行一次(左右)并检查loadedTimeRanges内的值。然后你会看到你正在寻找的变化。
dispatch_queue_t queue = dispatch_queue_create("playerQueue", NULL);
[player addPeriodicTimeObserverForInterval:CMTimeMake(1, 1)
queue:queue
usingBlock:^(CMTime time) {
for (NSValue *time in player.currentItem.loadedTimeRanges) {
CMTimeRange range;
[time getValue:&range];
NSLog(@"loadedTimeRanges: %f, %f", CMTimeGetSeconds(range.start), CMTimeGetSeconds(range.duration));
}
}];
答案 2 :(得分:0)
更新到Swift 4.0及更高版本:
loadedTimeRangesObserver = player.observe(\AVPlayer.currentItem?.loadedTimeRanges, options: [.new, .initial]) { [unowned self] (player, change) in
DispatchQueue.main.async {
guard let ranges = change.newValue as? [CMTimeRange] else { return }
// update UI
}
}