Поддержка воспроизведения фонового видео ChromeCast iOS

У меня есть проблема, когда при моем обращении в фоновом режиме GCKSocket хромовой iOS api закрывается, и я получаю этот typr ошибки из 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)"

Ответ 1

В настоящее время SDK Cast iOS закрывает сокет, когда вы переходите на задний план, и на данный момент это не настраиваемый элемент. Однако это не означает, что воспроизведение мультимедиа на устройстве Cast должно прекратиться; на самом деле правильное поведение таково:

  • Если пользователь явно отключил себя от литого устройства, и если она является последним подключенным устройством к ресиверу, то приемник должен остановить воспроизведение, в противном случае приемник должен продолжить воспроизведение.

Ключ здесь - "явная" часть; если, например, отправитель выходит из диапазона Wi-Fi и отключается, или если отправитель переходит в режим сна и отключается, они считаются "неявными" разъединениями и не должны останавливать приемник.

Другими словами, на самом деле приемник должен иметь логику, чтобы решить, нужно ли ей останавливаться или продолжать играть, и для этого нужно решить, было ли отключено устройство неявным образом или в явном виде. В существующих API-интерфейсах приемника SDK, к сожалению, он не включен в событие onSenderDisconnected, которое получает получатель; в следующем обновлении или около этого получателя он изменится, так что получатель может понять, почему происходит отключение, по крайней мере, столько, сколько нужно, чтобы выделить явное из неявного. Тогда он может реализовать логику. Между тем, отправитель должен иметь внеполосный канал для отправки сообщения с указанием его явного намерения.

Обновление:. Обновлен SDK приемника, чтобы иметь информацию, которая может определить, был ли отправитель неявным или явно отключен, см. docs.

Ответ 2

Существует хак, который помогает поддерживать связь в фоновом режиме.

Вы можете заменить вызов GCKSessionManager.suspendSession(с:) для пользовательского интерфейса, который не отключается.

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 пытается подключиться к устройству.

Я исправил повторное подключение, когда произошла ошибка, с флагом, чтобы идентифицировать его ранее в фоновом режиме.

ссылка: Как сохранить GCKCastSession в живых, когда приложение переходит в фоновый режим