首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AVAudioSession从未停止过

AVAudioSession从未停止过
EN

Stack Overflow用户
提问于 2017-04-12 23:14:25
回答 3查看 3.7K关注 0票数 4

我正在尝试将我的AVAudioSession设置为非活动状态以恢复到正常状态。

我的话语函数:

代码语言:javascript
复制
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仍然是活动的。我试过很多方法,但都不管用。

EN

回答 3

Stack Overflow用户

发布于 2017-04-25 01:03:36

您不能停止或停用AudioSession,您的应用程序会在启动时获取它。Documentation

音频会话是应用程序和iOS之间的中介,用于配置应用程序的音频行为。在启动时,您的应用程序会自动为提供一个单独的音频会话。

因此,方法-setActive:不会使您的AudioSession“活动”,它只是将其类别和模式配置付诸实施。为了回到“正常状态”,你可以设置default settings或者直接调用setActive(false, with:.notifyOthersOnDeactivation),这就足够了。

票数 1
EN

Stack Overflow用户

发布于 2017-04-25 16:25:22

来自documentation of AVAudioSession的一部分

讨论

如果另一个活动音频会话的优先级高于您的音频会话(例如,电话呼叫),并且两个音频会话都不允许混合,则激活音频会话的尝试将失败。如果任何关联的音频对象(如队列、转换器、播放器或录音机)当前正在运行,则停用您的会话将失败。

我的猜测是,未能停用会话是因为您的queue正在运行的进程,正如我在文档引用中突出显示的那样。

也许您应该使停用过程同步而不是异步,或者确保您的queue下所有正在运行的操作都已被处理。

试一试:

代码语言:javascript
复制
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
EN

Stack Overflow用户

发布于 2017-04-21 09:56:36

我建议使用AvAudioPlayer。它们有非常简单的启动和停止命令。

首先将音频播放器声明为变量

代码语言:javascript
复制
var SoundEffect: AVAudioPlayer!

然后选择您需要的文件

代码语言:javascript
复制
    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()

并停止音频播放器

代码语言:javascript
复制
if SoundEffect != nil {
            SoundEffect.stop()
            SoundEffect = nil
        }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43373486

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档