我正在尝试将我的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 {}
}
}
}
}我的方法被正确调用,但是当utterance完成时,我的audioSession仍然是活动的。我试过很多方法,但都不管用。
发布于 2017-04-25 01:03:36
您不能停止或停用AudioSession,您的应用程序会在启动时获取它。Documentation
音频会话是应用程序和iOS之间的中介,用于配置应用程序的音频行为。在启动时,您的应用程序会自动为提供一个单独的音频会话。
因此,方法-setActive:不会使您的AudioSession“活动”,它只是将其类别和模式配置付诸实施。为了回到“正常状态”,你可以设置default settings或者直接调用setActive(false, with:.notifyOthersOnDeactivation),这就足够了。
发布于 2017-04-25 16:25:22
来自documentation of AVAudioSession的一部分
讨论
如果另一个活动音频会话的优先级高于您的音频会话(例如,电话呼叫),并且两个音频会话都不允许混合,则激活音频会话的尝试将失败。如果任何关联的音频对象(如队列、转换器、播放器或录音机)当前正在运行,则停用您的会话将失败。
我的猜测是,未能停用会话是因为您的queue正在运行的进程,正如我在文档引用中突出显示的那样。
也许您应该使停用过程同步而不是异步,或者确保您的queue下所有正在运行的操作都已被处理。
试一试:
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 {}
}
}
}发布于 2017-04-21 09:56:36
我建议使用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
}https://stackoverflow.com/questions/43373486
复制相似问题