speakVoice.ts 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  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.localService = true;
  18. this.instance.pitch = 0; // 表示说话的音高,数值,范围从0(最小)到2(最大)。默认值为1
  19. this.instance.voiceURI = 'Ting-Ting';
  20. // this.instance.voiceURI = 'Google 普通话(中国大陆)';
  21. }
  22. // 语音开始
  23. handleSpeak() {
  24. this.synth.speak(this.instance as SpeechSynthesisUtterance); // 播放
  25. }
  26. // 语音队列重播
  27. handleReply(text) {
  28. this.instance.text = text;
  29. this.handleCancel();
  30. this.handleSpeak();
  31. }
  32. // 语音队列删除 , 删除队列中所有的语音.如果正在播放,则直接停止
  33. handleCancel() {
  34. this.synth.cancel();
  35. }
  36. // 语音暂停, 暂停语音该次语音播放
  37. handleStop() {
  38. this.synth.pause();
  39. }
  40. // 恢复暂停的语音
  41. handleResume() {
  42. this.synth.resume();
  43. }
  44. // 声音切换
  45. setVoiceType(voiceName) {
  46. const voice = this.voices.find((voice) => voice.name === voiceName);
  47. if (voice) {
  48. this.instance.voice = voice;
  49. } else {
  50. console.warn('指定的语音未找到:', voiceName);
  51. }
  52. }
  53. // 获取可用的中文语音
  54. async getSpeechCnVoices() {
  55. try {
  56. const voices = await this.getSpeechVoices();
  57. const cnVoices = voices.filter((item) => item.lang.startsWith('zh-') && item.localService);
  58. if (cnVoices.length === 0) {
  59. throw new Error('没有可用的中文语音!');
  60. }
  61. this.voices = cnVoices;
  62. return cnVoices;
  63. } catch (error) {
  64. console.error(error);
  65. throw error;
  66. }
  67. }
  68. // 异步获取所有可用的语音
  69. async getSpeechVoices() {
  70. // 返回一个新的 Promise
  71. return new Promise((resolve) => {
  72. // 如果当前没有可用的语音,等待 onvoiceschanged 事件触发
  73. if (this.synth.getVoices().length === 0) {
  74. this.synth.onvoiceschanged = () => resolve(this.synth.getVoices());
  75. } else {
  76. // 如果已经有可用的语音,立即解析 Promise
  77. resolve(this.synth.getVoices());
  78. }
  79. });
  80. }
  81. }