This commit is contained in:
2026-02-24 01:11:04 +08:00
parent d69a99882f
commit e01bb0bb5f
2 changed files with 100 additions and 79 deletions

View File

@@ -30,11 +30,11 @@
</div>
<!-- APlayer 播放器容器 -->
<div v-if="audioUrl" ref="playerContainer" class="aplayer-container"></div>
<div v-show="audioUrl" ref="playerContainer" class="aplayer-container"></div>
<!-- 下载按钮 -->
<a-button
v-if="audioUrl"
v-show="audioUrl"
type="link"
size="small"
@click="downloadAudio"
@@ -47,8 +47,8 @@
<script setup>
import { ref, computed, onMounted, onBeforeUnmount, nextTick, watch } from 'vue'
import { useRouter } from 'vue-router'
import { Empty } from 'ant-design-vue'
import { SoundOutlined } from '@ant-design/icons-vue'
import { useVoiceCopyStore } from '@/stores/voiceCopy'
import { useTTS, TTS_PROVIDERS } from '@/composables/useTTS'
import APlayer from 'aplayer'
@@ -64,13 +64,8 @@ const props = defineProps({
}
})
const router = useRouter()
const simpleImage = Empty.PRESENTED_IMAGE_SIMPLE
const goToVoiceManage = () => {
router.push('/digital-human/voice-copy')
}
const voiceStore = useVoiceCopyStore()
const emit = defineEmits(['select'])
@@ -205,14 +200,12 @@ const initPlayer = (url) => {
audioUrl.value = url
nextTick(() => {
if (!playerContainer.value) return
player = new APlayer({
container: playerContainer.value,
autoplay: true,
theme: '#3b82f6',
preload: 'auto',
volume: 0.7,
loop: 'none',
audio: [{
name: currentVoiceName.value || '语音合成',
artist: '合成',
@@ -221,7 +214,9 @@ const initPlayer = (url) => {
}]
})
// 播放结束后保留播放器,让用户可以再次播放
player.on('ended', () => {
player.seek(0)
})
player.on('error', (e) => {
console.error('APlayer 播放错误:', e)
@@ -235,9 +230,10 @@ const initPlayer = (url) => {
const downloadAudio = () => {
if (!audioUrl.value) return
const filename = `${currentVoiceName.value || '语音合成'}.mp3`
const link = document.createElement('a')
link.href = audioUrl.value
link.download = `${currentVoiceName.value || '语音合成'}.mp3`
link.download = filename
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
@@ -255,10 +251,11 @@ const destroyPlayer = () => {
}
player = null
}
if (audioUrl.value) {
// 只对 blob URL 调用 revokeObjectURL
if (audioUrl.value && audioUrl.value.startsWith('blob:')) {
URL.revokeObjectURL(audioUrl.value)
audioUrl.value = ''
}
audioUrl.value = ''
}
defineExpose({})