简体   繁体   English

AVPlayerItem.loadedTimeRanges 上的 KVO 可能吗?

[英]Is KVO on AVPlayerItem.loadedTimeRanges possible?

Apples documentation alludes to it, but how do you set up key-value observation for the loadedTimeRanges property of AVPlayerItem? Apples 文档中提到了它,但是如何为 AVPlayerItem 的 loadedTimeRanges 属性设置键值观察? That property is an NSArray that doesn't change, so you can't just use playerItem addObserver:self forKeyPath:@"loadedTimeRanges ...该属性是一个不会改变的 NSArray,所以你不能只使用playerItem addObserver:self forKeyPath:@"loadedTimeRanges ...

Or is there another way to get notifications or updates whenever this changes?或者有没有其他方法可以在这种情况发生变化时获得通知或更新?

Actually, I'm using KVO for loadedTimeRanges without any trouble.实际上,我将 KVO 用于加载的时间范围,没有任何问题。 Maybe you're just not setting the right options?也许您只是没有设置正确的选项? The following is a very slight modification of some of the code in Apple's AVPlayerDemo , and it's working quite nicely for me.下面是对 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]);
    }
}

Right.对。 loadedTimeRanges doesn't change but the objects inside of it change. loadTimeRanges 不会改变,但它里面的对象会改变。 You could setup a timer to run every second (or so) and inspect the values inside of loadedTimeRanges.您可以设置一个计时器以每秒(左右)运行一次并检查loadedTimeRanges 中的值。 Then you'll see the changes you are looking for.然后您将看到您正在寻找的更改。

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));
                                         }
                                     }];

Update to Swift 4.0 and later:更新到 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
    }
}     

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM