【问题标题】:required condition is false: IsFormatSampleRateAndChannelCountValid(hwFormat)所需条件为假:IsFormatSampleRateAndChannelCountValid(hwFormat)
【发布时间】:2019-01-24 21:29:53
【问题描述】:

我们的应用正在使用 SFSpeechRecognizer 来识别语音。它在我们端工作,但有时在客户端崩溃。我们在崩溃报告系统中收到以下错误:

Foundation.MonoTouchException: Objective-C exception thrown. Name: com.apple.coreaudio.avfaudio Reason: required condition is false: IsFormatSampleRateAndChannelCountValid(hwFormat)
...
AvAudioEngine.get_InputNode
MainViewController.ViewDidLoad
...

所以当我看到访问 AvAudioEngine 的 InputNode 属性时,ViewDidLoad 方法发生了崩溃。这是来自 ViewDidLoad 的代码:

public override void ViewDidLoad()
{
 ...
  speechRecognizer = new SFSpeechRecognizer(new NSLocale("en-US"));
  audioEngine = new AVAudioEngine();
  //simply access the engine's input node immediately after 
  instantiation so that the engine is configured for audio input TO FIX 
  IsFormatSampleRateAndChannelCountValid(format) crash                    
  //https://stackoverflow.com/questions/47903563/avaudioengine-inputnodes- 
  format-changes-when-playing-an-avaudioplayernode
  var input = audioEngine.InputNode;
...
}

这里还有开始/停止录制的方法:

    Timer speechTimer;
    private async void startDictating()
    {
        try
        {
            stopRecognizer = false;
            recognitionTask?.Cancel();
            recognitionTask = null;
            await Task.Delay(1000);//https://github.com/wenkesj/react- 
            native-voice/issues/50

            //==== Make volume louder =====//
            var audioSession = AVAudioSession.SharedInstance();
            error = 
    audioSession.SetCategory(AVAudioSessionCategory.PlayAndRecord);
            audioSession.SetMode(AVAudioSession.ModeDefault, out error);
            error = audioSession.SetActive(true, 
    AVAudioSessionSetActiveOptions.NotifyOthersOnDeactivation);

    audioSession.OverrideOutputAudioPort(AVAudioSessionPortOverride.Speaker, 
    out error);

            recognitionRequest = new SFSpeechAudioBufferRecognitionRequest
            {
                ShouldReportPartialResults = true
            };

            var inputNode = audioEngine.InputNode;
            if (inputNode == null)
            {
                StaticHolder.ReportCrash("startDictating: ", new 
      NullReferenceException("Audio engine has no input node"));
                return;
            }

            if (speechRecognizer != null)
                recognitionTask = 
    speechRecognizer.GetRecognitionTask(recognitionRequest,
                    (result, err) => InvokeOnMainThread(() =>
            {

                var isFinal = false;

                if (result != null)
                {
                    isFinal = result.Final;
                    voiceResult = result.BestTranscription.FormattedString;
                    lblVoiceRecogResult.Text = voiceResult;
                    if (PreferenceClass.VoiceInstantSearch)
                    {
                        if (!stopRecognizer)
                        {
                            if (speechTimer != null)
                            {
                                speechTimer.Stop();
                                speechTimer.Start();
                            }
                            if (speechTimer == null)
                            {
                                speechTimer = new Timer();
                                speechTimer.Interval = 3000;
                                speechTimer.Elapsed += (s, e) =>
                                {
                                    ((Timer)s).Stop();
                                    InvokeOnMainThread(() =>
                                    {

    SoundEngine.Instance.PlaySound(AudioFilesType.Multiple);
                                        stopDictating();
                                        btnRecordDone_Clicked(null);
                                    });

                                    return;
                                };
                                speechTimer.Start();
                            }
                        }
                    }
                }

                //if (err != null || isFinal)
                //{
                //    if (PreferenceClass.VoiceInstantSearch)
                //    {
                //        stopDictating();
                //        HandleSpeechToTextResult();
                //    }
                //}
            }));

           inputNode.RemoveTapOnBus(0);
    //https://stackoverflow.com/questions/41438219/terminating-app-due-to- 
    uncaught-app-crashes-while-using-speech-kit-ios
            /*
            var recordingFormat = new AVAudioFormat(sampleRate: 44100, 
    channels: 1);
            https://stackoverflow.com/questions/41805381/avaudioengine- 
    inputnode-installtap-crash-when-restarting-recording
            But it generated a crash again - 'required condition is false: 
    format.sampleRate == hwFormat.sampleRate'
            So used GetBusOutPutFormat
            */
            var recordingFormat = inputNode.GetBusOutputFormat(0);
            inputNode.InstallTapOnBus(
                        bus: 0,
                        bufferSize: 1024,
                        format: recordingFormat,
                        tapBlock: (buffer, when) => 
    recognitionRequest?.Append(buffer));
            audioEngine.Prepare();
            audioEngine.StartAndReturnError(out error);
        }
        catch (Exception ex)
        {
            StaticHolder.ReportCrash("try to get voice record task 
    exception:", ex);
        }
    }


    private void stopDictating()
    {
        try
        {
            stopRecognizer = true;
            audioEngine.Stop();
            audioEngine.InputNode.RemoveTapOnBus(0);                
            recognitionRequest?.EndAudio();
            recognitionTask = null;
            recognitionRequest = null;                
            if (voiceTapNotification != null) NSNotificationCenter.DefaultCenter.RemoveObserver(voiceTapNotification);
            if (searchTapNotification != null) NSNotificationCenter.DefaultCenter.RemoveObserver(searchTapNotification);
            viewRecording.Hidden = true;                
        }
        catch (Exception ex)
        {
            StaticHolder.ReportCrash("try to stop voice record exception:", ex);
        }
    }

【问题讨论】:

  • 崩溃发生时用户是否正在通话?
  • 我删除了 audioSession.SetCategor 和 audioSession.SetMode 行,崩溃就消失了。

标签: ios xamarin.ios


【解决方案1】:

请确保您已连接输入麦克风。您可能在未连接麦克风的 Mac mini 上运行您的应用程序。如果是 iPhone、iPad 或已连接输入麦克风的 mac。

【讨论】:

    【解决方案2】:

    我花了数周时间才弄清楚为什么我的 MacOS 应用会发生这种情况。您必须在项目设置中启用“音频输入”功能。

    【讨论】:

    • 如何添加音频输入功能? TARGETS->Sigin & Capability -> +capability 然后添加?
    猜你喜欢
    • 2019-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-01
    • 1970-01-01
    相关资源
    最近更新 更多