3 文章播放完后自动播放
This commit is contained in:
@@ -119,9 +119,14 @@ const handlePause = () => {
|
||||
isPlaying.value = false;
|
||||
};
|
||||
|
||||
const emit = defineEmits<{
|
||||
ended: []
|
||||
}>();
|
||||
|
||||
const handleEnded = () => {
|
||||
isPlaying.value = false;
|
||||
currentTime.value = 0;
|
||||
emit('ended');
|
||||
};
|
||||
|
||||
const handleError = () => {
|
||||
|
||||
@@ -33,6 +33,16 @@ let studyLoading = $ref(false)
|
||||
|
||||
let selectArticle: Article = $ref(getDefaultArticle())
|
||||
|
||||
// 计算当前选中文章的索引
|
||||
const currentArticleIndex = computed(() => {
|
||||
return runtimeStore.editDict.articles.findIndex(article => article.id === selectArticle.id)
|
||||
})
|
||||
|
||||
// 处理播放下一个音频
|
||||
const handlePlayNext = (nextArticle: Article) => {
|
||||
selectArticle = nextArticle
|
||||
}
|
||||
|
||||
function handleCheckedChange(val) {
|
||||
selectArticle = val.item
|
||||
}
|
||||
@@ -191,7 +201,11 @@ const totalSpend = $computed(() => {
|
||||
</div>
|
||||
<div class="en-article-family title text-xl">
|
||||
<div class="text-center text-2xl my-2">
|
||||
<ArticleAudio :article="selectArticle"></ArticleAudio>
|
||||
<ArticleAudio
|
||||
:article="selectArticle"
|
||||
:article-list="runtimeStore.editDict.articles"
|
||||
:current-index="currentArticleIndex"
|
||||
@play-next="handlePlayNext"></ArticleAudio>
|
||||
</div>
|
||||
<div class="text-center text-2xl">{{ selectArticle.title }}</div>
|
||||
<div class="text-2xl" v-if="selectArticle.text">
|
||||
|
||||
@@ -328,6 +328,14 @@ function changeArticle(val: ArticleItem) {
|
||||
}
|
||||
}
|
||||
|
||||
const handlePlayNext = (nextArticle: Article) => {
|
||||
let rIndex = articleData.list.findIndex(v => v.id === nextArticle.id)
|
||||
if (rIndex > -1) {
|
||||
store.sbook.lastLearnIndex = rIndex
|
||||
getCurrentPractice()
|
||||
}
|
||||
}
|
||||
|
||||
const {
|
||||
isArticleCollect,
|
||||
toggleArticleCollect
|
||||
@@ -489,7 +497,12 @@ provide('currentPractice', currentPractice)
|
||||
<div class="name">单词总数</div>
|
||||
</div>
|
||||
</div>
|
||||
<ArticleAudio ref="audioRef" :article="articleData.article"></ArticleAudio>
|
||||
<ArticleAudio
|
||||
ref="audioRef"
|
||||
:article="articleData.article"
|
||||
:article-list="articleData.list"
|
||||
:current-index="store.sbook.lastLearnIndex"
|
||||
@play-next="handlePlayNext"></ArticleAudio>
|
||||
<div class="flex flex-col items-center justify-center gap-1">
|
||||
<div class="flex gap-2 center">
|
||||
<Tooltip title="自动发音">
|
||||
|
||||
@@ -7,10 +7,45 @@ import Audio from "@/components/base/Audio.vue";
|
||||
|
||||
const props = defineProps<{
|
||||
article: Article
|
||||
articleList?: Article[]
|
||||
currentIndex?: number
|
||||
}>()
|
||||
|
||||
let file = $ref(null)
|
||||
let instance = $ref<{ audioRef: HTMLAudioElement }>({audioRef: null})
|
||||
let shouldAutoPlay = $ref(false) // 标记是否应该自动播放
|
||||
|
||||
const emit = defineEmits<{
|
||||
playNext: [nextArticle: Article]
|
||||
}>()
|
||||
|
||||
// 处理音频播放结束,自动播放下一个
|
||||
const handleAudioEnded = () => {
|
||||
if (props.articleList && props.currentIndex !== undefined) {
|
||||
const nextIndex = props.currentIndex + 1
|
||||
if (nextIndex < props.articleList.length) {
|
||||
const nextArticle = props.articleList[nextIndex]
|
||||
if (nextArticle.audioSrc || nextArticle.audioFileId) {
|
||||
shouldAutoPlay = true // 设置自动播放标记
|
||||
emit('playNext', nextArticle)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 当音频源改变时,如果需要自动播放则开始播放
|
||||
const startAutoPlay = async () => {
|
||||
if (shouldAutoPlay && instance?.audioRef) {
|
||||
shouldAutoPlay = false // 重置标记
|
||||
try {
|
||||
// 等待一小段时间确保音频元素已经准备好
|
||||
await new Promise(resolve => setTimeout(resolve, 100))
|
||||
await instance.audioRef.play()
|
||||
} catch (error) {
|
||||
console.error('自动播放失败:', error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
watch(() => props.article.audioFileId, async () => {
|
||||
if (!props.article.audioSrc && props.article.audioFileId) {
|
||||
@@ -19,6 +54,9 @@ watch(() => props.article.audioFileId, async () => {
|
||||
let rItem = list.find((file) => file.id === props.article.audioFileId)
|
||||
if (rItem) {
|
||||
file = URL.createObjectURL(rItem.file)
|
||||
// 当文件加载完成后尝试自动播放
|
||||
await new Promise(resolve => setTimeout(resolve, 50))
|
||||
startAutoPlay()
|
||||
}
|
||||
}
|
||||
}else {
|
||||
@@ -26,6 +64,15 @@ watch(() => props.article.audioFileId, async () => {
|
||||
}
|
||||
}, {immediate: true})
|
||||
|
||||
// 监听音频源变化,触发自动播放
|
||||
watch(() => props.article.audioSrc, async (newSrc) => {
|
||||
if (newSrc) {
|
||||
// 当音频源改变后尝试自动播放
|
||||
await new Promise(resolve => setTimeout(resolve, 50))
|
||||
startAutoPlay()
|
||||
}
|
||||
})
|
||||
|
||||
//转发一遍,这里Proxy的默认值不能为{},可能是vue做了什么
|
||||
defineExpose(new Proxy({
|
||||
currentTime: 0,
|
||||
@@ -57,8 +104,10 @@ defineExpose(new Proxy({
|
||||
<template>
|
||||
<Audio v-bind="$attrs" ref="instance"
|
||||
v-if="props.article.audioSrc"
|
||||
:src="props.article.audioSrc"/>
|
||||
:src="props.article.audioSrc"
|
||||
@ended="handleAudioEnded"/>
|
||||
<Audio ref="instance" v-else-if="file"
|
||||
:src="file"
|
||||
@ended="handleAudioEnded"
|
||||
/>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user