AirPlay is a protocol that allows wireless streaming between devices of audio, video, device screens, and photos, together with related metadata. Using this protocol, it is possible to view your media content on other devices compatible with Apple.
Background
If you are using Lumen SDK on your mobile device or any other apple device and wish to stream your content on any other device such as Apple TV, it is important to follow certain procedures in order to not break your playback.
This is because Lumen (Streamroot) operates as a proxy which hides visibility of the URL of the media content from your device to any other apple device such as Apple TV. The media content URL is converted to a local URL to talk to our proxy. The resulting URL is then a local host URL (Eg: https://localhost:888/).
This URL cannot be read by the device you are trying to stream to since its a local URL. As a result, playback will not begin and you won't be able to stream your media content.
The original URL has to be provided to the device you are trying to cast to in order to stream your media content.
Solution
You can use the following proposition while using Airplay. This will detect if the AirPlay is being used or not. This is determined by detecting the audio output of your device. If the audio output type is "AirPlay", the actual URL of the media content is sent to your device for streaming without Lumen on that device which ensures that the playback is not broken.
// MARK: - Airplay support
/// To detect actual airplay switch we can use the device audio output
// we need to register to AVAudioSession.routeChangeNotification
private func registerAirplayNotification() {
NotificationCenter.default.addObserver(
self,
selector: #selector(audioOutputDidChange),
name: AVAudioSession.routeChangeNotification,
object: AVAudioSession.sharedInstance())
}
@objc func audioOutputDidChange() {
// Get the current audio route
let currentRoute = AVAudioSession.sharedInstance().currentRoute
// Check if the audio output is an airplay type
guard let airplayOutput = currentRoute.outputs.filter({$0.portType == .airPlay}).first else {
return
}
// Save the current playbacktime
let time = self.player?.currentTime()
// Create a player item with the original url
let newItem = AVPlayerItem(url: manifestUrl)
// Replace the player item to bypass local proxy
self.player?.replaceCurrentItem(with: newItem)
// Seek to last saved time, especially helpful for VOD streams
if time != nil {
self.player?.seek(to: time!)
}
print("Airplay device name: \(airplayOutput.portName)")
}
}
If you disconnect AirPlay in the middle of the session and continue playback on your original device, playback will not break but Lumen SDK won't operate anymore unless you reconnect it.