如何动态更改 Google Cast 中的 `applicationID`? iOS 开发工具包

How to change `applicationID` in Google Cast dynamically? iOS SDK

我在 application: didFinishLaunching 中初始化 Google Cast SDK,就像这样:

let criteria = GCKDiscoveryCriteria(applicationID: kGCKDefaultMediaReceiverApplicationID)
let options = GCKCastOptions(discoveryCriteria: criteria)
GCKCastContext.setSharedInstanceWith(options)

我已经尝试将视频内容流式传输到默认媒体接收器并且它有效。

但我需要能够将 kGCKDefaultMediaReceiverApplicationID 更改为自定义接收器应用程序 ID,以便将不同的内容发送到我通过 Google Cast SDK 开发人员控制台注册的自定义接收器应用程序。我无法重新启动应用程序以指定不同的应用程序 ID。

GCKCastContext.setSharedInstanceWith(options) 已经被调用后,有没有办法在应用程序中的某个时刻动态地执行此操作?

此方法的调用仅有效一次,我无法更新 GCKDiscoveryCriteria:GCKCastContext.setSharedInstanceWith(options)

我用的是'google-cast-sdk-no-bluetooth',版本:4.5.3

在Android SDK中有一种方法可以动态更改接收者应用程序ID:https://developers.google.com/android/reference/com/google/android/gms/cast/framework/CastContext#public-void-setreceiverapplicationid-string-applicationid

不幸的是,我在 iOS SDK 中没有看到类似的东西:(

我唯一找到的是这个(在 GCKSessionManager 内部):

/**
 * Sets the default session options for the given device category.The session options are passed to
 * the GCKDeviceProvider::createSessionForDevice:sessionID:sessionOptions: method when the user
 * selects a device from the Cast dialog.  For Cast sessions, the session options can specify which
 * receiver application to launch.
 *
 * @param sessionOptions The session options. May be <code>nil</code> to remove any previously set
 * options.
 * @param category The device category.
 *
 * @since 4.0
 */
- (void)setDefaultSessionOptions:(nullable GCKSessionOptions *)sessionOptions
               forDeviceCategory:(NSString *)category;

但是没有关于传递哪个会话选项和类别的文档(类别可能是 kGCKCastDeviceCategory)。存在哪些参数以及如何构造它们是无法理解的。

您可以通过调用private objc unsetSharedInstance选择器删除Cast的单例实例,然后重新设置:

let unset = Selector("unsetSharedInstance")
if GCKCastContext.responds(to: unset) {
    GCKCastContext.perform(unset)
}
GCKCastContext.setSharedInstanceWith(GCKCastOptions(discoveryCriteria: GCKDiscoveryCriteria(applicationID: "APP_ID")))

您可以将其用作临时解决方案,因为它可以在新版本的库中进行更改。

经过一段时间的逆向工程,我找到了解决方案。它需要 2 个必要的步骤:

第 1 步:使用私有 Objective-C 调用初始化 GCKDiscoveryCriteria

let criteria = GCKDiscoveryCriteria(applicationID: kReceiverAppID)
let initWithIds = Selector(("initWithApplicationIDs:"))
if criteria.responds(to: initWithIds) {
    criteria.perform(initWithIds, with: NSOrderedSet(array: [kGCKDefaultMediaReceiverApplicationID, kReceiverAppID]))
}
    
let options = GCKCastOptions(discoveryCriteria: criteria)
GCKCastContext.setSharedInstanceWith(options)

在这里您需要提供一个 NSOrderedSet 的实例,其中包含您要使用的应用程序 ID。在我的例子中,其中一个是默认的媒体接收器应用程序 ID,第二个是自定义的。

第 2 步:动态设置用于新创建会话的应用程序 ID。您可以在应用程序生命周期中多次调用它:

let sessionManager = GCKCastContext.sharedInstance().sessionManager
sessionManager.setDefaultSessionOptions(["gck_applicationID": NSString("YOUR_RECEIVER_APP_ID")],
                                                                                forDeviceCategory: kGCKCastDeviceCategory)
    

这里我们使用字符串gck_applicationID作为key。找了好几天终于找到了!!!您可以使用 kGCKDefaultMediaReceiverApplicationID 作为值,或您的自定义接收器应用程序 ID。

感谢@iUrii 和他对逆向工程的指导。

P.S.: 我用私有方法完成了我想要的。它适用于 google-cast-sdk-no-bluetooth,版本 4.5.3。但它可能会发生变化。使用时要小心,新版本的SDK可能会破坏它。