长文本在说话中间暂停的语音合成问题

Ser*_*ara 1 javascript text-to-speech

再会。

我的语音合成在讲长文本时出现不一致的问题。

我正在尝试用英语和普通话进行文字转语音。当我指定 utterance.lang = 'en-US'; 我发现我的英文文章会一直读到读完。但是,当我使用 utterance.lang = 'zh-CN'; 我的英语和普通话文本只能读到 30 个单词。不知道是编码有问题还是什么。

文章:

E. 环果香

Enterolobium cyclocarpum,通常被称为 guanacaste、caro caro 或象耳树,是豌豆科中的一种开花树种。豆科植物,原产于美洲热带地区,从墨西哥中部南部到巴西北部(罗赖马)和委内瑞拉。它以其巨大的比例、广阔的、通常是球形的冠和形状奇特的种子荚而闻名。这种树的数量非常丰富,尤其是在哥斯达黎加的瓜纳卡斯特省,因其在强烈阳光下提供的阴凉处而备受推崇,再加上其巨大,使其成为广受认可的物种。它是哥斯达黎加的国树。

onload = function() {
    if ('speechSynthesis' in window) with(speechSynthesis) {

        var playEle = document.querySelector('#play');
        var pauseEle = document.querySelector('#pause');
        var stopEle = document.querySelector('#stop');
        var flag = false;

        playEle.addEventListener('click', onClickPlay);
        pauseEle.addEventListener('click', onClickPause);
        stopEle.addEventListener('click', onClickStop);

        function onClickPlay() {
            if(!flag){
                flag = true;
                utterance = new SpeechSynthesisUtterance(document.querySelector('article').textContent);
                utterance.lang = 'zh-CN';
                utterance.onend = function(){
                    flag = false; playEle.className = pauseEle.className = ''; stopEle.className = 'stopped';
                };
                playEle.className = 'played';
                stopEle.className = '';
                speak(utterance);
            }
             if (paused) { /* unpause/resume narration */
                playEle.className = 'played';
                pauseEle.className = '';
                resume();
            } 
        }

        function onClickPause() {
            if(speaking && !paused){ /* pause narration */
                pauseEle.className = 'paused';
                playEle.className = '';
                pause();
            }
        }

        function onClickStop() {
            if(speaking){ /* stop narration */
                /* for safari */
                stopEle.className = 'stopped';
                playEle.className = pauseEle.className = '';
                flag = false;
                cancel();

            }
        }
    }

    else { /* speech synthesis not supported */
        msg = document.createElement('h5');
        msg.textContent = "Detected no support for Speech Synthesis";
        msg.style.textAlign = 'center';
        msg.style.backgroundColor = 'red';
        msg.style.color = 'white';
        msg.style.marginTop = msg.style.marginBottom = 0;
        document.body.insertBefore(msg, document.querySelector('div'));
    }
}
Run Code Online (Sandbox Code Playgroud)

小智 8

我最近偶然发现了一个问题,即语音在持续 14(?)秒后被切断。这会导致合成陷入“说话”模式,永远不会将其标记为已完成,因此永远无法真正检查它何时完成说话。这也会导致所有语音合成选项被阻止,直到您重新启动浏览器。

这个错误似乎只在您使用承诺选项来获取语音和语言时才会发生。如果您不需要选择选项而只需预先设置它们,那么它似乎应该正常工作(至少对我来说)。

弗雷泽的解决方案对我不起作用,直到我还在恢复之前添加了一个暂停,使其停止很短的时间然后继续。这消除了“最长 14 秒”的错误。

添加这个小调整后,Frazer 的代码将如下所示:

let r = setInterval(() => {
  console.log(speechSynthesis.speaking);
  if (!speechSynthesis.speaking) {
    clearInterval(r);
  } else {
    speechSynthesis.pause();
    speechSynthesis.resume();
  }
}, 14000);
Run Code Online (Sandbox Code Playgroud)


Fra*_*zer 5

这是一个已知的错误。该解决方法是发出简历每14秒。

对于您的代码,这意味着在 'speak(utterance)' 之后添加以下内容:

let r = setInterval(() => {
  console.log(speechSynthesis.speaking);
  if (!speechSynthesis.speaking) {
    clearInterval(r);
  } else {
    speechSynthesis.resume();
  }
}, 14000);
Run Code Online (Sandbox Code Playgroud)

  • 更新:这不再有效。您必须在“恢复”之前首先发出“暂停”命令。 (4认同)