MPVolumeView Airplay 仅在镜像时触摸
Posted
技术标签:
【中文标题】MPVolumeView Airplay 仅在镜像时触摸【英文标题】:MPVolumeView Airplay only touches when mirroring 【发布时间】:2017-09-02 03:04:04 【问题描述】:我正在使用自定义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
当我(在真实设备上)运行我的代码时,我看到了按钮,但是当我点击它时,什么也没有发生。这可能是什么原因造成的?是不是因为我使用的是自定义AVPlayerLayer
和AVPlayer
?
编辑:
当我通过控制中心打开镜像时,我可以触摸按钮并显示弹出窗口。怎么回事?
【问题讨论】:
【参考方案1】:没有任何反应,因为您没有正确配置这个“新窗口”。
使用 Airplay 显示内容有两种方式。
镜像
不需要任何配置。
注意:您无需执行任何操作即可进行镜像。在 ios 中 5.0 及更高版本,镜像(即在主机设备和外部显示器上显示相同的内容)默认情况下发生 用户选择 AirPlay 视频输出设备。
额外窗口
(check apple guide here)
苹果描述的步骤是:
-
在应用启动时,检查是否存在外部显示器并注册屏幕连接和断开通知。
当外部显示器可用时(无论是在应用启动时还是在您的应用运行时)为其创建和配置一个窗口。
将窗口与适当的屏幕对象关联,显示第二个窗口,并正常更新。
这里是摘自苹果文档的代码供快速参考。
- 如果外部显示器已经存在,则创建一个新窗口
- (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 自动支持 AirPlay,但你需要 执行一些项目和音频会话配置,然后才可以 在您的应用程序中启用。
【讨论】:
真的这么复杂吗?我记得我在股票 avplayerviewcontroller 上使用了我的方法,效果很好。我已经很晚了,所以我明天试试你的解决方案 实现并不复杂,但它确实会发生变化,因为您使用的是自定义播放器。如果您要使用默认的 AVPlayerViewController,它将是自动的。事实上,它写在类描述上。 (检查编辑) 在checkForExistingScreenAndInitializeIfPresent
中,您有一个评论// Set up initial content to display...
,在handleScreenDidConnectNotification
中有类似的评论。最初的 UI 是什么?另外,如果我错了,请纠正我,但这是在 AppDelegate 中完成的,对吗?
至于在哪里完成,我建议在 AppDelegate 或 SingletonManager 中进行,您也可以在应用程序委托中初始化。这样做的目的是 1,尽快检测屏幕,2 持续监控连接的新屏幕。至于 cmets,是的,它就是你想在那里展示的任何东西。但简单地说,您创建一个根视图控制器并将其设置在该窗口上,如下所示: secondWindow!.rootViewController = rootVC以上是关于MPVolumeView Airplay 仅在镜像时触摸的主要内容,如果未能解决你的问题,请参考以下文章
iOS AirPlay:我的应用程序仅在镜像打开时才收到外部显示器通知?