14

我发现,语音识别 API在我的 Android 上重复了结果短语(并且在桌面上不重复)。

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

在此处输入图像描述

第二个是

在此处输入图像描述

如您所见,在第二次返回中,短语重复,每个副本都标记为final,第二个是 Beyond 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/

4

2 回答 2

4

Chrome mobile 上提供的关于该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;

}

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

于 2017-04-17T19:43:04.877 回答
2

尝试这个:

recognition.continuous = false;
recognition.interimResults = false;
recognition.maxAlternatives = 1;

JSFiddle:https ://jsfiddle.net/envwao8o/4/

于 2017-01-26T21:46:02.527 回答