gpt4 book ai didi

macos - AV Foundation : Difference between currentItem being ready to play, 和 -[AVPlayer readyForDisplay] 属性?

转载 作者:行者123 更新时间:2023-12-03 16:11:20 25 4
gpt4 key购买 nike

我的视频播放器遇到了奇怪的情况,其核心代码与我制作的早期应用程序中的代码相比没有太大变化。问题是:我插入一个“_loadingLayer”(一个表示视频正在加载的 CATextLayer),然后观察 AVPlayer 的 currentItem 的状态属性以找出何时删除“_loadingLayer”并将其替换为我实际的“_playerLayer” 。这是我的 KVO 代码:

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {

if ((object == _playerLayer) && (_playerLayer.player.currentItem.status == AVPlayerItemStatusReadyToPlay)) {

[CATransaction setAnimationDuration:1.8];

_loadingLayer.opaque = NO;

if (_playerLayer.readyForDisplay) {

NSLog(@"Should be ready now.");

}

[self addPlayerLayerToLayerTree];

}

}

我的问题是视频正在启动,但只有音频正在播放 - 图层保持黑色。当我插入上面的 NSLog 语句时,我发现了原因:显然,虽然 currentItem 的状态是“AVPlayerItemStatusReadyToPlay”,但播放器层实际上并未准备好显示。这对我来说毫无意义——这似乎违反直觉。有人可以给我一些指导吗?

我能够通过将 _playerLayer 的背景颜色设置为红色来验证它是否已添加到图层树中。

我认为可能相关的另一件奇怪的事情......我在调试器控制台中看到了这些消息:

PSsetwindowlevel,错误设置窗口级别(1000)CGSSetIgnoresCycle:错误 1000 设置或清除窗口标签

提前致谢。这是来自 Apple 开发论坛的交叉帖子。

最佳答案

我们遇到了类似的问题,并追踪到我认为是 iOS 5.1(可能还有更早版本)中的错误。它在 iOS 6.0 中得到修复。由于我在任何地方都找不到解决方案,因此我正在为 future 遇到此问题的人写一篇长文。

如果 AVPlayerItem 在获取 AVPlayerLayer 之前报告 AVPlayerStatusReadyToPlay 状态,则 AVPlayer 将永远不会报告它已准备就绪。

所以当你这样做时:

self.player = [AVPlayer playerWithPlayerItem:self.playerItem];

确保后面跟着:

self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player]; 

并且两者之间没有太多代码(如果有的话)。

我构建了一个测试装置,使其在 100% 的时间里正常工作,或者在 100% 的时间里失败。请注意,查看实际应用程序中发生的情况可能很棘手,因为视频的加载时间不同,这将影响playerItem报告AVPlayerStatusReadyToPlay的速度。

如果您想在您的应用程序中进行测试,请将其放入一个简单的 View 中。以下内容在 iOS 5.1 上不起作用(即您将听到音频但看不到视频)。如果您将 loadPlayerLayer 切换为在 loadPlayer 末尾调用,则它将始终有效。

为 future 的读者提供的后续内容:几个玩家事件可以改变这个顺序,让你认为它正在工作。但它们是转移注意力的,因为它们无意中颠倒了加载顺序,使得playerLayer在AVStatusReadyToPlay之前被抓取。这些事件是:寻找视频、转到主屏幕然后重新激活应用程序、播放器切换到 HLS 视频内的不同视频/音频轨道。这些操作再次触发 AVStatusReadyToPlay,从而使playerLayer 在 AVStatusReadyToPlay 之前发生。

这是使用 Apple 测试 HLS 视频的测试工具:

-(void)loadPlayer
{
NSLog(@"loadPlayer invoked");

NSURL *url = [NSURL URLWithString:@"https://devimages.apple.com.edgekey.net/resources/http-streaming/examples/bipbop_4x3/bipbop_4x3_variant.m3u8"];
self.playerItem = [AVPlayerItem playerItemWithURL:url];
[self.playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew context:&kPlayerContext];
self.player = [AVPlayer playerWithPlayerItem:self.playerItem];

}

-(void)loadPlayerLayer
{
NSLog(@"starting player layer");
self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
[self.playerLayer addObserver:self forKeyPath:@"readyForDisplay" options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew context:&kPlayerLayerContext];
[self.playerLayer setFrame:[[self view] bounds]];
[[[self view] layer] addSublayer:self.playerLayer];
}

-(void)observeValueForKeyPath:(NSString*)path ofObject:(id)object change:(NSDictionary*)change context:(void*) context
{
if(context == &kPlayerContext){
if([self.player status] == AVPlayerStatusReadyToPlay){
NSLog(@"Player is ready to play");
//Robert: Never works if after AVPlayerItem reports AVPlayerStatusReadyToPlay
if(!self.startedPlayerLayer){
self.startedPlayerLayer = YES;
[self loadPlayerLayer];
}
}
}

if(context == &kPlayerLayerContext){
if([self.playerLayer isReadyForDisplay] == YES){
NSLog(@"PlayerLayer says it's ready to display now");
[self playTheVideoIfReady];
}
}
}

关于macos - AV Foundation : Difference between currentItem being ready to play, 和 -[AVPlayer readyForDisplay] 属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12654783/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com