Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

语音可以考虑微软的 web speech api #36

Open
Nezuko-zZ opened this issue Nov 24, 2024 · 1 comment
Open

语音可以考虑微软的 web speech api #36

Nezuko-zZ opened this issue Nov 24, 2024 · 1 comment

Comments

@Nezuko-zZ
Copy link

import config from '../config';
// 移除不再需要的翻译相关函数
// import { currentTranslateToCode, getTranslateTTSUrl, translate } from './translation';

// 创建音频元素
const $audio = document.createElement('audio');
const $source = document.createElement('source');
$audio.volume = config.voiceVolume; // 设置音量
$audio.playbackRate = config.voiceSpeed; // 设置语速
$source.setAttribute('type', 'audio/mpeg'); // 使用更通用的 mpeg 类型
$source.setAttribute('src', '');
$audio.appendChild($source);
document?.body.appendChild($audio); // 将音频元素添加到页面

// 使用浏览器内置的语音合成 API
const synth = window.speechSynthesis;

// 语音播报队列
let utteranceQueue: SpeechSynthesisUtterance[] = [];
// 是否正在播报语音
let isSpeaking = false;

// 语音播报函数
async function speak(uname: string, text: string) {
  const fullText = `${uname}${text}`; // 组合用户名和文本

  const utterance = new SpeechSynthesisUtterance(fullText); // 创建语音播报对象

  // 配置语音参数
  utterance.lang = config.voiceTranslateTo || 'zh-CN'; // 设置语言,默认为中文
  utterance.volume = config.voiceVolume; // 设置音量 (0-1)
  utterance.rate = config.voiceSpeed; // 设置语速 (0.1-10)


  // 将语音播报对象添加到队列
  utteranceQueue.push(utterance);

  // 如果当前没有语音播报,则开始处理队列
  if (!isSpeaking) {
    processQueue();
  }
}

// 处理语音播报队列
async function processQueue() {
  isSpeaking = true; // 设置正在播报语音的标志

  while (utteranceQueue.length > 0) {
    const currentUtterance = utteranceQueue.shift()!; // 获取队列中的第一个语音播报对象
    // 使用 Promise 等待语音播报完成
    await new Promise<void>(resolve => {
      currentUtterance.onend = () => { // 语音播报结束时 resolve Promise
        resolve();
      };
      synth.speak(currentUtterance); // 开始播报语音
    });
  }

  isSpeaking = false; // 清除正在播报语音的标志
}

// 对外暴露的语音控制对象
const voice = {
  push: speak, // 添加语音播报任务到队列
  resetPush: (uname: string, text: string) => { // 重置队列并添加新任务
    voice.reset();
    voice.push(uname, text);
  },
  reset: () => { // 重置语音播报队列
    synth.cancel(); // 取消所有正在进行的语音播报
    utteranceQueue = [];
    isSpeaking = false;
  },
  updateVolume: (volume: number) => { // 更新音量
    config.voiceVolume = volume; // 更新配置中的音量
    //  根据需要更新当前正在播放 utterance 的音量
  },
  updatePlaybackRate: (rate: number) => { // 更新语速
    config.voiceSpeed = rate; // 更新配置中的语速
    //  根据需要更新当前正在播放 utterance 的语速
  }
};

export default voice;
@Nezuko-zZ
Copy link
Author

electron内置的浏览器内核对web speech支持的比较少,中文只有几个读起来比较生硬的,没有在edge浏览器上那么多流畅自然的语音这点有点遗憾。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant