Prise en charge de la lecture video en arrière-plan ChromeCast iOS

J'ai un problème que quand mon application entre en arrière-plan, le GCKSocket de l'api chromecast iOS se ferme et je reçois ce typr d'erreur de l'API

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

puis, si j'apporte l'application au premier plan, l'API crée automatiquement le socket et met l'état de lecture en pause. Si j'essaie maintenant de lire à nouveau la video, elle joue normalement.

Je commence la lecture du média sur le fil de fond comme ça.

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

Comment maintenir la lecture en vie même lorsque l'application passe en arrière-plan?

voici la notation de l'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)" 

Actuellement, le SDK iOS de Cast ferme le socket lorsque vous passez en arrière-plan, et ce n'est pas un élément configurable à ce stade. Cependant, cela ne signifie pas que votre lecture multimédia sur l'appareil Cast doit s'arrêter; en fait, le comportement correct est le suivant:

  • Si l'user s'est explicitement déconnecté de l'appareil de dissortingbution, et s'il est le dernier appareil connecté au récepteur, alors le récepteur devrait arrêter la lecture, sinon le récepteur devrait continuer la lecture.

La key ici est la partie "explicite"; si, par exemple, l'expéditeur sort de la scope du wifi et se déconnecte, ou si l'expéditeur s'endort et se déconnecte, ils sont considérés comme des déconnections «implicites» et ne doivent pas provoquer l'arrêt du récepteur.

En d'autres termes, c'est vraiment le récepteur qui devrait avoir la logique de décider s'il doit s'arrêter ou continuer à jouer, et pour que cela fonctionne, il doit être capable de décider si une déconnection de périphérique a été provoquée implicitement ou explicitement. Dans les API SDK actuelles du récepteur, malheureusement, cela n'est pas inclus dans l'événement onSenderDisconnected que le récepteur reçoit; dans la prochaine mise à jour du receveur, cela changera pour que le receveur puisse voir pourquoi une déconnection se produit, au less autant qu'il le faut pour distinguer un message explicite d'un message implicite. Ensuite, il peut mettre en œuvre la logique. Pendant ce time, l'expéditeur doit avoir un canal hors bande pour envoyer un message indiquant son intention explicite.

Mise à jour: Receiver SDK a été mis à jour pour avoir les informations permettant de savoir si l'expéditeur a été implicitement ou explicitement déconnecté, voir les docs .

Il y a un hack qui aide à garder la connection en vie quand elle passe en arrière-plan.

Vous pouvez replace l'appel d'une GCKSessionManager.suspendSession (avec 🙂 pour une coutume qui ne se déconnecte pas.

 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) } } 

Appelez simplement la méthode ignoreAppBackgroundModeChange () une fois de n'importe où avant d'entrer en arrière-plan.

Le problème que j'ai trouvé avec ceci est quand vous revenez à l'application que vous allez avoir une erreur de réseau après quelques secondes, parce que Google Cast essaye de se reconnecter à l'appareil.

J'ai corrigé cette reconnection lorsque l'erreur se produit, avec un drapeau pour l'identifier entré en arrière-plan avant.

reference: Comment conserver GCKCastSession en vie lorsque l'application passe en arrière-plan