feat: 优化

This commit is contained in:
2026-02-26 18:52:09 +08:00
parent c2e4fde218
commit b76e3ff47d
17 changed files with 1027 additions and 1630 deletions

View File

@@ -18,7 +18,7 @@
<a-button
class="preview-button"
size="small"
:disabled="!selectedVoiceId"
:disabled="!selectedVoiceId || isPlayerInitializing"
:loading="previewLoadingVoiceId === selectedVoiceId"
@click="handleSynthesize"
>
@@ -74,6 +74,7 @@ let player = null
const playerContainer = ref(null)
const audioUrl = ref('')
const currentVoiceName = ref('')
const isPlayerInitializing = ref(false)
// 默认封面图片(音频波形图标)
const defaultCover = `data:image/svg+xml;base64,${btoa(`
@@ -154,6 +155,8 @@ const handleVoiceChange = (value, option) => {
const handleSynthesize = () => {
if (!selectedVoiceId.value) return
// 防止在播放器初始化过程中重复点击
if (isPlayerInitializing.value) return
const voice = userVoiceCards.value.find(v => v.id === selectedVoiceId.value)
if (!voice) return
@@ -171,23 +174,17 @@ watch(() => props.speechRate, (newRate) => {
setSpeechRate(newRate)
}, { immediate: true })
/**
* 处理音色
*/
const handlePlayVoiceSample = (voice) => {
currentVoiceName.value = voice.name
playVoiceSample(
voice,
(data) => {
const url = data.audioUrl || data.objectUrl
if (!url) {
console.error('无效的音频数据格式', data)
return
}
if (!url) return
initPlayer(url)
},
(error) => {
console.error('音频播放失败', error)
// 音频播放失败,静默处理
},
{ autoPlay: false } // 禁用自动播放,由 APlayer 控制
)
@@ -197,31 +194,46 @@ const handlePlayVoiceSample = (voice) => {
* 初始化 APlayer
*/
const initPlayer = (url) => {
// 防止并发初始化
if (isPlayerInitializing.value) {
return
}
isPlayerInitializing.value = true
destroyPlayer()
audioUrl.value = url
nextTick(() => {
player = new APlayer({
container: playerContainer.value,
autoplay: true,
theme: '#3b82f6',
volume: 0.7,
loop: 'none',
audio: [{
name: currentVoiceName.value || '语音合成',
artist: '合成',
url: url,
cover: defaultCover
}]
})
try {
player = new APlayer({
container: playerContainer.value,
autoplay: true,
theme: '#3b82f6',
volume: 0.7,
loop: 'none',
audio: [{
name: currentVoiceName.value || '语音合成',
artist: '合成',
url: url,
cover: defaultCover
}]
})
player.on('ended', () => {
player.seek(0)
})
player.on('ended', () => {
player.seek(0)
})
player.on('error', (e) => {
console.error('APlayer 播放错误:', e)
})
player.on('error', (e) => {
console.error('APlayer 播放错误:', e)
})
player.on('canplay', () => {
isPlayerInitializing.value = false
})
} catch (e) {
console.error('APlayer 初始化失败:', e)
isPlayerInitializing.value = false
}
})
}
@@ -244,8 +256,11 @@ const downloadAudio = () => {
* 销毁播放器
*/
const destroyPlayer = () => {
isPlayerInitializing.value = false
if (player) {
try {
// 先暂停播放,防止销毁过程中出错
player.pause()
player.destroy()
} catch (e) {
console.error('销毁播放器失败:', e)
@@ -259,8 +274,6 @@ const destroyPlayer = () => {
audioUrl.value = ''
}
defineExpose({})
onMounted(async () => {
await voiceStore.refresh()
})