Reputation: 6033
When AirPlay is enabled in a MPMoviePlayerController, it displays a text "This video is playing on device name ". When using AirPlay with an AVPlayer, is there any way to programatically get the device name?
Upvotes: 13
Views: 6997
Reputation: 1076
Swift 4
private func addAirplayNotifier() {
NotificationCenter.default.addObserver(
self,
selector: #selector(airplayChanged),
name: AVAudioSession.routeChangeNotification,
object: AVAudioSession.sharedInstance())
}
@objc func airplayChanged() {
isAirPlaying = false
let currentRoute = AVAudioSession.sharedInstance().currentRoute
for output in currentRoute.outputs where output.portType == AVAudioSession.Port.airPlay {
print("Airplay Device connected with name: \(output.portName)")
isAirPlaying = true
}
}
Upvotes: 5
Reputation: 2916
I'll post a similar answer than ambientlight for swift. Maybe it is helpful for someone in the future.
private func addAirplayNotifier() {
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("airplayChanged:"), name: AVAudioSessionRouteChangeNotification, object: AVAudioSession.sharedInstance())
}
func airplayChanged(sender:NSNotification) -> Bool {
var airplayConnected = false
let currentRoute = AVAudioSession.sharedInstance().currentRoute
for output in currentRoute.outputs {
if output.portType == AVAudioSessionPortAirPlay {
print("Airplay Device connected with name: \(output.portName)")
airplayConnected = true
}
}
print("Disconnect Airplay")
return airplayConnected
}
Swift 3.0
private func addAirplayNotifier() {
NotificationCenter.default.addObserver(self, selector: Selector("airplayChanged:"), name:NSNotification.Name.AVAudioSessionRouteChange, object: AVAudioSession.sharedInstance())
}
Upvotes: 9
Reputation: 7332
Starting from iOS7 AudioToolbox API for currentRoute becomes deprecated:
Apple instead made currentRoute API available to you in AudioSession, which allows retrieving it's port information as well as listening to audioRouteChangeNotification in a nice way:
NSString* airplayName = [self activeAirplayOutputRouteName];
if (airplayName) {
//airplay is active
}
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(audioRouteHasChangedNotification:) name:AVAudioSessionRouteChangeNotification object:[AVAudioSession sharedInstance]];
(what you want to get is the portType
of portDescription
of audioSession.currentRoute
):
- (NSString*)activeAirplayOutputRouteName
{
AVAudioSession* audioSession = [AVAudioSession sharedInstance];
AVAudioSessionRouteDescription* currentRoute = audioSession.currentRoute;
for (AVAudioSessionPortDescription* outputPort in currentRoute.outputs){
if ([outputPort.portType isEqualToString:AVAudioSessionPortAirPlay])
return outputPort.portName;
}
return nil;
}
- (void)audioRouteHasChangedNotification:(NSNotification*)notification
{
//do something
}
Upvotes: 10
Reputation: 112
After searching in other frameworks to get the name of the Apple TV you're connected to, I finally found this information in the AudioToolbox framework. There may be other ways to get this, but so far I have not found another way. Hope this helps.
You'll need to import the AudioToolbox framework:
#import <AudioToolbox/AudioToolbox.h>
and then a method to call when you want to detect if airplay is available
- (BOOL)isAirplayActive {
CFDictionaryRef currentRouteDescriptionDictionary = nil;
UInt32 dataSize = sizeof(currentRouteDescriptionDictionary);
AudioSessionGetProperty(kAudioSessionProperty_AudioRouteDescription, &dataSize, ¤tRouteDescriptionDictionary);
self.deviceOutputType = nil;
self.airplayDeviceName = nil;
if (currentRouteDescriptionDictionary) {
CFArrayRef outputs = CFDictionaryGetValue(currentRouteDescriptionDictionary, kAudioSession_AudioRouteKey_Outputs);
if(CFArrayGetCount(outputs) > 0) {
CFDictionaryRef currentOutput = CFArrayGetValueAtIndex(outputs, 0);
//Get the output type (will show airplay / hdmi etc
CFStringRef outputType = CFDictionaryGetValue(currentOutput, kAudioSession_AudioRouteKey_Type);
//If you're using Apple TV as your ouput - this will get the name of it (Apple TV Kitchen) etc
CFStringRef outputName = CFDictionaryGetValue(currentOutput, @"RouteDetailedDescription_Name");
self.deviceOutputType = (NSString *)outputType;
self.airplayDeviceName = (NSString *)outputName;
return (CFStringCompare(outputType, kAudioSessionOutputRoute_AirPlay, 0) == kCFCompareEqualTo);
}
}
return NO;
}
Upvotes: 8