MPVolumeView Airplay 仅在镜像时触摸

MPVolumeView Airplay only touches when mirroring

我正在使用自定义 AVPlayerLayer 来显示一个简单的视频。我正在尝试添加 airplay 支持,但是点击按钮时没有显示任何内容。

self.player.allowsExternalPlayback = true
...
let airplayButton = MPVolumeView(frame: self.airplayButtonPlaceholder!.bounds)
airplayButton.showsRouteButton = true
airplayButton.showsVolumeSlider = false

self.airplayButtonPlaceholder?.addSubview(airplayButton)
self.airplayButtonPlaceholder?.backgroundColor = UIColor.clear

当我 运行 我的代码(在真实设备上)时,我看到了按钮,但是当我点击它时,没有任何反应。是什么原因造成的?是因为我使用的是自定义 AVPlayerLayerAVPlayer 吗?

编辑:

当我通过控制中心打开镜像时,我可以触摸按钮并显示弹出窗口。怎么回事?

没有任何反应,因为您没有正确配置 "new window"。

使用 Airplay 显示内容有两种方式。

镜像

不需要任何配置。

Note: You don’t need to do anything to make mirroring happen. In iOS 5.0 and later, mirroring—that is, displaying the same content on both the host device and the external display—occurs by default when the user selects an AirPlay video output device.

额外Window

(check apple guide here)

苹果描述的步骤是:

  1. 在应用程序启动时,检查是否存在外部显示器并注册屏幕连接和断开连接通知。
  2. 当外部显示器可用时——无论是在应用程序启动时还是当您的应用程序处于 运行 时——为其创建并配置 window。
  3. 将 window 与适当的屏幕对象相关联,显示第二个 window,并正常更新它。

这是从苹果文档中获取的代码,供快速参考。


- 创建一个新的 Window 如果外部显示器已经存在

- (void)checkForExistingScreenAndInitializeIfPresent
{
    if ([[UIScreen screens] count] > 1)
    {
        // Get the screen object that represents the external display.
        UIScreen *secondScreen = [[UIScreen screens] objectAtIndex:1];
        // Get the screen's bounds so that you can create a window of the correct size.
        CGRect screenBounds = secondScreen.bounds;

        self.secondWindow = [[UIWindow alloc] initWithFrame:screenBounds];
        self.secondWindow.screen = secondScreen;

        // Set up initial content to display...
        // Show the window.
        self.secondWindow.hidden = NO;
    }
}

- 注册连接和断开连接通知

- (void)setUpScreenConnectionNotificationHandlers
{
    NSNotificationCenter *center = [NSNotificationCenter defaultCenter];

    [center addObserver:self selector:@selector(handleScreenDidConnectNotification:)
            name:UIScreenDidConnectNotification object:nil];
    [center addObserver:self selector:@selector(handleScreenDidDisconnectNotification:)
            name:UIScreenDidDisconnectNotification object:nil];
}

- 处理连接和断开连接通知

- (void)handleScreenDidConnectNotification:(NSNotification*)aNotification
{
    UIScreen *newScreen = [aNotification object];
    CGRect screenBounds = newScreen.bounds;

    if (!self.secondWindow)
    {
        self.secondWindow = [[UIWindow alloc] initWithFrame:screenBounds];
        self.secondWindow.screen = newScreen;

        // Set the initial UI for the window.
    }
}

- (void)handleScreenDidDisconnectNotification:(NSNotification*)aNotification
{
    if (self.secondWindow)
    {
        // Hide and then delete the window.
        self.secondWindow.hidden = YES;
        self.secondWindow = nil;

    }

}

编辑:

当使用 AVPlayerViewController 时,它已经按照文档 here 中的描述自动实现。

AVPlayerViewController automatically supports AirPlay, but you need to perform some project and audio session configuration before it can be enabled in your application.