Androidでreact-native-voiceを使った音声認識エラーを解決する方法

課題

React Nativeでreact-native-voiceを使ってAndroidの音声認識を実装していると、1秒間無音になると自動的に終了してしまい、実運用に適しませんでした。iOSではこの問題は発生しませんが、Androidでの利用には大きな障害がありました。

解決策

この問題を解決するためには、音声認識の無音タイムアウトを調整するオプションを渡す必要があります。以下のコードのように、EXTRA_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS と EXTRA_SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS を設定することで、無音のタイムアウト時間を延長できます。

javascript
Voice.start("en-US", {
    EXTRA_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS: 5000,
    EXTRA_SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS: 5000,
})

オプションの意味
・EXTRA_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS: 音声入力が完全に停止したと判断されるまでの時間(ミリ秒)。この設定によって、無音が続いた際に終了するまでの猶予を与えます。

・EXTRA_SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS: 音声認識が一時的に停止したと判断されるまでの時間(ミリ秒)。これにより、ユーザーが考えているときなど、短い無音時間を許容できます。

続いてパッチを当てます。

上記の設定で一時的に無音が許容されるようになりますが、次に null エラーが発生する問題があります。このエラーを解決するために、@react-native-voice/voice パッケージにパッチを当てる必要があります。以下のパッチを適用することで、null の結果が発生した際のエラー処理を追加できます。

react-native-voice+voice+3.2.4.patch
diff --git a/node_modules/@react-native-voice/voice/android/src/main/java/com/wenkesj/voice/VoiceModule.java b/node_modules/@react-native-voice/voice/android/src/main/java/com/wenkesj/voice/VoiceModule.java
index f22833e..01d296e 100644
--- a/node_modules/@react-native-voice/voice/android/src/main/java/com/wenkesj/voice/VoiceModule.java
+++ b/node_modules/@react-native-voice/voice/android/src/main/java/com/wenkesj/voice/VoiceModule.java
@@ -342,11 +342,20 @@ public class VoiceModule extends ReactContextBaseJavaModule implements Recogniti
 
   @Override
   public void onResults(Bundle results) {
+    if (results == null) {
+        Log.d("ASR", "No results bundle received");
+        return;
+    }
+
     WritableArray arr = Arguments.createArray();
 
     ArrayList<String> matches = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
-    for (String result : matches) {
-      arr.pushString(result);
+    if (matches != null) {
+        for (String result : matches) {
+            arr.pushString(result);
+        }
+    } else {
+        Log.d("ASR", "No speech results received");
     }
 
     WritableMap event = Arguments.createMap();

パッチを適用した後

パッチを適用したら、ネイティブモジュールの変更を反映するために、再度 EAS Build を実行する必要があります。これは、React Nativeのネイティブモジュールに変更が加わった際には必須のステップです。

結果

上記の手順をすべて実行することで、Androidでの音声認識機能が無音の時間を考慮して動作するようになり、無音で終了してしまう問題が解決されます。また、null エラーも回避できるため、実運用に耐える環境を構築できます。

これで、AndroidでもiOSと同様に、react-native-voice を使った音声認識機能が利用できるようになります。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です