ChromeCast фоновое воспроизведение видео с поддержкой iOS
У меня проблема в том, что когда мое приложение переходит в фоновый режим, GCKSocket в chromecast iOS api закрывается, и я получаю этот тип ошибки от 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)"
2 ответа
В настоящее время Cast iOS SDK закрывает сокет при переходе в фоновый режим, и на данный момент это не настраиваемый элемент. Однако это не означает, что воспроизведение мультимедиа на устройстве Cast должно быть остановлено; на самом деле правильное поведение следующее:
- если пользователь явно отключил себя от устройства приведения и если он является последним подключенным устройством к приемнику, то приемник должен остановить воспроизведение, в противном случае приемник должен продолжить воспроизведение.
Ключевым моментом здесь является "явная" часть; если, например, отправитель выходит за пределы диапазона Wi-Fi и отключается, или если отправитель переходит в спящий режим и отключается, это считается "неявным" отключением и не должно вызывать остановку приемника.
Другими словами, это действительно получатель, который должен иметь логику, чтобы решить, должен ли он остановить себя или продолжать играть, и чтобы это работало, он должен иметь возможность решить, было ли отключение устройства вызвано неявно или явно. К сожалению, в текущих API SDK получателя, к сожалению, это не включено в событие onSenderDisconnected, которое получает получатель; в следующем обновлении получателя оно изменится, так что получатель сможет увидеть, почему происходит разъединение, по крайней мере, настолько, насколько ему нужно, чтобы отличить явное от неявного. Тогда он может реализовать логику. Между тем отправителю необходимо иметь внеполосный канал для отправки сообщения, указывающего его явное намерение.
Обновление: SDK Receiver был обновлен для получения информации, которая может сказать, был ли отправитель неявно или явно отключен, см. Документацию.
Существует хак, который помогает поддерживать соединение, когда оно идет в фоновом режиме.
Вы можете заменить вызов для 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, когда приложение переходит в фоновый режим