How to configure a different stream to Chromecast on iOS
Some streaming setups require you to cast a different stream to a Chromecast Receiver device than the one playing on a Chromecast Receiver device. For example, if you're playing HLS + FairPlay DRM on your iOS application, you need to cast a different source with DASH + Widevine DRM to your Chromecast application, because Chromecast applications aren't able to support FairPlay.
You can achieve this use case with the ChromecastConnection API.
ChromecastConnection API
The ChromecastConnection API allows you to implement callbacks related to Chromecast playback.
To achieve the described use case you can use the onStart (i.e. the start of a Chromecast session) to set a new stream,
and onStop (i.e. the end of a Chromecast session) to (re)set your previous stream.
You may also be interested in onJoin (i.e. joining an existing Chromecast session with a new device) or
onLeave (i.e. leaving an existing Chromecast session on a device).
To achieve this use case on the iOS SDK, you have to leverage the ChromecastConnectionDelegate
of your THEOplayer object.
The snippet below is an example of how your ChromecastConnectionDelegate could look like.
This particular snippet has two sources:
senderSourceis intended for playback on your sender device (i.e. your iOS app)chromecastSourceis intended for playback on your Chromecast application
The ChromecastConnectionDelegate is used to:
- Set the
chromecastSourcewhen Chromecast playback starts through theonStartcallback. - Revert to the
senderSourcewhen Chromecast playback stops through theonStopcallback.
import UIKit
import THEOplayerSDK
class ChromecastController: ChromecastConnectionDelegate {
weak var theoplayer : THEOplayer?
private var senderSource: SourceDescription {
let typedSource = TypedSource(
src: "https://cdn.theoplayer.com/video/big_buck_bunny/big_buck_bunny_metadata.m3u8",
type: "application/x-mpegurl"
)
return SourceDescription(source: typedSource)
}
private var chromecastSource: SourceDescription {
let typedSource = TypedSource(
src: "https://amssamples.streaming.mediaservices.windows.net/622b189f-ec39-43f2-93a2-201ac4e31ce1/BigBuckBunny.ism/manifest(format=mpd-time-csf)",
type: "application/dash+xml",
drm: WidevineDRMConfiguration(licenseAcquisitionURL: "https://amssamples.keydelivery.mediaservices.windows.net/Widevine/?KID=1ab45440-532c-4399-94dc-5c5ad9584bac")
)
return SourceDescription(source: typedSource)
}
init(theo : THEOplayer) {
self.theoplayer = theo
self.theoplayer?.cast?.chromecast?.setConnectionDelegate(self)
}
func onStart(sourceDescription: SourceDescription?) -> SourceDescription? {
return chromecastSource
}
func onStop(sourceDescription: SourceDescription?) -> SourceDescription? {
return senderSource
}
func onJoin(sourceDescription: SourceDescription?) -> SourceDescription? {
return sourceDescription
}
func onLeave(sourceDescription: SourceDescription?) -> SourceDescription? {
return sourceDescription
}
}
The onJoin and onLeave implementations in the above snippet adhere to the default behavior.
Once you've implemented your ChromecastConnectionDelegate, you have to initialize an instance of this near the code of your where
you're setting your player.source (e.g. https://github.com/THEOplayer/samples-ios-sdk/blob/master/Google-Cast/Google_Cast/PlayerViewController.swift).
The snippet below demonstrates this concept:
...
class PlayerViewController: UIViewController {
...
var chromecastController : ChromecastController!
var senderSource: SourceDescription {
let typedSource = TypedSource(
src: "https://cdn.theoplayer.com/video/big_buck_bunny/big_buck_bunny_metadata.m3u8",
type: "application/x-mpegurl"
)
return SourceDescription(source: typedSource)
}
...
override func viewDidLoad() {
...
player.source = senderSource
chromecastController = ChromecastController(theo: theoplayer)
...
}
...
}
...