【问题标题】:iOS AVPlayerViewController does not display playback controlsiOS AVPlayerViewController 不显示播放控件
【发布时间】:2014-11-05 19:55:10
【问题描述】:

知道为什么我可以让我的 AVPlayerViewController 类播放内容,但不能让它显示播放控件吗?播放器按预期加载内容,仅此而已。

在我的 MediaPlayerViewController.m 类中,我有:

#pragma mark - Player
- (void)setupPlayer{

    // Sample URLs to use either a local file or streaming URL
    NSURL *url = [[NSBundle mainBundle] URLForResource:@"Besan" withExtension:@"mp4"];
    //url = [NSURL URLWithString:@"http://www.youtube.com/watch?v=qcI2_v7Vj2U"];

    // Create an instance of the AVPlayer object
    self.player = [AVPlayer playerWithURL:url];


    // Keep an eye on the status of our player
    [self.player addObserver:self forKeyPath:@"status" options:0 context:nil];
}

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

    if (object == self.player && [keyPath isEqualToString:@"status"]) {
        if (self.player.status == AVPlayerStatusFailed){
            NSLog(@"AVPlayer setup failed");
        } else if (self.player.status == AVPlayerStatusReadyToPlay) {
            NSLog(@"AVPlayer is ready to play");
            [self.player play];
        }
    }
}

【问题讨论】:

  • 我也遇到了这个问题。结果是,当您删除 observeValueForKeyPath 方法时,控件会出现。现在正在寻找某种解决方法...

标签: ios objective-c ios8.1


【解决方案1】:

这不是框架错误,而是与键值观察的工作方式有关。通过实现

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

在您的 ViewController 中,您将覆盖 AVPlayerViewController 的实现。解决方案是在注册观察者时添加上下文:

static NSString* const AVPlayerStatusObservationContext = @"AVPlayerStatusObservationContext";

然后像这样注册你的观察者

[self.player addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionPrior context:(__bridge void *)(AVPlayerStatusObservationContext)];

并在 observeValueForKeyPath 中执行以下操作

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

    if (context == (__bridge void *)(AVPlayerStatusObservationContext))
    {
        NSLog(@"Change Object %@, Value %@",object,change);
    } else {
        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
    }
}

【讨论】:

  • 文档声明“不要继承 AVPlayerViewController。不支持覆盖此类的方法,并导致未定义的行为。”。我想这个问题是他们不希望我们这样做的原因之一 :)
【解决方案2】:

正如我在对该问题的评论中指出的那样,当您在 AVPlayerViewController 中实现 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 时,这些控件就会消失。它可以是一个空的实现;播放器控件不会出现。这一定是一个框架错误,我很震惊(震惊!)Apple 没有发现这一点。

我的解决方案是在不同的类中实现观察者。我创建了一个继承自 NSObject 的 VideoObserver 类,并将其设置为:

@implementation VideoObserver

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if ([keyPath isEqualToString:@"status"]) {
        NSLog(@"Change: %@", change);
    }
}
@end

在 AVPlayerViewController 中,我将观察者设置为属性,然后使用它开始观察:

self.observer = [VideoObserver new];

NSURL * videoURL = [NSURL URLWithString:@"http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4"];
self.videoPlayer = [AVPlayer playerWithURL:videoURL];

[self.videoPlayer addObserver:self.observer forKeyPath:@"status" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial context:nil];

我在 Github 上有 posted my demo project

【讨论】:

  • 谢谢亚伦。您的解决方法有效,感谢您的回答。
【解决方案3】:

也许很有趣,但请确保控件实际上并未隐藏在 TabBar 下方。还没有找到解决办法,但是那个小事让我有些难过,花了一点时间才意识到——但控件实际上仍然存在。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-08-17
    • 2019-08-03
    • 2021-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多