ios – 未观察到AVPlayerItem初始timedMetadata(KVO)

ios – 未观察到AVPlayerItem初始timedMetadata(KVO),第1张

概述我有一个处理AVPlayer(和AVPlayerItem)的类,它向状态,时间和timedMetadata报告委托. 除了大约70-80%的时间之外,工作良好,初始timedMetadata不是“观察到的关键值”.但是,在错过timedMetadata的第一个实例之后,似乎没有问题地观察到所有其他timedMetadata. 作为一个临时修复,我已经开始在视频的开头嵌入虚拟的timedMetada 我有一个处理AVPlayer(和AVPlayerItem)的类,它向状态,时间和timedMetadata报告委托.

除了大约70-80%的时间之外,工作良好,初始timedMetadata不是“观察到的关键值”.但是,在错过timedMetadata的第一个实例之后,似乎没有问题地观察到所有其他timedMetadata.

作为一个临时修复,我已经开始在视频的开头嵌入虚拟的timedMetadata标签,除了“踢出轮胎”之外什么都不做,然后一切正常.然而,这看起来非常糟糕.我怀疑我要么以次优的方式设置AVPlayerItem和KVO,要么这里只是一个BUG.

关于为什么会发生这种情况的任何想法都非常感谢!代码如下……

// CL: define constants for the key-value observation contexts.static const Nsstring *ItemStatusContext;static const Nsstring *ItemMetadataContext;static const Nsstring *ItemPlaybackForcastContext;- (ID)initWithURL:(NSURL *)url{    if (self = [super init]) {        __weak TFPAVController *_self = self;        AVURLAsset *asset = [AVURLAsset URLAssetWithURL:url options:nil];        Nsstring *tracksKey = @"tracks";        [asset loadValuesAsynchronouslyForKeys:[NSArray arrayWithObject:tracksKey] completionHandler:         ^{             dispatch_async(dispatch_get_main_queue(),^{                                NSError *error = nil;                                AVkeyvalueStatus status = [asset statusOfValueForKey:tracksKey error:&error];                                if (status == AVkeyvalueStatusLoaded) {                                    AVPlayerItem *item = [AVPlayerItem playerItemWithAsset:asset];                                    [item addobserver:_self forKeyPath:@"status" options:0 context:&ItemStatusContext];                                    [item addobserver:_self forKeyPath:@"timedMetadata" options:0 context:&ItemMetadataContext];                                    [item addobserver:_self forKeyPath:@"playbacklikelyToKeepUp" options:0 context:&ItemPlaybackForcastContext];                                    [[NSNotificationCenter defaultCenter] addobserver:_self                                                                             selector:@selector(playerItemDIDReachEnd:)                                                                                 name:AVPlayerItemDidplayToEndTimeNotification                                                                               object:item];                                    AVPlayer *player = [AVPlayer playerWithPlayerItem:item];                                    _self.totalRunTime = CMTimeGetSeconds(item.duration);                                    [_self.delegate avPlayerNeedsVIEw:player];                                    _self.playerItem = item;                                    _self.player = player;                                }                                else {                                    NSLog(@"The asset's tracks were not loaded: %@ // [%@ %@]",error.localizedDescription,NsstringFromClass([self class]),NsstringFromSelector(_cmd));                                }                                _self.playerObserver = [_self.player addPeriodicTimeObserverForInterval:CMTimeMake(1,_FrameRate_)                                                                                                   queue:NulL                                                                                             usingBlock: ^(CMTime time) {                                                                                                 _self.currentVIDeoTime = CMTimeGetSeconds([_self.playerItem currentTime]);                                                                                             }];                            });         }];    }    return self;}#pragma mark - KVO Response Methods- (voID)observeValueForKeyPath:(Nsstring *)keyPath                       ofObject:(ID)object                         change:(NSDictionary *)change                        context:(voID *)context {            __weak TFPAVController *_self = self;    if (context == &ItemStatusContext) {        dispatch_async(dispatch_get_main_queue(),^{                           if (((AVPlayerItem *)object).status == AVPlayerItemStatusReadytoplay) {                               [_self.delegate vIDeoIsLoadedInPlayer:_self];                           }                       });        return;    }    else if (context == &ItemMetadataContext) {        dispatch_async(dispatch_get_main_queue(),^{                           [_self checkMetaDataForPlayerItem: (AVPlayerItem *)object];                       });        return;    }    else if (context == &ItemPlaybackForcastContext) {        dispatch_async(dispatch_get_main_queue(),^{                           AVPlayerItem *playerItem = object;                                                      if (CMTimeGetSeconds([playerItem currentTime]) <= 0) return;                           NSDictionary *notificationDictionary = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:playerItem.playbacklikelyToKeepUp]                                                                                               forKey:kAVPlayerStateKey];                           [[NSNotificationCenter defaultCenter] postNotificationname:kAVPlayerNotification                                                                                object:self                                                                              userInfo:notificationDictionary];                        });        return;    }    [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];}- (voID)checkMetaDataForPlayerItem:(AVPlayerItem *)item{    NSMutableDictionary *MetaDict = [NSMutableDictionary dictionary];    // CL: make sure there's stuff there    if (item.timedMetadata != nil && [item.timedMetadata count] > 0) {        // CL: if there is,cycle through the items and create a Dictionary        for (AVMetadataItem *Metadata in item.timedMetadata) {            [MetaDict setobject:[Metadata valueForKey:@"value"] forKey:[Metadata valueForKey:@"key"]];        }        // CL: pass it to the delegate        [self.delegate parseNewMetaData:[NSDictionary dictionaryWithDictionary:MetaDict]];    }}
解决方法 啊,KVO.可能是Apple历史上最糟糕的设计决策之一.

我想它已经不再相关了,但是猜测你遇到的问题是,当你开始将自己添加为观察者时,有时你试图观察到的值已被分配给键,所以你的观察者选择器不叫.

为避免这种情况,您可以在调用addobserver:forKeyPath:options:context:时将NSkeyvalueObservingOptionInitial添加到选项中,并使用当前值立即调用您的observer方法.

总结

以上是内存溢出为你收集整理的ios – 未观察到AVPlayerItem初始timedMetadata(KVO)全部内容,希望文章能够帮你解决ios – 未观察到AVPlayerItem初始timedMetadata(KVO)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://www.outofmemory.cn/web/999398.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存