在播放Podcast时,iOS 11 setPreferredInput到HFP不起作用

时间:2017-10-10 04:49:45

标签: ios audio bluetooth podcast hpf

我的应用程序允许使用HFP(免提协议),因为它的#34;语音"提示(如导航应用程序)。

自从iOS 9.x开始,TextToSpeech或AVAudioPlayer之前的设置音频的功能如下所示。 我没有经常测试它是否经常运行PodCast所以我不确定什么时候会发生故障。如果音乐从电话流式传输到蓝牙A2DP或音乐正在汽车的FM收音机上播放(即它将中断收音机,提示和恢复收音机),则下面的功能非常有效。但如果我正在播放PodCast,它将无法运行。 PodCast暂停并出现提示静音,然后恢复PodCast。

我最近检查了Waze,Google地图和Apple地图(所有这些也都提供此HFP选项)。

Waze被打破了(但我不会经常对PodCast进行测试)。 谷歌地图仍然完美无缺。 Apple Maps很奇怪。流式传输时,HFP的选项显示为灰色。但是当它试图暂停和播放时它也会失败。

但同样,谷歌地图可以运作,所以可以做到。

当我使用HFP路由调用setPreferredInput时,如果PodCast正在流式传输,则不会调用我的路由更改处理程序(也如下所示)。如果音乐是Streaming我的路线更改处理程序被调用,而我的应用程序中的音频正确地来自HFP。

背景或前景并不重要。

任何有待解决的建议都将不胜感激。

func setupSound(_ activate: Bool)
{
    if !Settings.sharedInstance.soundOn && !Settings.sharedInstance.voiceOn
    {
        return
    }

    var avopts:AVAudioSessionCategoryOptions = [
        .mixWithOthers,
        .duckOthers,
        .interruptSpokenAudioAndMixWithOthers,
        .allowBluetooth
    ]

    if #available(iOS 10.0, *)
    {
        avopts.insert(AVAudioSessionCategoryOptions.allowBluetoothA2DP)
        avopts.insert(AVAudioSessionCategoryOptions.allowAirPlay)
    }

    var HFP = false

    if Settings.sharedInstance.HFPOn && callCenter.currentCalls == nil
    {
        do
        {
            if #available(iOS 10.0, *)
            {
                try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayAndRecord, mode: AVAudioSessionModeSpokenAudio, options: avopts)
            }
            else
            {
                try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayAndRecord, with: avopts)
                try AVAudioSession.sharedInstance().setMode(AVAudioSessionModeSpokenAudio)
            }
        }
        catch
        {
            Settings.vprint("Failed Setup HFP Bluetooth Audio, ", error.localizedDescription)
        }

        if let inputs = AVAudioSession.sharedInstance().availableInputs
        {
            for route in inputs
            {
                if route.portType == AVAudioSessionPortBluetoothHFP
                {
                    HFP = true

                    do
                    {
                        try AVAudioSession.sharedInstance().setPreferredInput(route)
                        HFP = true
                        break
                    }
                    catch
                    {
                        Settings.vprint("Failed Set Route HFP Bluetooth Audio, ", error.localizedDescription)
                    }
                }
            }
        }
    }

    lastHFPStatus = HFP

    if !HFP
    {

        var avopts:AVAudioSessionCategoryOptions = [
            .mixWithOthers
        ]

        if Settings.sharedInstance.duckingSoundOn
        {
            avopts.insert(.duckOthers)
            avopts.insert(.interruptSpokenAudioAndMixWithOthers)
        }

        if Settings.sharedInstance.speakerOnlyOn
        {
            avopts.insert(.defaultToSpeaker)
            do
            {
                try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayAndRecord, with: avopts)
            }
            catch
            {
                Settings.vprint("Failed setCategory, ", error.localizedDescription)
            }
        }
        else
        {
            do
            {
                try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, with: avopts)
            }
            catch
            {
                Settings.vprint("Failed setCategory, ", error.localizedDescription)
            }
        }
    }

    do
    {
        try AVAudioSession.sharedInstance().setActive(activate, with: .notifyOthersOnDeactivation)
        if ((Settings.sharedInstance.debugMask & 2) != 0)
        {
            Settings.vprint(activate)
        }
    }
    catch
    {
        Settings.vprint("Could not setActive, ", error.localizedDescription)
    }
}

@objc func handleRouteChange(notification: Notification)
{
    Settings.vprint(notification)

    let currentRoute = AVAudioSession.sharedInstance().currentRoute

    for route in currentRoute.outputs
    {
        Settings.vprint("Change Output: ", route.portName)
    }

    for route in currentRoute.inputs
    {
        Settings.vprint("Change Input: ", route.portName)
    }
}

0 个答案:

没有答案