【问题标题】:Headphones plugin/out detection in SwiftSwift 中的耳机插件/输出检测
【发布时间】:2015-01-15 18:09:40
【问题描述】:

我正在开发适用于 iOS 8.1 的 iphone 应用程序,该应用程序与核心音频一起生成频率并调整强度。在我生成频率的视图控制器中,如果耳机在某个时刻被拔出,我需要控制,我已经在控制耳机是否已连接,然后再使用以下功能进入我的频率发生器视图:

- (BOOL)isHeadsetPluggedIn {
    AVAudioSessionRouteDescription* route = [[AVAudioSession sharedInstance]   currentRoute];
    for (AVAudioSessionPortDescription* desc in [route outputs]) {
        if ([[desc portType] isEqualToString:AVAudioSessionPortHeadphones])
            return YES;
    }
    return NO;
}

这个函数在 C 中,因为我使用 core-audio 来生成频率,但是在视图控制器中我使用 swift,所以需要一种方法来实现侦听器来检测耳机拔出事件并返回到对于上一个视图的用户,我不知道我是否可以将我的函数 isHeadsetPluggedin() 与事件侦听器一起使用,或者我应该创建一个新的。 在我的 MenuViewController 中,我使用以下函数控制是否插入耳机:

func isHeadsetPluggedIn() -> Bool {
    return freqController.isHeadsetPluggedIn();
}     

【问题讨论】:

  • this function is in C Objective-C ;)

标签: iphone swift core-audio ios8.1


【解决方案1】:

在 Swift 4 中

    func activateHeadPhonesStatus(){
     NotificationCenter.default.addObserver(self, selector: #selector(audioRouteChangeListener(_:)), name: AVAudioSession.routeChangeNotification, object: nil)
    }

    @objc func audioRouteChangeListener(_ notification:Notification) {
            guard let userInfo = notification.userInfo,
                let reasonValue = userInfo[AVAudioSessionRouteChangeReasonKey] as? UInt,
                let reason = AVAudioSession.RouteChangeReason(rawValue:reasonValue) else {
                    return
            }
            switch reason {
            case .newDeviceAvailable:
                let session = AVAudioSession.sharedInstance()
                for output in session.currentRoute.outputs where output.portType == AVAudioSession.Port.headphones {
                    headphonesConnected = true
                    print("headphone plugged in")
                    break
                }
            case .oldDeviceUnavailable:
                if let previousRoute =
                    userInfo[AVAudioSessionRouteChangePreviousRouteKey] as? AVAudioSessionRouteDescription {
                    for output in previousRoute.outputs where output.portType == AVAudioSession.Port.headphones {
                        headphonesConnected = false
                        print("headphone pulled out")
                        break
                    }
                }
            default: ()
            }

        }

【讨论】:

  • 这对我不起作用,直到我通过 AVAudioSession.sharedInstance() 作为通知中心的参数对象而不是 nil,即` NotificationCenter.default.addObserver(self, selector: #selector(audioRouteChangeListener (_:)),名称:AVAudioSession.routeChangeNotification,对象:AVAudioSession.sharedInstance())`
  • 它对我有用。最初我将耳机连接设置为 --> 文件私有 var 耳机连接 : Bool = AVAudioSession.isHeadphonesConnected 扩展 AVAudioSession { static var isHeadphonesConnected: Bool { return sharedInstance().isHeadphonesConnected } var isHeadphonesConnected: Bool { return !currentRoute.outputs.filter { $0.isHeadphones }.isEmpty } } 扩展 AVAudioSessionPortDescription { var isHeadphones: Bool { return portType == AVAudioSession.Port.headphones } }
【解决方案2】:

这个article 为我工作。还有一个带有解决方案的GitHub repo。如果你不想看,这里是我的代码:

把它放在你的 INIT 方法中:

    self.session = AVAudioSession.sharedInstance()
    let currentRoute = self.session.currentRoute
    if currentRoute.outputs.count != 0 {
        for description in currentRoute.outputs {
            if description.portType == AVAudioSessionPortHeadphones {
                print("headphone plugged in")
            } else {
                print("headphone pulled out")
            }
        }
    } else {
        print("requires connection to device")
    }

    NSNotificationCenter.defaultCenter().addObserver(
        self,
        selector: #selector(YOUR_VIEW_CONTROLLER_OR_VIEW.audioRouteChangeListener(_:)),
        name: AVAudioSessionRouteChangeNotification,
        object: nil)

把它放在你班级的任何地方:

 dynamic private func audioRouteChangeListener(notification:NSNotification) {
    let audioRouteChangeReason = notification.userInfo![AVAudioSessionRouteChangeReasonKey] as! UInt

    switch audioRouteChangeReason {
    case AVAudioSessionRouteChangeReason.NewDeviceAvailable.rawValue:
        print("headphone plugged in")
    case AVAudioSessionRouteChangeReason.OldDeviceUnavailable.rawValue:
        print("headphone pulled out")
    default:
        break
    }
}

保重!

【讨论】:

    【解决方案3】:

    您可以通过观察AVAudioSessionRouteChangeNotification 通知来跟踪路线变化。

    //Observe for route changing notification
        [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(handleRouteChange:) name:AVAudioSessionRouteChangeNotification object:[AVAudioSession sharedInstance]];
    
       -(void)handleRouteChange:(NSNotification *)notif
        {
           NSDictionary *dict = notif.userInfo;
           AVAudioSessionRouteDescription *routeDesc = dict[AVAudioSessionRouteChangePreviousRouteKey];
           AVAudioSessionPortDescription *prevPort = [routeDesc.outputs objectAtIndex:0];
           if ([prevPort.portType isEqualToString:AVAudioSessionPortHeadphones]) {
                //Head phone removed
              }
         }
    

    【讨论】:

      猜你喜欢
      • 2017-04-24
      • 2012-01-18
      • 2010-10-26
      • 2011-04-04
      • 2013-11-11
      • 1970-01-01
      • 2013-05-08
      • 2011-09-09
      • 2016-02-25
      相关资源
      最近更新 更多