# AirPlay

AirPlay is a proprietary wireless technology developed by Apple Inc. that allows users to stream audio, video, and other media content from their Apple devices to compatible devices such as speakers, TVs, and computers.

With AirPlay, you can effortlessly mirror the screen of your iPhone, iPad, or Mac onto a larger display, enabling you to share photos, videos and presentations.

Route picker (`AVRoutePickerView`) is the default supported way to integrate:

    let routePickerView = AVRoutePickerView()

## CastAPI

The SDK introduces `CastAPI` and its `AirPlay` implementation. To start with `AirPlay` via `CastAPI` first register a plugin to PRESTOplay SDK:

    import PRESTOplay
    import CastlabsApple

    ...

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

### Configuration

    var cast = PRESTOplaySDK.shared.cast(for: player, engine: .airplay)

It is important to add a Cast Button (which internally is `AVRoutePickerView`) to the view hierarchy, so users can select a cast destination device.

### State

AirPlay state is reported to `CastAPI`.

    cast?.onCastState = { [weak self] state in
        guard let self else { return }
        print("<<<< AirPlay state: \(state)")
        switch state {
        case .ready:
            if let castButton = cast?.button,
                let airPlayButton = castButton as? AVRoutePickerView {
                airPlayButton.prioritizesVideoDevices = true

                DispatchQueue.main.async {
                    airPlayButton.frame = CGRect(
                        x: 30.0,
                        y: 150.0,
                        width: 30.0,
                        height: 30.0
                    )
                    airPlayButton.center = self.view.center
                    self.view.addSubview(airPlayButton)
                }
            }
        case .sessionStart: break
        case .sessionResume: break
        case .sessionEnd: break
        case .unknown: break
        case .idle: break
        case .playing:
            print("Tracks: \(String(describing: cast?.tracks))")
        case .paused: break
        case .buffering: break
        case .loading: break
        case .sessionStarting: break
        case .error: break
        @unknown default: break
        }
    }

## Auth token

Airplay is supported and no changes are required from the SDK user. Specifically:

- HLS streams are natively supported, i.e. you only need to switch on Airplay on your device
- MPEG-DASH requires to switch on Airplay and to active the screen mirroring

By default, AirPlay is disabled for DRM-encrypted content. To enable, set preventSecondScreenPlayback to false in the DRM configuration.

    playerConfiguration.drmConfiguration?.preventSecondScreenPlayback = false

If the content requires an authentication token (playerConfiguration.drmConfiguration.authToken), implement the `PRESTOplaySDK.shared.onAirplayAuthTokenRequired()` method to provide authentication key for AirPlay. For example,

    PRESTOplaySDK.shared.onAirplayAuthTokenRequired = { [weak self] playerConfiguration in
        guard let self,
              let configurationUrl = playerConfiguration.configurationUrl else {
            return nil
        }

        var authToken: String?
        let group = DispatchGroup()
        group.enter()
        Utils.loadAuthToken(from: configurationUrl, userToken: self.userToken) { token in
            authToken = token
            group.leave()
        }
        let _ = group.wait(timeout: .now() + 10)
        return authToken
    }

In the example code, the `userToken` is a key obtained from your DRM provider.