refactor: 浏览器播放的语音支持暂停和继续播放

This commit is contained in:
CaptainB 2024-09-24 14:43:11 +08:00 committed by 刘瑞斌
parent e69b74ec86
commit 791c94724c
2 changed files with 73 additions and 8 deletions

View File

@ -90,6 +90,7 @@ const EditMarkDialogRef = ref()
const buttonData = ref(props.data)
const loading = ref(false)
const utterance = ref<SpeechSynthesisUtterance | null>(null)
function editContent(data: any) {
EditContentDialogRef.value.open(data)
@ -101,18 +102,60 @@ function editMark(data: any) {
const audioPlayerStatus = ref(false)
function markdownToPlainText(md: string) {
return (
md
// ![alt](url)
.replace(/!\[.*?\]\(.*?\)/g, '')
// [text](url)
.replace(/\[([^\]]+)\]\([^)]+\)/g, '$1')
// Markdown (#, ##, ###)
.replace(/^#{1,6}\s+/gm, '')
// **text** __text__
.replace(/\*\*(.*?)\*\*/g, '$1')
.replace(/__(.*?)__/g, '$1')
// *text* _text_
.replace(/\*(.*?)\*/g, '$1')
.replace(/_(.*?)_/g, '$1')
// `code`
.replace(/`(.*?)`/g, '$1')
// ```code```
.replace(/```[\s\S]*?```/g, '')
//
.replace(/\n{2,}/g, '\n')
.trim()
)
}
const playAnswerText = (text: string) => {
if (!text) {
text = '抱歉,没有查找到相关内容,请重新描述您的问题或提供更多信息。'
}
// text
text = markdownToPlainText(text)
audioPlayerStatus.value = true
if (props.tts_type === 'BROWSER') {
if (text !== utterance.value?.text) {
window.speechSynthesis.cancel()
}
if (window.speechSynthesis.paused) {
window.speechSynthesis.resume()
return
}
// SpeechSynthesisUtterance
const utterance = new SpeechSynthesisUtterance(text)
utterance.value = new SpeechSynthesisUtterance(text)
utterance.value.onend = () => {
audioPlayerStatus.value = false
utterance.value = null
}
utterance.value.onerror = () => {
audioPlayerStatus.value = false
utterance.value = null
}
//
window.speechSynthesis.speak(utterance)
window.speechSynthesis.speak(utterance.value)
}
if (props.tts_type === 'TTS') {
audioPlayerStatus.value = true
//
if (audioPlayer.value?.src) {
audioPlayer.value?.play()
@ -152,10 +195,13 @@ const playAnswerText = (text: string) => {
}
const pausePlayAnswerText = () => {
audioPlayerStatus.value = false
if (props.tts_type === 'TTS') {
audioPlayerStatus.value = false
audioPlayer.value?.pause()
}
if (props.tts_type === 'BROWSER') {
window.speechSynthesis.pause()
}
}
function refreshMark() {

View File

@ -120,6 +120,7 @@ const audioPlayer = ref<HTMLAudioElement | null>(null)
const audioPlayerStatus = ref(false)
const buttonData = ref(props.data)
const loading = ref(false)
const utterance = ref<SpeechSynthesisUtterance | null>(null)
function regeneration() {
emit('regeneration')
@ -165,14 +166,29 @@ const playAnswerText = (text: string) => {
}
// text
text = markdownToPlainText(text)
audioPlayerStatus.value = true
if (props.tts_type === 'BROWSER') {
if (text !== utterance.value?.text) {
window.speechSynthesis.cancel()
}
if (window.speechSynthesis.paused) {
window.speechSynthesis.resume()
return
}
// SpeechSynthesisUtterance
const utterance = new SpeechSynthesisUtterance(text)
utterance.value = new SpeechSynthesisUtterance(text)
utterance.value.onend = () => {
audioPlayerStatus.value = false
utterance.value = null
}
utterance.value.onerror = () => {
audioPlayerStatus.value = false
utterance.value = null
}
//
window.speechSynthesis.speak(utterance)
window.speechSynthesis.speak(utterance.value)
}
if (props.tts_type === 'TTS') {
audioPlayerStatus.value = true
//
if (audioPlayer.value?.src) {
audioPlayer.value?.play()
@ -212,10 +228,13 @@ const playAnswerText = (text: string) => {
}
const pausePlayAnswerText = () => {
audioPlayerStatus.value = false
if (props.tts_type === 'TTS') {
audioPlayerStatus.value = false
audioPlayer.value?.pause()
}
if (props.tts_type === 'BROWSER') {
window.speechSynthesis.pause()
}
}
</script>
<style lang="scss" scoped></style>