36 lines
1.6 KiB
Swift
36 lines
1.6 KiB
Swift
|
|
import Foundation
|
||
|
|
import Capacitor
|
||
|
|
import AVFoundation
|
||
|
|
|
||
|
|
// Earpiece <-> speaker toggle for calls. Registered by cap sync as a normal Capacitor plugin package, so it
|
||
|
|
// appears as window.Capacitor.Plugins.AudioRoute (unlike an app-embedded class, which gets stripped/not
|
||
|
|
// discovered in release builds). setSpeaker({on}) overrides the AVAudioSession output port.
|
||
|
|
@objc(AudioRoutePlugin)
|
||
|
|
public class AudioRoutePlugin: CAPPlugin, CAPBridgedPlugin {
|
||
|
|
public let identifier = "AudioRoutePlugin"
|
||
|
|
public let jsName = "AudioRoute"
|
||
|
|
public let pluginMethods: [CAPPluginMethod] = [
|
||
|
|
CAPPluginMethod(name: "setSpeaker", returnType: CAPPluginReturnPromise)
|
||
|
|
]
|
||
|
|
|
||
|
|
override public func load() {
|
||
|
|
// Default calls to the loudspeaker when the plugin initialises (iOS uses the quiet earpiece otherwise).
|
||
|
|
let session = AVAudioSession.sharedInstance()
|
||
|
|
try? session.setCategory(.playAndRecord, mode: .voiceChat, options: [.defaultToSpeaker, .allowBluetooth, .allowBluetoothA2DP])
|
||
|
|
try? session.setActive(true)
|
||
|
|
}
|
||
|
|
|
||
|
|
@objc func setSpeaker(_ call: CAPPluginCall) {
|
||
|
|
let on = call.getBool("on") ?? true
|
||
|
|
let session = AVAudioSession.sharedInstance()
|
||
|
|
do {
|
||
|
|
try session.setCategory(.playAndRecord, mode: .voiceChat, options: [.allowBluetooth, .allowBluetoothA2DP])
|
||
|
|
try session.setActive(true)
|
||
|
|
try session.overrideOutputAudioPort(on ? .speaker : .none)
|
||
|
|
call.resolve(["route": on ? "speaker" : "earpiece"])
|
||
|
|
} catch {
|
||
|
|
call.reject(error.localizedDescription)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|