Commit 98c564f4 authored by xuchaozou's avatar xuchaozou

pref: 优化语音播报断句

parent ce5c9c28
Pipeline #87201 waiting for manual action with stages
export default { export default {
punctuationMark : "。,、;:?!”“,.!:" punctuationMark : new Set(Array.from(["。", ",", "、", ":", ";", "?", "!", "”", "“", ",", ".", "!", ":", "\"", "\n"]))
} }
\ No newline at end of file
import config from "../../config"
class PandaSpeechSynthesisUtterance { class PandaSpeechSynthesisUtterance {
constructor (options = {}) { constructor(options = {}) {
this.voiceParams = this.getVoiceParams(options.voiceParams ?? {}) this.voiceParams = this.getVoiceParams(options.voiceParams ?? {})
this.data = [] this.data = []
window.speechSynthesis.cancel() window.speechSynthesis.cancel()
this.resolve = null this.resolve = null
this.reject = null this.reject = null
this.onEnd = this.onEnd.bind(this) this.onEnd = this.onEnd.bind(this)
this.tempText = ""
this.punctuationMark = Array.from(config.punctuationMark)
} }
getVoiceParams (voiceParams) { getVoiceParams(voiceParams) {
return { return {
volume : 1, volume: 1,
rate : 1, rate: 1,
pitch : 1, pitch: 1,
...voiceParams ...voiceParams
} }
} }
push(text) { push(text) {
if(!text) return if (!text) return
this.data.push(this.getSpeechSynthesisUtterance(text)) this.tempText += text;
const match = this.tempText.matchAll(new RegExp(`[${this.punctuationMark.join("|")}]`, "g"))
if (!match) return
let startIndex = 0, endIndex = 0
for (const result of match) {
startIndex = endIndex
endIndex = result.index + 1
const sentence = this.tempText.substring(startIndex, endIndex)
this.data.push(this.getSpeechSynthesisUtterance(sentence))
window.speechSynthesis.speak(this.data.at(-1)) window.speechSynthesis.speak(this.data.at(-1))
} }
this.tempText = this.tempText.substring(endIndex)
}
getSpeechSynthesisUtterance(text) { getSpeechSynthesisUtterance(text) {
const speak = new SpeechSynthesisUtterance(text) const speak = new SpeechSynthesisUtterance(text)
speak.addEventListener("end", this.onEnd) speak.addEventListener("end", this.onEnd)
for(let key in this.voiceParams) { for (let key in this.voiceParams) {
speak[key] = this.voiceParams[key] speak[key] = this.voiceParams[key]
} }
return speak return speak
} }
onEnd () { onEnd() {
this.data.shift() this.data.shift()
if(this.data.length == 0) { if (this.data.length == 0) {
this.resolve && this.resolve() this.resolve && this.resolve()
} }
} }
speakEnd () { speakEnd() {
return new Promise((resolve , reject) => { if(this.tempText) {
this.data.push(this.getSpeechSynthesisUtterance(this.tempText))
window.speechSynthesis.speak(this.data.at(-1))
this.tempText = ""
}
return new Promise((resolve, reject) => {
this.resolve = resolve this.resolve = resolve
this.reject = reject this.reject = reject
}) })
......
...@@ -10,16 +10,16 @@ class CloseMenuDirective extends BaseDirective { ...@@ -10,16 +10,16 @@ class CloseMenuDirective extends BaseDirective {
const { text } = this; const { text } = this;
let result = null; let result = null;
if(!result) { if(!result) {
result = text.match(new RegExp(`关闭(所有).*(?=(?:[${config.punctuationMark}]?))`)) result = text.match(new RegExp(`关闭(所有).*(?=(?:[${Array.from(config.punctuationMark).join("|")}]?))`))
} }
if (!result) { if (!result) {
result = text.match(new RegExp(`关闭(当前).*(?=(?:[${config.punctuationMark}]?))`)) result = text.match(new RegExp(`关闭(当前).*(?=(?:[${Array.from(config.punctuationMark).join("|")}]?))`))
} }
if (!result) { if (!result) {
result = text.match(/关闭(.*)(?=(?:菜单|功能|路径))/); result = text.match(/关闭(.*)(?=(?:菜单|功能|路径))/);
} }
if (!result) { if (!result) {
result = text.match(new RegExp(`关闭(.*)(?=(?:[${config.punctuationMark}]?))`)) result = text.match(new RegExp(`关闭(.*)(?=(?:[${Array.from(config.punctuationMark).join("|")}]?))`))
} }
if (result && result.length >= 2 && !this.matchResult) { if (result && result.length >= 2 && !this.matchResult) {
this.matchResult = result[1]; this.matchResult = result[1];
......
...@@ -3,7 +3,7 @@ import BaseDirective from './BaseDirective' ...@@ -3,7 +3,7 @@ import BaseDirective from './BaseDirective'
class CloseSessionDirective extends BaseDirective { class CloseSessionDirective extends BaseDirective {
match (){ match (){
const {text} = this const {text} = this
if(/结束(.*)[的对]/.test(text)) { if(/[熊猫熊猫|什么什么]/.test(text)) {
return true return true
} }
return false return false
......
...@@ -15,7 +15,7 @@ class OpenMenuDirective extends BaseDirective { ...@@ -15,7 +15,7 @@ class OpenMenuDirective extends BaseDirective {
result = text.match(/打开(.*)(?=(?:菜单|功能|路径))/) result = text.match(/打开(.*)(?=(?:菜单|功能|路径))/)
} }
if (!result) { if (!result) {
result = text.match(new RegExp(`打开(.*)(?=(?:[${config.punctuationMark}]?))`)) result = text.match(new RegExp(`打开(.*)(?=(?:[${Array.from(config.punctuationMark).join("|")}]?))`))
} }
if (result && result.length >= 2 && !this.matchResult) { if (result && result.length >= 2 && !this.matchResult) {
this.matchResult = result[1] this.matchResult = result[1]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment