ios - 如何以编程方式发现iOS设备列表并使用airplay进行镜像连接?

标签 ios airplay apple-tv

我想创建一个应用程序,让用户不知道附近设备(例如iphone,ipad和appletv等)的发现,并选择唯一的appleTv(如果附近可用),然后自动连接并启动镜像。为此,我阅读了 AirPlay :

Using AirPlay, users redirect audio and video from iTunes or an iOS-based device to either an Apple TV (and from there to a home theater system) or to an AirPlay-enabled sound system. AirPlay can stream media coming live from the Internet, media already stored in iTunes, or media stored on an iOS-based device. AirPlay can stream Internet-based media when it is playing in iOS apps, in the Safari browser on iOS-based devices, or in iTunes on any platform



但我不需要airplay按钮,我想以编程方式发现设备并仅与appleTv连接,然后开始镜像。

我读了很多博客,并且在Google上搜索了很多,但没有发现任何有用的东西。 http://spin.atomicobject.com/2012/04/23/ios-mirroring-and-programmatic-airplay-selection/给出了一些解释,但出现了。

请给我建议,“如何以一种很好的方式实现这种东西”。

最佳答案

抱歉,这太晚了,您可能已经实现了其他功能,但是经过 DAYS 的研究和反复试验后,我终于有了一些工作。

许多开发人员在其应用程序中拥有真正的高级UI,并使用了许多自定义弹出窗口和 Controller ,从而为其应用程序提供了非常独特的外观,然后不得不使用现有的AirPlay Controller UI,这使用户完全脱离了应用程序的体验,可能会让人完全厌倦。

其他人则需要更好的用户体验。 IE。他们无需将菜单分开以供人们将其当前媒体流传输到(一个菜单用于AirPlay,另一个菜单用于其他所有内容),而是希望将两者结合起来,以便用户拥有真正的绝佳体验。

不幸的是,使用今天可用的公共(public)API,您实际上无能为力。 Spotify试图使其在其应用程序中运行,尽管比大多数方法要好,但仍然有很多不足之处。
enter image description here enter image description here

但是,如果由于某种原因,您不想在应用商店上发布您的应用,或者您有一个很好的代码混淆器,可以隐藏来自苹果的函数调用(极不可能),或者您希望将应用分发到另一家商店(Cydia)等)为您提供一个选项:专用API。

许多人在听到这两个单词时会回避,但是一旦习惯了这种格式,它实际上与普通的Cocoa编程相同(减去Xcode代码完成)。

别再胡说八道了,只给GIMME DE CODEZ

我不会向您介绍与私有(private)API的交互;您可以阅读其他比我更愿意深入研究的文章。事不宜迟,这就是我想出的。

步骤1:阅读其他更聪明的人在github(https://github.com/nst/iOS-Runtime-Headers/blob/master/Frameworks/)上发布的反向工程头文件。确实值得阅读所有头文件,因为您可以做的一些事情真的很有趣。

步骤2:开始工作。现在,我将在Swift中进行此操作,但是我将在下面提供Objective-C链接。我建议使用Objective-C,因为这些类中的大多数都是用Objective-C编写的,并且许多方法都以iVars的“_”快速错误开头,而且确实很乱。但是,如果必须的话,这就是您的做法。

因此,与在方法中使用[class performSelector:methodName]和访问实例变量的[instance valueForKey:_iVar]的常规方法相比,在Swift中使用协议(protocol)更容易。主要是因为在Swift中执行选择器会SUCKS

因此,我们将基本上创建稍后将需要使用的类的本地表示形式。

@objc protocol MPAVRoutingControllerProtocol {
    optional func fetchAvailableRoutesWithCompletionHandler(completion: (routes: [MPAVRouteProtocol]) -> Void)
    optional func pickRoute(route: MPAVRouteProtocol) -> Bool
    optional func setDelegate(delegate: NSObject)
}

@objc protocol MPAVRouteProtocol {
    optional func routeName() -> String
    optional func routeUID() -> String
    optional func isPicked() -> Bool
    optional func wirelessDisplayRoute() -> MPAVRouteProtocol
}

@objc protocol MPAudioDeviceControllerProtocol {
    optional func setRouteDiscoveryEnabled(enabled: Bool)
    optional func routeDescriptionAtIndex(index: Int) -> [String: AnyObject]
}

extension NSObject : MPAVRoutingControllerProtocol, MPAVRouteProtocol, MPAudioDeviceControllerProtocol {

}

现在,这实际上就是发生魔法的地方。在您的 View Controller 中的某处,我们使用NSClassFromString()创建类
let MPAudioDeviceControllerClass: NSObject.Type =  NSClassFromString("MPAudioDeviceController") as! NSObject.Type
let MPAVRoutingControllerClass: NSObject.Type = NSClassFromString("MPAVRoutingController") as! NSObject.Type

然后,我们从这些类中创建对象,并通过调用协议(protocol)函数与它们进行交互。
let routingController = MPAVRoutingControllerClass.init() as MPAVRoutingControllerProtocol
let audioDeviceController = MPAudioDeviceControllerClass.init() as MPAudioDeviceControllerProtocol

现在,我们已经完全初始化了对象,我们可以做一些真正的酷事了。因此,我们要做的第一件事是启动守护程序以搜索airplay设备。
audioDeviceController.setRouteDiscoveryEnabled!(true)

此步骤是可选的,但建议这样做。我们可以为自己分配MPAVRoutingController的委托(delegate),并在设备变为 Activity 状态时获得委托(delegate)调用,而不是为可能存在或可能不存在的更改更新UI。
routingController.setDelegate!(self)

然后,我们实现该功能。
func routingControllerAvailableRoutesDidChange(controller: MPAVRoutingControllerProtocol) {
}

然后,在此函数内,我们可以为UI填充数据源。
routingController.fetchAvailableRoutesWithCompletionHandler! { (routes) in

}

因此,从此开始,我们正在调用routingController的方法将向我们返回一个MPAVRoute对象数组,我们可以从中提取信息。您需要的所有信息都在MPAVRouteProtcol中,但是如果您需要更多信息,可以致电audioDeviceController.routeDescriptionAtIndex!(an Index)。这将返回详细信息,例如airplay设备的类型,mac地址,是否支持视频等等。

然后,当您需要选择路线时,可以调用routingController.pickRoute!(selectedRoute)。您无需担心密码,iOS会自动为您处理密码(错误,缓存警报 Controller 等)。

关于ios - 如何以编程方式发现iOS设备列表并使用airplay进行镜像连接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34115251/

相关文章:

ios - 检测 iOS AirPlay 屏幕镜像功能

ios - iPad Mirroring 使用 2 个屏幕,支持 1080 分辨率吗?

swift - <memory> 不是 BOMStorage 文件

iphone - 如何在sqlite查询中传递表名

ios - 如何使用 swift 等待登录 View 的 api 响应值

objective-c - AVAudioSessionCategoryPlayAndRecord 使 AirPlay 不可见

javascript - TVML/tvOS : Template background?

Xcode 10 “appletv is busy: Preparing debugger support for apple tv”

ios - 使用编程约束在 View 中创建 2 个 View

iphone - SIGABRT 在 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ 上崩溃