在 chrome android 上使用 speechSynthesis.resume() 恢复暂停的演讲不起作用

Resuming a paused speech using speechSynthesis.resume() on chrome android doesn't work

使用浏览器 api speechSynthesis.resume() 我正在尝试恢复 android chrome

上暂停的演讲

我已经在 chrome 桌面版 78.0.3904.97 和 mac os mojave 上测试了下面的代码,它可以在演讲暂停后毫无问题地恢复演讲。但是同样的代码无法在androidchrome版本77.x和78.x

上恢复发言

重现步骤

  1. 运行下面的代码
  2. 按播放键收听演讲
  3. 中途暂停演讲
  4. 按简历
  5. 语音在桌面 chrome 上恢复,但在 android chrome
  6. 上未恢复

这是 chrome 中的错误吗?

<!DOCTYPE html>
<html>
  <head>
    <title>Parcel Sandbox</title>
    <meta charset="UTF-8" />
  </head>

  <body>
    <button id="play">Play</button>
    <button id="pause">Pause</button>
    <button id="resume">Resume</button>

    <div id="data"></div>

    <script>
      const play = document.getElementById("play");
      const pause = document.getElementById("pause");
      const resume = document.getElementById("resume");

      play.addEventListener("click", function() {
        document.getElementById("data").innerText = "play";
        var utterance = new SpeechSynthesisUtterance(
          "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15"
        );

        utterance.lang = "en-US";
        speechSynthesis.cancel();
        speechSynthesis.speak(utterance);
      });

      pause.addEventListener("click", function() {
        document.getElementById("data").innerText = "pause";
        speechSynthesis.pause();
      });
      
      resume.addEventListener("click", function() {
        document.getElementById("data").innerText = "resume";
        speechSynthesis.resume();
      });
    </script>
  </body>
</html>

是的,这是一个错误:https://github.com/mdn/browser-compat-data/issues/4500

状态已修复,因此它可能会在测试版或开发版或 Chronium 中运行。

就目前而言,当您暂停 speechSynthesis 时,其暂停状态不会更新,并且所有进一步的发言命令都将放入待处理队列,给人的印象是 speechSynthesis 已完全停止工作。您的代码在每个 'speak' 命令之前使用 'cancel' 行避免了这种情况。

顺便说一句,你想让这段代码在 Firefox 中工作吗?

编辑:希望您不要介意,我稍微更改了您的代码并添加了一个 'status' 按钮来演示此错误。状态按钮显示发言、暂停和待定状态。

点击'Play'然后'Status':发言为真,暂停为假,待定为假。然后单击 'Pause' 和 'Status'。在Windows speaking 是 true,paused 是 true,pending 是 false。但是在 Andriod 中,状态分别为 true、false、false。所以 resume 不能做任何事情,因为 paused 是错误的。

此后,如果您再次单击 'Play',该话语就会进入待处理队列,因此状态为真、假、真。

<!DOCTYPE html>
<html>
  <head>
    <title>Parcel Sandbox</title>
    <meta charset="UTF-8" />
  </head>

  <body>
    <button id="play">Play</button>
    <button id="pause">Pause</button>
    <button id="resume">Resume</button>
    <button id="status">Status</button>
    <button id="ssCancel">Cancel</button>

    <div id="data"></div>

    <script>
      const play = document.getElementById("play");
      const pause = document.getElementById("pause");
      const resume = document.getElementById("resume");
      const status = document.getElementById("status");
      const ssCancel = document.getElementById("ssCancel");
      const data = document.getElementById("data");

      play.addEventListener("click", () => {
        data.innerText = "play";
        var utterance = new SpeechSynthesisUtterance(
          "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15"
        );
        utterance.lang = "en-US";
        //speechSynthesis.cancel();
        speechSynthesis.speak(utterance);
      });

      pause.addEventListener("click", () => {
        data.innerText = 'pause';
        speechSynthesis.pause();
      });
      
      resume.addEventListener("click", () => {
        data.innerText = "resume";
        speechSynthesis.resume();
      });
      
      status.addEventListener('click', () => {
        data.innerText = `
          Speaking: ${speechSynthesis.speaking},
          Paused: ${speechSynthesis.paused},
          Pending: ${speechSynthesis.pending}.`;
      });
      
      ssCancel.addEventListener('click', () => {
          speechSynthesis.cancel();
      });
    </script>
  </body>
</html>

(为了更好地显示错误,我注释掉了您的取消行并添加了一个单独的取消按钮)

其实问题是有些浏览器不会自动更新状态,Mozilla官网说明这是一个实验性的功能,并不是所有的浏览器都支持,建议我们也看看这个支持到什么程度,对于chromiun及其衍生物,声明只是暂停,对此的简单解决方案是:

var synth = window.speechSynthesis;
    var voice = new SpeechSynthesisUtterance('hello');
    var voices = speechSynthesis.getVoices();
   //Put this on the play button
    synth.resume();
    synth.speak(voice);

所以,如果有什么要恢复的,它会从它停止的地方returns开始,否则,它会开始,为此不需要 if (),resume () 函数本身会启动语句,但如果出现故障,speak 函数会执行其工作,不会生成错误。