当我尝试观察下一个视频的开始时 AVQueuePlayer 崩溃:AVPlayerItem 已与观察者解除分配
AVQueuePlayer crashes when I try to observe the start of the next video: AVPlayerItem was deallocated with observers
我有一个 AVQueuePlayer,其中包含我需要一个接一个播放的视频 URL 数组。一切正常,直到我尝试添加观察者来跟踪每个视频的开始。
为了让 AVQueuePlayer 自动前进到下一个视频,我有这个:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(playerItemDidReachEnd:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:[playerItems lastObject]];
- (void)playerItemDidReachEnd:(NSNotification *)notification {
[self nextVideoOrExit];
}
- (void)nextVideoOrExit
{
if ([player.items count] == 1)
[self shutdown];
else
[player advanceToNextItem];
}
- (void)shutdown
{
[player removeAllItems];
[self dismissPlayerView];
}
到目前为止,这按预期工作 - 视频一个接一个地播放。现在我还需要立即知道视频何时开始播放,以便我可以使用文件名更新 UI 中的标签。
以下是我添加 AVPlayerItems 和用于跟踪下一个视频播放时间的观察器的方法:
for (Tag *tag in self.tagsWithVideos) {
tagUrlToTag[tag.video.url] = tag;
NSURL *url = [[NSURL alloc] initWithString:tag.video.url];
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:url options:nil];
AVPlayerItem *playerItem = [[AVPlayerItem alloc] initWithAsset:asset];
[player insertItem:playerItem afterItem:nil];
[playerItems addObject:playerItem];
[playerItem addObserver:self
forKeyPath:@"status"
options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
context:@"AVPlayerStatus"];
NSLog(@"LOADING ANOTHER VID");
};
下面是我处理观察者的方式:
- (void)observeValueForKeyPath:(NSString *)path
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context {
if (context == @"AVPlayerStatus") {
AVPlayerStatus status = [[change objectForKey:NSKeyValueChangeNewKey] integerValue];
switch (status) {
case AVPlayerStatusUnknown: {
}
break;
case AVPlayerStatusReadyToPlay: {
NSLog(@"AVPlayerStatusReadyToPlay");
}
break;
}
}
}
当我 运行 这样做时,第一个视频播放正常。它在 nextVideoOrExit
内的 [player advanceToNextItem];
处崩溃
崩溃:
2015-06-07 13:31:52.017 AppName[7375:1775566] *** Terminating app due
to uncaught exception 'NSInternalInconsistencyException', reason: 'An
instance 0x17001bea0 of class AVPlayerItem was deallocated while key
value observers were still registered with it. Current observation
info: ( Context: 0x1001da910, Property: 0x17065b4e0>
)'
如果我注释掉 [player advanceToNextItem];
行,它不会崩溃,但也不会播放列表中的第二个视频。
我不确定应该在哪里移除观察者(或者是否有更好的方法来确定视频何时开始播放。
有什么建议吗?谢谢!
根据AVFoundation Programming Guide,您可以使用 KVO 来监控播放器本身的值,而不是每个项目:
如果用户使用多任务切换到不同的应用程序,玩家的 rate 属性 将下降到 0.0.
播放器的 currentItem 属性 在为 HTTP 直播流创建播放器项目时发生变化。
播放器或播放器物品的状态属性可能会因某种原因播放失败而改变。
我有一个 AVQueuePlayer,其中包含我需要一个接一个播放的视频 URL 数组。一切正常,直到我尝试添加观察者来跟踪每个视频的开始。
为了让 AVQueuePlayer 自动前进到下一个视频,我有这个:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(playerItemDidReachEnd:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:[playerItems lastObject]];
- (void)playerItemDidReachEnd:(NSNotification *)notification {
[self nextVideoOrExit];
}
- (void)nextVideoOrExit
{
if ([player.items count] == 1)
[self shutdown];
else
[player advanceToNextItem];
}
- (void)shutdown
{
[player removeAllItems];
[self dismissPlayerView];
}
到目前为止,这按预期工作 - 视频一个接一个地播放。现在我还需要立即知道视频何时开始播放,以便我可以使用文件名更新 UI 中的标签。
以下是我添加 AVPlayerItems 和用于跟踪下一个视频播放时间的观察器的方法:
for (Tag *tag in self.tagsWithVideos) {
tagUrlToTag[tag.video.url] = tag;
NSURL *url = [[NSURL alloc] initWithString:tag.video.url];
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:url options:nil];
AVPlayerItem *playerItem = [[AVPlayerItem alloc] initWithAsset:asset];
[player insertItem:playerItem afterItem:nil];
[playerItems addObject:playerItem];
[playerItem addObserver:self
forKeyPath:@"status"
options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
context:@"AVPlayerStatus"];
NSLog(@"LOADING ANOTHER VID");
};
下面是我处理观察者的方式:
- (void)observeValueForKeyPath:(NSString *)path
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context {
if (context == @"AVPlayerStatus") {
AVPlayerStatus status = [[change objectForKey:NSKeyValueChangeNewKey] integerValue];
switch (status) {
case AVPlayerStatusUnknown: {
}
break;
case AVPlayerStatusReadyToPlay: {
NSLog(@"AVPlayerStatusReadyToPlay");
}
break;
}
}
}
当我 运行 这样做时,第一个视频播放正常。它在 nextVideoOrExit
[player advanceToNextItem];
处崩溃
崩溃:
2015-06-07 13:31:52.017 AppName[7375:1775566] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'An instance 0x17001bea0 of class AVPlayerItem was deallocated while key value observers were still registered with it. Current observation info: ( Context: 0x1001da910, Property: 0x17065b4e0> )'
如果我注释掉 [player advanceToNextItem];
行,它不会崩溃,但也不会播放列表中的第二个视频。
我不确定应该在哪里移除观察者(或者是否有更好的方法来确定视频何时开始播放。
有什么建议吗?谢谢!
根据AVFoundation Programming Guide,您可以使用 KVO 来监控播放器本身的值,而不是每个项目:
如果用户使用多任务切换到不同的应用程序,玩家的 rate 属性 将下降到 0.0.
播放器的 currentItem 属性 在为 HTTP 直播流创建播放器项目时发生变化。
播放器或播放器物品的状态属性可能会因某种原因播放失败而改变。