通过蓝牙命令控制AVAudioRecorder

时间:2019-06-18 11:47:27

标签: ios bluetooth avaudiosession avaudiorecorder callkit

我有这个应用程序,它允许用户记录周围的东西。然后,当他们拥有蓝牙附件(例如耳机)时,他们应该能够通过蓝牙设备上的播放/暂停按钮开始/停止录制会话。

我已经使用MPRemoteCommandCenter成功实现了启动会话。

let rcCenter = MPRemoteCommandCenter.shared()
rcCenter.nextTrackCommand.isEnabled = false
rcCenter.nextTrackCommand.addTarget { _ in return .success }

rcCenter.previousTrackCommand.isEnabled = false
rcCenter.previousTrackCommand.addTarget { _ in return .success }

rcCenter.togglePlayPauseCommand.isEnabled = true
rcCenter.playCommand.isEnabled = true
rcCenter.pauseCommand.isEnabled = true
rcCenter.stopCommand.isEnabled = true

rcCenter.togglePlayPauseCommand.addTarget(self, action: #selector(remotePlayPauseAction(_:)))
rcCenter.playCommand.addTarget(self, action: #selector(remotePlayPauseAction(_:)))
rcCenter.pauseCommand.addTarget(self, action: #selector(remotePlayPauseAction(_:)))
rcCenter.stopCommand.addTarget(self, action: #selector(remotePlayPauseAction(_:)))

但是,它从未遇到过我的蓝牙暂停/停止操作。在设备控制台中看到此消息之前,我不知道发生了什么:

  

默认18:19:46.609673 +0700蓝牙从设备接收到“获取播放状态”请求

     

默认18:19:46.671092 +0700蓝牙从设备接收到AVRCP播放命令

     

//发送音频会话状态,因为应用正在录制等等……

     

默认18:19:48.246780 +0700蓝牙AudioSendThread开始

应用未录制时触发->从蓝牙HDD接收播放命令->开始录制->向蓝牙发送会话。

然后,我将再次按“播放/暂停”按钮并获得以下日志:

  

默认18:20:09.650855 +0700蓝牙收到呼叫挂断事件   (AT + CHUP)来自设备默认值18:20:09.651273   +0700蓝牙发现正在进行的虚拟通话-正在唤醒设备并通知上层。

=>看起来电话正在接收结束通话信号(请注意,没有正在进行的通话,只是会话中的录音)

那么,如何处理此事件?我尝试使用CallKit,但仍然没有用:

let callCenter = CXCallObserver()
callCenter.setDelegate(self, queue: nil)

func callObserver(_ callObserver: CXCallObserver, callChanged call: CXCall) {
   print("Hi!") // not jump in!
}

更新

我试图切换回旧样式处理程序:

UIApplication.shared.beginReceivingRemoteControlEvents()
becomeFirstResponder()
/////////////////
override func remoteControlReceived(with event: UIEvent?) {
    guard let event = event, event.type == .remoteControl else { return }
   // Start / pause actions
}

并且仍然得到相同的结果(可以像以前一样启动但无法停止,得到事件playcall hangup)。现在,我的猜测已切换到AVAudioSession的模式和类别,但仍然没有任何线索。

do {
    let session = AVAudioSession.shared()
    // What is the correct params here? 
    // try session.setCategory(.playAndRecord, mode: .voiceChat, options: [.allowBluetoothA2DP, .allowBluetooth])
    // try session.setCategory(.record, options: .allowBluetooth)
    session.setActive(true)
} catch { print(error) }

1 个答案:

答案 0 :(得分:1)

问题似乎与蓝牙硬件有关。对不起,如果您在这里没有任何建议,我不能给您太多。

我正在做一些不使用AVAudioProducer的荒谬的C ++录音逻辑(我使用的是AudioToolBox Framework),但实际上我遇到了与您相同的问题。

我尝试过的所有市场设备(Jabra OTE23,Jaybird X3,索尼WH1000XM2,官方《星际迷航》通信徽章)都表现出相同的行为,只要打开麦克风,蓝牙设备就会认为它正在虚拟通话中,并且会仅发出呼叫AVRCP事件。出于某种原因,iOS似乎没有办法监听这些呼叫AVRCP事件。

我公司中有一个内部设备,每当麦克风打开且设备处于录制状态时,(可能是偶然)会同时发出暂停和挂断事件。结果,我可以暂停并继续录制。请注意,该设备是专门为录制音频而设计的。在此处进行证明:

default 15:38:53.994336 -0500   bluetoothd  Received call hangup event (AT+CHUP) from device <private>
default 15:38:53.998181 -0500   bluetoothd  Found ongoing virtual call - Acking device and notifying upper layers.
default 15:38:54.001477 -0500   locationd   service mask 0x1 event type 2 event 104 result 0
default 15:38:54.186054 -0500   powerlogHelperd {"msg":"CLCopyAppsUsingLocation", "event":"activity"}
default 15:38:54.473038 -0500   bluetoothd  Received AVRCP Pause command from device <private>
default 15:38:54.475637 -0500   BTAvrcp Request: Command = <Pause>, SenderDevice = <M’s iPhone>, SenderBundleIdentifier = <BTAvrcp>, SenderPID = <419>, commandID = <B46341E9-7B98-4ACE-94A3-D84A8F4A63B1>, remote control interface = <com.apple.AVRCP>, appOptions = <0>, options = <{kMRMediaRemoteOptionSourceID = "00:13:8A:20:1C:70";}> (null) for origin-M’s iPhone-1280262988/client-com.mmodal.SDK.SettingsTest-1015 (SettingsTest)/player-MediaRemote-DefaultPlayer

为什么该设备的行为与其他主流设备不同?我还不知道我真的只是希望iOS(和Android)能​​够监听所有原始AVRCP事件,但现在似乎并非如此。

蓝牙是一种疯狂的技术堆栈...

相关问题