javascript - Android 上的语音识别 API 重复短语

标签 javascript android google-chrome speech-recognition webkitspeechrecognition

我发现,speech recognition API在我的 Android 上复制结果短语(在桌面上不复制)。

对于所说的每个短语,它会返回两个结果。第一个是

enter image description here

第二个是

enter image description here

如您所见,在第二次返回中,短语被复制,每个副本都标记为 final,第二个副本超出 resultIndex。在第一个返回中只有一个副本,它是 final 并且超出了 resultIndex

我只接受第二次返回,但问题是它发生在移动 Chrome 上,但不会发生在桌面 Chrome 上。桌面版 Chrome 仅返回第一个返回值。

因此,问题是:这是设计行为吗?那么如何为所有计算机区分单个最终短语呢?

或者这可能是一些类似声音回声的错误,那么问题是如何避免/检查回声?

更新

HTML 如下:

<input id="recbutton" type="button" value="Recognize">
<div id="output">

  <div>
    Initial text
  </div>

</div>

代码如下:

var recognition = null;
var recognitionStarted = false;
var printcount = 1;
var lastPhrase = null;

$(function() {
  attachRecognition();
});

$('#recbutton').click( function() {
    if( !recognitionStarted ) {
    recognition.start();
  }
  else {
    recognition.stop();
  }
});

function printOut(text) {
    var id = 'printcount' + printcount;
  printcount++;

    $('#output').append(
    "<div id='" + printcount + "'>" + text + "</div>"
  );

    $("#output").animate({ scrollTop: $("#output").prop('scrollHeight')});

  return printcount;

}


function attachRecognition() {

  if (!('webkitSpeechRecognition' in window)) {

    $('button').prop('disabled', true);

    recognition = null;

  } else {
    $('button').prop('disabled', false);

    recognition = new webkitSpeechRecognition();

    recognition.continuous = true;
    recognition.interimResults = true;
    recognition.lang = "en-US";

    recognition.onstart = function(event) {
      recognitionStarted = true;
      printOut("speech recognition started");
    };

    recognition.onend = function(event) {
            recognitionStarted = false;
            printOut("speech recognition stopped");
    };

    recognition.onresult = function(event) {

      var finalPhrase = '';
      var interimPhrase = '';
      var result;
      var printcount;

      for(var i=0; i<event.results.length; ++i) {
        result = event.results[i];
        if( result.isFinal ) {
          finalPhrase = finalPhrase.trim() + ' ' + result[0].transcript;
        }
        else {
          interimPhrase = interimPhrase.trim() + ' ' + result[0].transcript;
        }
      }

      if( !lastPhrase ) {
        printcount = printOut('');
        lastPhrase = $('#' + printcount);
      }

      lastPhrase.html(finalPhrase.trim() + ' ' + interimPhrase.trim());

      if( finalPhrase.trim() ) {
        lastPhrase = null;
      }


    };
  }
}

JsFiddle:https://jsfiddle.net/dimskraft/envwao8o/1/

最佳答案

在 Chrome 移动设备上提供的关于 result.isFinal 属性的结果似乎有一个错误,或者在任何情况下都与 Chrome 桌面设备上的结果不同。一种可能的解决方法是检查(第一个)备选方案的置信度属性:

onResultHandler(event) {
    let i = event.resultIndex;
    let result = event.results[i];
    let isFinal = result.isFinal && (result[0].confidence > 0);
}

看起来有时最终结果会发出两次(具有相同的 confidence 值),在这种情况下,您可能想要对其进行去抖动或只处理第一个事件,如下所示:

if (isFinal) {
    transcript = result[0].transcript;

    if(transcript == lastDebounceTranscript) {
        return;
    }

    lastDebounceTranscript = transcript;

}

其中 lastDebounceTranscript 是您在事件处理程序范围之外初始化的变量

关于javascript - Android 上的语音识别 API 重复短语,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35112561/

相关文章:

Android:在同一个SurfaceView中录制和播放视频

javascript - 如何在谷歌浏览器扩展中引用版本信息?

javascript - Owl Carousel 可以工作,但在 Rails 4 应用程序中表现得非常奇怪

javascript - 如何正确读取 Firebase 数据库?

javascript - 如何使用 lodash 递归地从 JSON 中删除空对象

javascript - 灯箱、CSS 和 JavaScript

android - 我们可以用 "requestCode"发送和获取 "registerForActivityResult"吗?

android - 如何取消 ksoap2 中的 soap 调用?

javascript - 为什么禁用表单提交会影响 min 和 max 属性?

html - 如何在 Chrome 中查看 mime 类型?它在 "document"选项卡下显示 "Network"