AVPlayerItem.loadedTimeRanges 上的 KVO 可能吗?

发布于 2024-12-29 04:54:24 字数 208 浏览 3 评论 0原文

Apple 文档提到了这一点,但是如何为 AVPlayerItem 的 returnedTimeRanges 属性设置键值观察?该属性是一个不会更改的 NSArray,因此您不能只使用 playerItem addObserver:self forKeyPath:@"loadedTimeRanges ...

或者是否有其他方法可以在发生更改时获取通知或更新?

Apples documentation alludes to it, but how do you set up key-value observation for the loadedTimeRanges property of AVPlayerItem? That property is an NSArray that doesn't change, so you can't just use playerItem addObserver:self forKeyPath:@"loadedTimeRanges ...

Or is there another way to get notifications or updates whenever this changes?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

南街女流氓 2025-01-05 04:54:24

实际上,我使用 KVO 来加载时间范围没有任何问题。也许您只是没有设置正确的选项?以下是对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]);
    }
}

Actually, I'm using KVO for loadedTimeRanges without any trouble. 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.

//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]);
    }
}
扮仙女 2025-01-05 04:54:24

更新到 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
    }
}     

Update to Swift 4.0 and later:

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
    }
}     
陪我终i 2025-01-05 04:54:24

正确的。 loadTimeRanges 不会改变,但其中的对象会改变。您可以设置一个计时器每秒运行一次(左右)并检查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));
                                         }
                                     }];

Right. loadedTimeRanges doesn't change but the objects inside of it change. You could setup a timer to run every second (or so) and inspect the values inside of 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));
                                         }
                                     }];
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文