使用AVPlayer获取AirPlay设备的名称

13

当在MPMoviePlayerController中启用AirPlay时,它会显示文本"This video is playing on 设备名称"。使用AVPlayer使用AirPlay时,是否有任何方法可以通过编程方式获取设备名称?


从沉默的回应来看,似乎无法通过编程方式获取设备名称? - coco
4个回答

10

iOS7起,AudioToolbox API的currentRoute被废弃:

相反,苹果在AudioSession中提供了currentRoute API,它允许您检索端口信息以及以一种不错的方式监听audioRouteChangeNotification:

NSString* airplayName = [self activeAirplayOutputRouteName];
if (airplayName) {
    //airplay is active

}

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(audioRouteHasChangedNotification:) name:AVAudioSessionRouteChangeNotification object:[AVAudioSession sharedInstance]];

您想要获取的是 audioSession.currentRouteportDescriptionportType

- (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
}

9

我将发布与ambientlight关于Swift类似的答案。也许对未来的某个人有所帮助。

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())
}

3
这个很好用而且简单,我会把你推到顶部。 - SebastianView
1
你帮了我一个大忙!我谷歌搜了一个小时,才弄清楚如何判断 Airplay 目标设备是否被选择! - Paul Bruneau

8

在搜索其他框架以获得连接的 Apple TV 名称后,我最终在 AudioToolbox 框架中找到了这些信息。可能还有其他方法可以获取此信息,但目前为止,我没有找到其他方法。希望这能帮到你。

您需要导入 AudioToolbox 框架:

#import <AudioToolbox/AudioToolbox.h>

然后需要一个调用方法,用于检测Airplay是否可用

- (BOOL)isAirplayActive {
  CFDictionaryRef currentRouteDescriptionDictionary = nil;
  UInt32 dataSize = sizeof(currentRouteDescriptionDictionary);
  AudioSessionGetProperty(kAudioSessionProperty_AudioRouteDescription, &dataSize, &currentRouteDescriptionDictionary);

  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;
}

听起来很有前途!我会尝试一下并回来。 - Anton
在iOS 8中,您需要更改:if(CFArrayGetCount(outputs) > 0)为:if(outputs && CFArrayGetCount(outputs) > 0)。 - Jason R. Escamilla
有人可以帮忙提供一个Swift版本吗? - Ankit Kumar Gupta

5

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
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接