# Chromecast

Chromecast is a streaming media device developed by Google that allows users to wirelessly stream audio and video content from various devices to a television or display. It plugs into the HDMI port of the TV and connects to the user’s Wi-Fi network. Chromecast enables users to “cast” or send content from supported apps on their smartphones, tablets, or computers to the TV, essentially turning it into a smart TV.

We provide pre-integrations with the Cast SDK for iOS. In most cases, you will only need to initialize the plugin with your Chromecast `appId` and optional custom data.

## Cast API/SDK

The Cast SDK allows a user to select streaming audio-visual content using a Sender, and play it on (or cast it to) another device known as the Receiver, while controlling playback using the Sender.

The term Sender refers to an app that plays the role of controller for the Cast session. A Sender initiates the Cast session and manages the user’s interaction with the content.

There are many kinds of Senders, including mobile apps and Google Chrome web apps, as well as virtual control surfaces on touch-enabled Google Home devices. The media controls in the Chrome web browser function as a Sender, as does Google Assistant itself.

The term Receiver refers to an app running on a Cast-enabled device that is responsible for responding to Sender commands and for conveying streaming content from an online streaming service to the Cast-enabled device. Examples of Cast-enabled Receiver devices include Chromecasts, smart televisions, smart screens, and smart speakers.

The Cast SDK also supports multiple Senders connecting to a Cast session. For instance, one Sender could start a session on a Receiver and another Sender could join the same session to control playback, load new content, or queue more content for later.

(Source: https://developers.google.com/cast/docs/overview)

### Integrate

To start with Chromecast, first register the plugin to PRESTOplay SDK:

    import PRESTOplay
    import CastlabsChromecast

    ...

    PRESTOplaySDK.shared.setup("LICENSE", [ChromecastPlugin()])

### Configuration

First make sure your app meets all the configuration and requirements needed by Google (https://developers.google.com/cast/docs/ios_sender). Especially `Info.plist` entries for `NSBonjourServices` and `NSLocalNetworkUsageDescription`. Otherwise your application may crash.

We use `no bluetooth` versions of the Google Cast SDK.

    let appId = "6BF5C590"
    let castSettings = CastSettings(appId)
    castSettings.debug = true

    var cast = PRESTOplaySDK.shared.cast(for: castSettings)

It is important to add a Cast Button to the view hierarchy, so users can select a cast destination device.

### State

Chromecast state is reported to `CastAPI`.

To start a Chromecast session one has to first call `load` method, which takes `PlayerConfiguration` and passes it to Chromecast remote device. After a successful load, you can operate on the `cast` object as a regular player. You can `play`, `pause`, `seek`, etc.

    cast?.onCastState = { [weak self] state in
        guard let self else { return }
        switch state {
        case .ready:
            if let castButton = cast?.button {
                DispatchQueue.main.async {
                    castButton.center = self.view.center
                    self.view.addSubview(castButton)
                }
            }
        case .sessionStart:
            if let config = playerConfig {
                self.player.pause()
                cast?.load(config)
            }
        case .sessionResume: break
        case .sessionEnd:
            self.player.play()
        case .unknown: break
        case .idle: break
        case .playing:
            print("Tracks: \(String(describing: cast?.tracks))")
        case .paused: break
        case .buffering: break
        case .loading: break
        case .error:
            cast?.endSession(true)
        @unknown default: break
        }
    }

By calling `load` method you can provide a custom `PlayerConfiguration`. For instance: for protected Fairplay HLS stream you can `load` MPEG-DASH stream.

### Ads

Chromecast Plugins supports IMA ads. One can enable them by setting `imaUrl` in CastSettings object:

    castSettings.imaUrl = UserPreferences.Ads.imaTagUrl

### Chromecast notes

        On iOS 14.+ you have to enable the "NSBonjourServices" (to find devices with your Receiver App Id) and "NSLocalNetworkUsageDescription" in your app Info.plist to explain iOS Local Network access. For more info: https://developers.google.com/cast/docs/ios_sender/ios_permissions_changes

        On iOS 13.+ you have to enable the "Privacy - Bluetooth Always Usage Description" in your app Info.plist to explain the Bluetooth® usage (if in use).

        On iOS 12.+ you have to enable the "Access Wifi Information" capability to make Chromecast devices discoverable by GCKCastContext's discovery manager.

        If you plan to integrate Cast SDK manually, please read: https://developers.google.com/cast/docs/ios_sender/#manual_setup