I am using AVAudioSession, AVAudioEngine and SpeechAnalyzer to listen to commands, also when the phone is locked. In the same time, I can receive PushNotifications with pre-defined sound. However, the pre-defined sound is not played when the AVAudioEngine is running and the phone is locked. In the code below, I have made many experiments, all of them are "Receive Push Notification while the phone is locked", and I have the following results:
If audioEngine has started - I only see the alert, but no sound.
If I comment out audioEngine.start, all works as expected and I hear the apns sound on the speaker.
If I change the AVAudioSession category to 'record' I don't receive the push message at all!
I wonder if anyone has seen it. Here is my code:
private func doStartListening() async {
print("SpeechService: doStartListening called")
guard !audioEngine.isRunning else {
print("SpeechService: Audio engine already running")
return
}
do {
try configureAudioSession()
let recordingFormat = audioEngine.inputNode.outputFormat(forBus: 0)
audioEngine.inputNode.removeTap(onBus: 0)
guard let locale = await SpeechTranscriber.supportedLocale(equivalentTo: Locale(identifier: "en-US")) else {
print("English is not supported on this device")
return
}
let transcriber = SpeechTranscriber(locale: locale, preset: .transcription)
if let installationRequest = try await AssetInventory.assetInstallationRequest(supporting: [transcriber]) {
try await installationRequest.downloadAndInstall()
}
let (inputSequence, inputBuilder) = AsyncStream.makeStream(of: AnalyzerInput.self)
let audioFormat = await SpeechAnalyzer.bestAvailableAudioFormat(compatibleWith: [transcriber])
let analyzer = SpeechAnalyzer(modules: [transcriber])
// Initialize the modern SpeechAnalyzer
self.analyzer = analyzer
task = Task {
print("SpeechService: Starting analyzer results loop")
do {
for try await result in transcriber.results {
if Task.isCancelled { break }
self.handleAnalyzerResult(result)
}
} catch {
print("SpeechService: Analyzer error: \(error.localizedDescription)")
let nsError = error as NSError
if nsError.domain == "kAFAssistantErrorDomain" && nsError.code == 203 {
self.addLog(NSLocalizedString("error_siri_disabled", comment: ""))
Task { await self.stopListening() }
} else if self.isListening {
self.restartRecognition()
}
}
}
audioEngine.inputNode.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { [weak self]buffer, _ in
guard let audioFormat else { return }
do {
let converted = try self!.converter.convertBuffer(buffer, to: audioFormat)
inputBuilder.yield(AnalyzerInput(buffer: converted))
} catch {
print("Exception when converting audio")
}
}
audioEngine.prepare()
try audioEngine.start()
print("SpeechService: Audio engine started")
try await analyzer.start(inputSequence: inputSequence)
isListening = true
addLog(NSLocalizedString("waiting_wakeup", comment: ""))
} catch {
print("SpeechService: Error starting listening: \(error.localizedDescription)")
addLog("Error starting listening: \(error.localizedDescription)")
lastError = error.localizedDescription
isListening = false
}
}
private func configureAudioSession() throws {
let audioSession = AVAudioSession.sharedInstance()
try audioSession.setCategory(.playAndRecord, mode: .default, options: [.mixWithOthers, .defaultToSpeaker])
try audioSession.setActive(true, options: .notifyOthersOnDeactivation)
}
0
0
35