speakVoice.ts 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. // 定义 SpeakVoice 类并将其导出为默认导出
  2. export default class SpeakVoice {
  3. synth: SpeechSynthesis;
  4. instance: any;
  5. voices: { name: string }[];
  6. constructor() {
  7. this.synth = window.speechSynthesis; // 启用文本
  8. this.instance = new SpeechSynthesisUtterance();
  9. this.voices = [];
  10. this.initVoice();
  11. }
  12. // 初始化
  13. initVoice() {
  14. this.instance.volume = 1; // 声音音量:1,范围从0到1
  15. this.instance.rate = 3; // 设置语速:1,范围从0到100
  16. this.instance.lang = 'zh-CN'; // 使用的语言:中文
  17. this.instance.pitch = 0; // 表示说话的音高,数值,范围从0(最小)到2(最大)。默认值为1
  18. this.instance.voiceURI = 'Ting-Ting';
  19. // this.instance.voiceURI = 'Google 普通话(中国大陆)';
  20. }
  21. // 语音开始
  22. handleSpeak() {
  23. this.synth.speak(this.instance as SpeechSynthesisUtterance); // 播放
  24. }
  25. // 语音队列重播
  26. handleReply(text) {
  27. this.instance.text = text;
  28. this.handleCancel();
  29. this.handleSpeak();
  30. }
  31. // 语音队列删除 , 删除队列中所有的语音.如果正在播放,则直接停止
  32. handleCancel() {
  33. this.synth.cancel();
  34. }
  35. // 语音暂停, 暂停语音该次语音播放
  36. handleStop() {
  37. this.synth.pause();
  38. }
  39. // 恢复暂停的语音
  40. handleResume() {
  41. this.synth.resume();
  42. }
  43. // 声音切换
  44. setVoiceType(voiceName) {
  45. const voice = this.voices.find((voice) => voice.name === voiceName);
  46. if (voice) {
  47. this.instance.voice = voice;
  48. } else {
  49. console.warn('指定的语音未找到:', voiceName);
  50. }
  51. }
  52. // 获取可用的中文语音
  53. async getSpeechCnVoices() {
  54. try {
  55. const voices = await this.getSpeechVoices();
  56. const cnVoices = voices.filter((item) => item.lang.startsWith('zh-') && item.localService);
  57. if (cnVoices.length === 0) {
  58. throw new Error('没有可用的中文语音!');
  59. }
  60. this.voices = cnVoices;
  61. return cnVoices;
  62. } catch (error) {
  63. console.error(error);
  64. throw error;
  65. }
  66. }
  67. // 异步获取所有可用的语音
  68. async getSpeechVoices() {
  69. // 返回一个新的 Promise
  70. return new Promise((resolve) => {
  71. // 如果当前没有可用的语音,等待 onvoiceschanged 事件触发
  72. if (this.synth.getVoices().length === 0) {
  73. this.synth.onvoiceschanged = () => resolve(this.synth.getVoices());
  74. } else {
  75. // 如果已经有可用的语音,立即解析 Promise
  76. resolve(this.synth.getVoices());
  77. }
  78. });
  79. }
  80. }