我正在尝试将AVAudioSession
设置为无效以恢复正常状态。
我的话语功能:
class SSpeech : NSObject, AVSpeechSynthesizerDelegate {
var group = DispatchGroup();
var queue = DispatchQueue(label: "co.xxxx.speech", attributes: [])
class var sharedInstance: SSpeech {
struct Static {
static var instance: SSpeech?
}
if !(Static.instance != nil) {
Static.instance = SSpeech()
}
return Static.instance!
}
required override init() {
super.init();
self.speechsynt.delegate = self;
}
deinit {
print("deinit SSpeech")
}
let audioSession = AVAudioSession.sharedInstance();
var speechsynt: AVSpeechSynthesizer = AVSpeechSynthesizer()
var queueTalks = SQueue<String>();
func pause() {
speechsynt.pauseSpeaking(at: .word)
}
func talk(_ sentence: String, languageCode code:String = SUtils.selectedLanguage.code, withEndPausing: Bool = false) {
if SUser.sharedInstance.currentUser.value!.speechOn != 1 {
return
}
queue.async{
self.queueTalks.enQueue(sentence)
do {
let category = AVAudioSessionCategoryPlayback;
var categoryOptions = AVAudioSessionCategoryOptions.duckOthers
if #available(iOS 9.0, *) {
categoryOptions.formUnion(AVAudioSessionCategoryOptions.interruptSpokenAudioAndMixWithOthers)
}
try self.audioSession.setCategory(category, with: categoryOptions)
try self.audioSession.setActive(true);
} catch _ {
return;
}
self.utteranceTalk(sentence, initSentence: false, speechsynt: self.speechsynt, languageCode:code, withEndPausing: withEndPausing)
do {
try self.audioSession.setCategory(AVAudioSessionCategoryPlayback, with: AVAudioSessionCategoryOptions.mixWithOthers)
} catch _ {
return;
}
}
}
func utteranceTalk(_ sentence: String, initSentence: Bool, speechsynt: AVSpeechSynthesizer, languageCode:String = "en-US", withEndPausing: Bool = false){
if SUser.sharedInstance.currentUser.value!.speechOn != 1 {
return
}
let nextSpeech:AVSpeechUtterance = AVSpeechUtterance(string: sentence)
nextSpeech.voice = AVSpeechSynthesisVoice(language: languageCode)
if !initSentence {
nextSpeech.rate = 0.4;
}
if(withEndPausing){
nextSpeech.postUtteranceDelay = 0.2;
}
speechsynt.speak(nextSpeech)
}
func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didFinish utterance:AVSpeechUtterance) {
print("Speaker has finished to talk")
queue.async {
do {
try self.audioSession.setActive(false, with: AVAudioSessionSetActiveOptions.notifyOthersOnDeactivation)
}
catch {}
}
}
}
}
我的方法被正确调用,但audioSession
完成后utterance
仍处于活动状态。我已经尝试了很多东西,但没有任何效果:(。
答案 0 :(得分:1)
来自documentation of AVAudioSession的部分:
<强>讨论强>
如果另一个活动音频会话的优先级高于您的优先级(for 例如,电话),音频会话都不允许混音, 尝试激活您的音频会话失败。 停用你的 如果任何相关的音频对象(如队列, 转换器,播放器或刻录机)目前正在运行。
我的猜测是,无法停用会话是queue
的正在运行的过程,正如我在文档引用中所强调的那样。
可能您应该停用进程同步而不是异步或确保queue
下的所有正在运行的操作都已处理< / em>的
尝试一下:
func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didFinish utterance:AVSpeechUtterance) {
print("Speaker has finished to talk")
queue.sync { // <---- `async` changed to `sync`
do {
try self.audioSession.setActive(false, with: AVAudioSessionSetActiveOptions.notifyOthersOnDeactivation)
}
catch {}
}
}
}
答案 1 :(得分:0)
我建议使用AvAudioPlayer。它们具有非常简单的启动和停止命令。
首先将音频播放器声明为变量
var SoundEffect: AVAudioPlayer!
然后选择您需要的文件
let path = Bundle.main.path(forResource: "Untitled2.wav", ofType:nil)!
let url = URL(fileURLWithPath: path)
let sound = try AVAudioPlayer(contentsOf: url)
SoundEffect = sound
sound.numberOfLoops = -1
sound.play()
并停止音频播放器
if SoundEffect != nil {
SoundEffect.stop()
SoundEffect = nil
}
答案 2 :(得分:0)
您无法停止或停用AudioSession
,您的应用会在启动时获取它。 Documentation:
音频会话是您的应用和iOS之间的中介,用于配置应用的音频行为。启动后,您的应用会自动单个音频会话。
因此方法-setActive:
不会使您的AudioSession
“处于活动状态”,只需将其类别和模式配置付诸实践。要恢复“正常状态”,您可以设置default settings或只调用setActive(false, with:.notifyOthersOnDeactivation)
,这就足够了。