文字转语音 H5API方案(Hook,拿去就能用)+接口方案+浏览器阻止自动播放的隐藏问题

H5的API:

功能: 支持间隔特定时间播放(这里的坑是,无法预判播放语音要多久,所以间隔特定时间播放功能,不能定时调用speak,需要根据utterance的状态,在结束时调用speak)

开发文档:developer.mozilla.org/en-US/docs/...

useTextToVoice:

js 复制代码
import { message } from 'ant-design-vue';

const useTextToVoice = (gap = 1000, voiceType = 0) => {
  const synth = window.speechSynthesis;
  const voices = synth.getVoices();
  const utteranceQueue = []; // 待播报文本队列

  const checkVoiceSupport = () => {
    const isSupport = 'speechSynthesis' in window;
    if (!isSupport) {
      message.warn('您的浏览器不支持文本转语音功能。请更换浏览器或者升级浏览器版本。');
    }
    return isSupport;
  };

  const speak = (text) => {
    if (!checkVoiceSupport()) return;

    const utterance = new SpeechSynthesisUtterance(text);
    utterance.voice = voices[voiceType];

    // 如果有待播报的文本或者正在播报中,将文本添加到队列中
    if (synth.pending || synth.speaking) {
      utteranceQueue.push(text);
    } else {
      synth.speak(utterance);
    }

    utterance.onend = () => {
      console.log('speak end');
      // 检查队列中是否还有待播报的文本
      if (utteranceQueue.length > 0) {
        const nextText = utteranceQueue.shift();

        setTimeout(() => speak(nextText), gap);
      }
    };
  };

  return { speak };
};

export default useTextToVoice;

使用

scss 复制代码
const { speak } = useTextToVoice(2000);
直接调用speak()传入文本就好啦~

接口

还有另一种方式,使用接口,觉得要构建audio标签有点麻烦,没采用

api.oick.cn/txt/apiz.ph...

隐藏问题

这里有个坑,就是浏览器出于避免打扰用户,做了安全机制限制了需要用户与界面有一定交互才可以自动播放,目前可以实现自动播放的方案:

  1. 播放次数多了,浏览器安全值提高则会自动播放。
  2. 打开浏览器的安全设置,解除当前网站的播放限制(需要能拿到用户设备,手动设置,最后我们采用了这个)。
  3. 模仿爱奇艺等视频网站,提供静音按钮让用户解除静音。
  4. iframe(没试过,因为我们的需求是动态的播放内容,用文字转语音方案,没有现成的音频文件,所以没用到audio标签)

自动点击是不生效的,自动点击需要等手动点击之后才生效。不生效的原因是 浏览器内置了isTrusted变量,这个变量只有等用户操作后才会变成true,自动点击事件才会生效。 也是出于安全考虑。

MDN文档如下:

Event接口的isTrusted是一个Boolean类型的只读属性.当事件由用户操作生成时为true,由脚本创建或修改,或通过调用EventTarget.dispatchEvent生成,为false

相关推荐
卸任12 小时前
Vibe coding工具使用心得
前端·ai编程
brien913 小时前
为什么模型标称 1M,Google Antigravity 聊到 256K 却突然失忆?我们给它做了个原生行内监控圆环
前端
修炼的dance13 小时前
录屏关键帧间隔多少合适?六档实测,2秒到10秒小了75.6%
前端
Lank_M13 小时前
关键帧从1秒拉到10秒,录屏小87.3%,摄像头小10.8%
前端
补码缩写13 小时前
用 ffprobe 拆录屏,八成字节在 29 个关键帧上
前端
百思不得小李13 小时前
一个复杂的动态表单是如何实现的
前端·设计模式
陈随易13 小时前
Cmder 停更 17 个月,2.0 支持 Windows Terminal
前端·后端·程序员
风骏时光牛马14 小时前
前沿视界
前端
kyriewen14 小时前
我扫了 814 个依赖,97 个还敢要 Node 10
前端·javascript·程序员
陈随易14 小时前
3000 万人在用的翻译插件,重写一遍就是一门生意
前端·后端·程序员