iOSで外部出力(AirPlayやHDMI)を検出する方法

AVPlayerのexternalPlaybackActiveを利用せずに外部出力を検出する方法を調べることがあったのでメモしておきます。

AVPlyaerを利用する方法

以下のようにAVPlayerのプロパティを利用すれば外部出力を検出することができます。

参考:AVPlayer Class Reference

登録

// externalPlaybackActiveのコールバック
[_avPlayer addObserver:self
            forKeyPath:MVAvPlayerExternalPlaybackActive
               options:(NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld)
               context:nil];

KVO

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if ([keyPath isEqualToString:MVAvPlayerExternalPlaybackActive]) {
       // 検知したときの処理
    }
}

ただ上記だとAVPlayerが再生していないと検知できません。

AVAudioSessionを利用する

参考:Get name of AirPlay device using AVPlayer

上記はiOS7でdeprecatedなメソッドを利用しているので少し変更しました。

- (BOOL)isExternalPlayback
{
   __block BOOL isExternalOutput = NO;
   // 入出力を取得
   AVAudioSessionRouteDescription *audioRouteDesc = [[AVAudioSession sharedInstance] currentRoute];
   // 出力を取得
   NSArray *outputs = audioRouteDesc.outputs;
   [outputs enumerateObjectsUsingBlock:^(AVAudioSessionPortDescription *audioDesc, NSUInteger idx, BOOL *stop) {
       if([audioDesc.portType isEqualToString:AVAudioSessionPortAirPlay]){
           NSLog(@"AirPlay(๑˃̵ᴗ˂̵)و");
           *stop = YES;
           isExternalPlayback = YES;
       } else if ([audioDesc.portType isEqualToString:AVAudioSessionPortHDMI]){
           NSLog(@"HDMI(。╹ω╹。)");
           *stop = YES;
           isExternalOutput = YES;
       } else {
           // その他
       }
   }];

   return result;
}