feat: ability to resume mic redirection after a phone call
This commit is contained in:
1 parent
ef60aeeead
commit
e64090d88f
2 files changed
+39
-1
No files matched your search
@@ -2,7 +2,7 @@
|
|||||||
// InertialScroller.swift
|
// InertialScroller.swift
|
||||||
// VoidLink
|
// VoidLink
|
||||||
//
|
//
|
||||||
// Created by True砖家 on 2025/11/5.
|
// Created by True砖家 on 2025/12/5.
|
||||||
// Copyright © 2025 True砖家 on Bilibili. All rights reserved.
|
// Copyright © 2025 True砖家 on Bilibili. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import Collections
|
|||||||
@objcMembers
|
@objcMembers
|
||||||
public class MicHandler: NSObject {
|
public class MicHandler: NSObject {
|
||||||
|
|
||||||
|
private var notificationTokens = [NSObjectProtocol]()
|
||||||
private let engine = AVAudioEngine()
|
private let engine = AVAudioEngine()
|
||||||
private let playerNode = AVAudioPlayerNode()
|
private let playerNode = AVAudioPlayerNode()
|
||||||
private var audioSink: Any?
|
private var audioSink: Any?
|
||||||
@@ -48,6 +49,16 @@ public class MicHandler: NSObject {
|
|||||||
|
|
||||||
@objc public init(useBuiltinMic:Bool) {
|
@objc public init(useBuiltinMic:Bool) {
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
|
let token = NotificationCenter.default.addObserver(
|
||||||
|
forName: AVAudioSession.interruptionNotification,
|
||||||
|
object: nil,
|
||||||
|
queue: .main
|
||||||
|
) { [weak self] notification in
|
||||||
|
self?.handleInterruption(notification)
|
||||||
|
}
|
||||||
|
notificationTokens.append(token)
|
||||||
|
|
||||||
self.useBuiltinMic = useBuiltinMic
|
self.useBuiltinMic = useBuiltinMic
|
||||||
do {
|
do {
|
||||||
try configureSession()
|
try configureSession()
|
||||||
@@ -140,6 +151,29 @@ public class MicHandler: NSObject {
|
|||||||
|
|
||||||
/* ----------- Audio Session -------------*/
|
/* ----------- Audio Session -------------*/
|
||||||
|
|
||||||
|
private func handleInterruption(_ notification: Notification) {
|
||||||
|
guard let info = notification.userInfo,
|
||||||
|
let typeValue = info[AVAudioSessionInterruptionTypeKey] as? UInt,
|
||||||
|
let type = AVAudioSession.InterruptionType(rawValue: typeValue)
|
||||||
|
else { return }
|
||||||
|
|
||||||
|
switch type {
|
||||||
|
case .began:
|
||||||
|
self.stopTapping(stopEngine: true)
|
||||||
|
case .ended:
|
||||||
|
do {
|
||||||
|
try configureEngine()
|
||||||
|
} catch {
|
||||||
|
notify(error)
|
||||||
|
}
|
||||||
|
DispatchQueue.global().asyncAfter(deadline: .now() + 0.5) {
|
||||||
|
self.startTapping()
|
||||||
|
}
|
||||||
|
@unknown default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private func configureOpus(sampleRate: Int32, channels: Int) throws {
|
private func configureOpus(sampleRate: Int32, channels: Int) throws {
|
||||||
var err: Int32 = 0
|
var err: Int32 = 0
|
||||||
guard let enc = opus_encoder_create(sampleRate, Int32(channels), OPUS_APPLICATION_VOIP, &err), err == OPUS_OK else {
|
guard let enc = opus_encoder_create(sampleRate, Int32(channels), OPUS_APPLICATION_VOIP, &err), err == OPUS_OK else {
|
||||||
@@ -336,6 +370,10 @@ public class MicHandler: NSObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@objc public func clean() {
|
@objc public func clean() {
|
||||||
|
for token in notificationTokens {
|
||||||
|
NotificationCenter.default.removeObserver(token)
|
||||||
|
}
|
||||||
|
notificationTokens.removeAll()
|
||||||
self.timer?.clean()
|
self.timer?.clean()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user