如何在 iOS 设备上检测耳机(扬声器)的可用性?
Posted
技术标签:
【中文标题】如何在 iOS 设备上检测耳机(扬声器)的可用性?【英文标题】:How to detect ear piece (speaker) availability on iOS devices? 【发布时间】:2016-12-29 06:51:21 【问题描述】:我想专门在 iPad 上检测是否有可用的耳机。
例如 - 我可以检测 ios 设备是否有使用 AVFoundation,所以有什么方法可以检测耳机的可用性。
【问题讨论】:
【参考方案1】:1) 如果您想检查设备上是否有耳机(接收器扬声器)
您可以通过简单地识别设备是否为 iPhone 来识别这一点。
UIDevice.current.userInterfaceIdiom == .phone
在 iOS 原型中 AVAudioSessionPortBuiltInReceiver
用于内置 Inreceriver 扬声器。
根据apple's documentation,这仅适用于 iPhone 设备。所以没有必要检查其他任何东西,如果它的 iPhone,你有耳机,如果它不是 iPhone(在 ipad 上)它没有耳机。
2)如果要检查耳机是否连接:
您可以使用共享音频会话的当前路由来检查耳机是否连接: 这是 swift 3.0
中的示例函数 func IsHeadSetConnected() -> Bool
let route = AVAudioSession.sharedInstance().currentRoute;
for desc in route.outputs
let portType = desc.portType;
if (portType == AVAudioSessionPortHeadphones)
return true;
return false;
你还应该通过监听路由变化来监控它的状态:
NotificationCenter.default.addObserver(self, selector: #selector(handleRouteChange(_:)), name: NSNotification.Name.AVAudioSessionRouteChange, object: nil)
这是上述通知设置处理程序的示例代码:
func handleRouteChange(_ notification: Notification)
guard
let userInfo = notification.userInfo,
let reasonRaw = userInfo[AVAudioSessionRouteChangeReasonKey] as? NSNumber,
let reason = AVAudioSessionRouteChangeReason(rawValue: reasonRaw.uintValue)
else fatalError("Strange... could not get routeChange")
switch reason
case .oldDeviceUnavailable:
print("oldDeviceUnavailable")
case .newDeviceAvailable:
print("headset/line plugged in")
case .routeConfigurationChange:
print("headset pulled out")
case .categoryChange:
print("Just category change")
default:
print("not handling reason")
【讨论】:
在注意到您对其他答案的评论后,我理解您的问题。所以相应地更新了我的答案。希望这会有所帮助! 我现在面临另一个问题,也许您有任何解决办法:1 - 我插入耳机 -> 我的音频路由更改回调被调用。 2 - 然后我将声音切换到扬声器(无需拔下耳机)-> 调用音频路由更改回调。 3 - 然后我拔下耳机(当声音仍在输出到扬声器时)-> 不调用音频路由更改回调,这似乎是合乎逻辑的。但这是我的问题!所以我的问题是:你有没有办法检测到最后一种情况下耳机被拔掉了? @Nilesh 你在这种情况下找到解决方案了吗。【参考方案2】:斯威夫特 3:
import AVFoundation
let currentRoute = AVAudioSession.sharedInstance().currentRoute
for description in currentRoute.outputs
if description.portType == AVAudioSessionPortLineOut
else if description.portType == AVAudioSessionPortHeadphones
else if description.portType == AVAudioSessionPortBluetoothA2DP
else if description.portType == AVAudioSessionPortBuiltInReceiver
else if description.portType == AVAudioSessionPortBuiltInSpeaker
else if description.portType == AVAudioSessionPortHDMI
else if description.portType == AVAudioSessionPortAirPlay
else if description.portType == AVAudioSessionPortBluetoothLE
参考:
苹果文档:https://developer.apple.com/reference/avfoundation/avaudiosessionportdescription/1669281-output_port_types
【讨论】:
我建议使用switch
而不是if/else if/.../else if
@Pang Ho Ming 有什么办法可以录制耳机的声音吗?【参考方案3】:
一个班轮Swift 4+解决方案:
检测内置麦克风是否可用
let isMicAvailable: Bool = AVAudioSession.sharedInstance().availableInputs?.first(where: $0.portType == AVAudioSessionPortBuiltInMic ) != nil
检测耳机(接收器扬声器)是否可用
let isEarPieceAvailable: Bool = AVAudioSession.sharedInstance().currentRoute.outputs.first(where: $0.portType == AVAudioSessionPortBuiltInReceiver ) != nil
【讨论】:
【参考方案4】:简短而简单的方法是通过contains
进行检查。
func isHeadphonesConnected() -> Bool
let routes = AVAudioSession.sharedInstance().currentRoute
return routes.outputs.contains(where: (port) -> Bool in
port.portType == AVAudioSessionPortHeadphones
)
【讨论】:
其实和 iPhone 一样,我们可以在扬声器和听筒之间切换,但在 iPad 中我们只有扬声器,我担心某些型号是否有像手机一样的听筒扬声器,所以我想检测设备是否有听筒与否。【参考方案5】:检查
if let availableInputs = AVAudioSession.sharedInstance().availableInputs
for route in availableInputs
if ( route.portType == AVAudioSessionPortBuiltInMic )
//built-in-mic available
break;
【讨论】:
【参考方案6】:您可以检查内置麦克风是否可用。
var isMicAvailable = false
if let availableInputs = AVAudioSession.sharedInstance().availableInputs
for route in availableInputs
if ( route.portType == AVAudioSessionPortBuiltInMic )
//built-in-mic available
isMicAvailable = true
break;
print("current device has mic - \(isMicAvailable)")
另一种检查当前设备是否为 iPhone 的方法。
NSString *deviceType = [UIDevice currentDevice].model;
if([deviceType isEqualToString:@"iPhone"])
//current device is iPhone.
【讨论】:
以上是关于如何在 iOS 设备上检测耳机(扬声器)的可用性?的主要内容,如果未能解决你的问题,请参考以下文章
在 Mac OS X 上使用 AudioUnit 检测扬声器/耳机
如何检测音频当前是不是正在 Android 手机扬声器上播放?