すでに一見似たような質問がありますが、コードを検索して実験した後、私は明確な答えを見つけることができませんでした。私が見つけることができる最も近いものは、4年前に「既知のバグ」を暗示していたthis answerでしたが、それに対処する方法を詳しく説明していません。電話がかかっていない状態でAVAudioPlayerを再開する
AVAudioPlayerでオーディオファイルを再生し、AVAudioSessionDelegate
のメソッドbeginInterruption
とendInterruption
をリッスンしているaudioPlayerクラスがあります。 endInterruption
は保証されていないので、beginInterruption
にブール値を格納し、applicationDidBecomeActive
にオーディオ再生を再開するように処理します。
電話機が通話を受信したときに、ユーザーがそれを拒否したり、ボイスメールに移動させたりすると、これはすべて正常に動作します。私のアプリがアクティブ状態に戻るとすぐに、オーディオ再生が再開されます。私は奇妙な振る舞いを得ているところ
がここにあります:彼らはハングアップしたらユーザーが答え呼び出した場合は、すべては期待どおりに動作するようだが、何の音はヘッドフォンやスピーカーのいずれかを介して出てきません。
オーディオは技術的にはのを再生していることを確認できます。ボリュームとcurrentTimeを毎秒印刷しても音は出ません。
私が20-40秒間待つと、突然音声が途切れて、静かに背景で再生しているかのように聞こえます。
よりデバッグした後、私はAVAudioSession.sharedInstance().secondaryAudioShouldBeSilencedHint
が突然false
に変更し、オーディオ再生をさせる前に、沈黙のこれらの20〜40秒間true
ままであることに気づきました。
私はこの変更を検出できるかどうかを確認するためにAVAudioSessionSilenceSecondaryAudioHintNotification
に加入したが、それが呼び出されることは決してありません、場合でもtrue
からfalse
へ.secondaryAudioShouldBeSilencedHint
変更。
設定AVAudioSession.sharedInstance().setActive(true)
をオーディオの再生を再開する方法で試してみましたが、動作は変更されませんでした。
最後に、applicationDidBecomeActive
の後に10秒間レジュームを遅らせるようにタイマーを設定しようとしましたが、動作は変更されませんでした。
なぜ、電話が私のアプリに戻ってオーディオセッションのコントロールを放棄していないように見えるのですか?
ありがとうございました!
コード:init()
で
AVAudioSessionセットアップ:
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(self.handleAudioHintChange), name: AVAudioSessionSilenceSecondaryAudioHintNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(self.handleAudioInterruption), name: AVAudioSessionInterruptionNotification, object: nil)
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, withOptions: AVAudioSessionCategoryOptions.MixWithOthers)
print("AVAudioSession Category Playback OK")
do {
try AVAudioSession.sharedInstance().setActive(true, withOptions: .NotifyOthersOnDeactivation)
print("AVAudioSession is Active")
} catch let error as NSError {
print(error.localizedDescription)
}
} catch let error as NSError {
print(error.localizedDescription)
}
通知ハンドラ:
///////////////////////////////////
// This never gets called :(//////
func handleAudioHintChange(notification: NSNotification) {
print("audio hint changed")
}
///////////////////////////////////
func handleAudioInterruption(notification: NSNotification) {
if notification.name != AVAudioSessionInterruptionNotification || notification.userInfo == nil{
return
}
if let typeKey = notification.userInfo [AVAudioSessionInterruptionTypeKey] as? UInt,
let type = AVAudioSessionInterruptionType(rawValue: typeKey) {
switch type {
case .Began:
print("Audio Interruption Began")
NSUserDefaults.standardUserDefaults().setBool(true, forKey:"wasInterrupted")
case .Ended:
print("Audio Interuption Ended")
}
}
}
アプリの委任:
func applicationDidBecomeActive(application: UIApplication) {
if(NSUserDefaults.standardUserDefaults().boolForKey("wasInterrupted")) {
audioPlayer.resumeAudioFromInterruption()
}
}
再起動機能:
// This works great if the phone call is declined
func resumeAudioFromInterruption() {
NSUserDefaults.standardUserDefaults().removeObjectForKey("wasInterrupted")
do {
try AVAudioSession.sharedInstance().setActive(true)
print("AVAudioSession is Active")
} catch let error as NSError {
print(error.localizedDescription)
}
thisFunctionPlaysMyAudio()
}
ねえ、答えに感謝を。私はバグかもしれないと私は狂っているだけでなく、うれしいです。残念ながら、私は運がないまま遅延をも試みたと確信しています。今週もう一度チェックして、もう一度試してみて、それがどうなっているかを教えてください... –
これに関するアップデートはありますか? –
まだ、申し訳ありません。私はこれをもう一度見直すつもりですが、私たちが優先順位を決めることを決めた他のものがリスト上に上がっています。私は見てチャンスを得るとすぐにここでコメントします。 –