【问题标题】:ChromeCast background video playback support iOSChromeCast 后台视频播放支持 iOS
【发布时间】:2014-03-27 12:51:35
【问题描述】:

我有一个问题,当我的应用程序进入后台时,chromecast iOS api 的 GCKSocket 会关闭,并且我从 api 收到此类型的错误

-[GCKCastSocket socketDidDisconnect:withError:]  socketDidDisconnect:withError: "(null)"

然后,如果我将应用程序置于前台,api 会自动创建套接字并将播放状态设置为暂停。如果我现在再次尝试播放视频,它会正常播放。

我正在像这样在后台线程上开始播放媒体。

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND,
                                             0), ^ {
[[CastViewController instance] castMedia:self.media];      

});

即使应用程序进入后台,如何保持播放状态?

这里是来自 api 的日志

2014-02-25 17:19:01.388 CastVideos[28470:60b] -[GCKCastSocket disconnect] disconnect

2014-02-25 17:19:01.391 CastVideos[28470:60b] -[GCKCastSocket doTeardownWithError:] doTeardownWithError

2014-02-25 17:19:01.395 CastVideos[28470:60b] -[GCKCastSocket doTeardownWithError:] notifying delegate that socket is disconnected

2014-02-25 17:19:01.399 CastVideos[28470:60b] -[GCKHeartbeatChannel didDisconnect] disconnected - stopping heartbeat timer if necessary

2014-02-25 17:19:01.457 CastVideos[28470:60b] -[GCKCastSocket socketDidDisconnect:withError:] socketDidDisconnect:withError: "(null)"

【问题讨论】:

  • 后台模式下的应用和后台线程无关。
  • 所以应该使用哪种背景模式来支持 chromecast 播放,例如我们使用带有音频背景模式的 avaudiosession 来支持 chromecast 播放
  • 如果您不需要提交到 AppStore,任何后台模式都可以,前提是 chromecast 将在后台模式下工作。我不熟悉的。
  • 我已经为airplay定义了音频背景模式,为什么它不起作用呢?

标签: ios objective-c google-cast chromecast


【解决方案1】:

目前,Cast iOS SDK 会在您进入后台时关闭套接字,此时这不是可配置项。但是,这并不意味着您在 Cast 设备上的媒体播放应该停止;实际上正确的行为如下:

  • 如果用户明确断开了与投射设备的连接,并且如果她是最后连接到接收器的设备,则接收器应停止播放,否则接收器应继续播放。

这里的关键是“显式”部分;例如,如果发送方超出 wifi 范围并断开连接,或者发送方进入睡眠状态并断开连接,则这些被视为“隐式”断开连接,不应导致接收方停止。

换句话说,真正的接收者应该有逻辑来决定它是否必须停止自己或继续播放,并且要使其正常工作,它必须能够决定设备断开连接是隐式引起的还是明确地。在当前的接收方 SDK API 中,不幸的是,接收方获取的 onSenderDisconnected 事件中并未包含该 API;在接收器的下一次更新中,它会发生变化,因此接收器可以看到为什么会发生断开连接,至少与区分显式和隐式断开一样多。然后它可以实现逻辑。同时,发送者需要有一个带外通道来发送一条表明其明确意图的消息。

更新: Receiver SDK 已更新,包含可以判断发送方是隐式还是显式断开连接的信息,请参阅docs

【讨论】:

  • 感谢您的回答,我是否应该在应用程序进入睡眠或后台后尝试向接收方发送消息?也许告诉接收者这是一个隐式/显式断开连接
  • 不,如果您进入后台或超出范围,接收方会意识到您已离开并认为您已断开连接,并且由于您没有发送显式消息,因此应将其解释为隐式消息。仅当用户明确断开连接时才发送消息(在修复生效之前)
  • 但目前演示接收器应用程序一旦发送者进入后台就会自动停止,如何克服?
  • 这是一个示例应用程序;确保您的家宴应用程序没有在断开连接时发送 stopApplication,然后编写您自己的自定义接收器来执行我概述的逻辑。
  • 好的,一旦从发送方调用 [self.mediacontrolchannel stop] 方法,我已经设法通过在接收方为 mediaelement stop 实现一个单独的方法来做到这一点。并在接收器端注释掉 onDiscconect 中停止媒体元素的代码。
【解决方案2】:

有一个技巧可以帮助在后台连接时保持连接。

您可以将 GCKSessionManager.suspendSession(with:) 的调用替换为不会断开连接的自定义。

extension GCKSessionManager {
    static func ignoreAppBackgroundModeChange() {
        let oldMethod = class_getInstanceMethod(GCKSessionManager.self, #selector(GCKSessionManager.suspendSession(with:)))
        let newMethod = class_getInstanceMethod(GCKSessionManager.self, #selector(GCKSessionManager.suspendSessionIgnoringAppBackgrounded(with:)))
        method_exchangeImplementations(oldMethod, newMethod)

    }

    func suspendSessionIgnoringAppBackgrounded(with reason: GCKConnectionSuspendReason) -> Bool {
        guard reason != .appBackgrounded else { return false }
        return suspendSession(with:reason)
    }
}

只需在之前的任意位置调用一次ignoreAppBackgroundModeChange()方法即可进入后台。

我发现的问题是,当您返回应用程序时,几秒钟后您将遇到网络错误,因为 Google Cast 正在尝试重新连接到设备。

我修复了错误发生时重新连接的问题,并在之前在后台输入了一个标志来识别它。

参考:How to keep GCKCastSession alive when app goes to background

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-05-19
    • 1970-01-01
    • 2017-09-25
    • 2013-07-27
    • 1970-01-01
    • 1970-01-01
    • 2013-06-13
    • 1970-01-01
    相关资源
    最近更新 更多