必填条件为假:IsFormatSampleRateAndChannelCountValid(hwFormat)

时间:2018-08-17 20:00:54

标签: ios xamarin.ios

我们的应用程序正在使用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);
        }
    }

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

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