This commit is contained in:
itcsx committed 2026-09-21 21:31:16 +08:00
1 parent 7c8af2fb08
commit c10f8347e2
31 files changed
+358 -292

No files matched your search

+33 -7
View File
@@ -19,7 +19,8 @@
<a-spin size="large" />
<span>加载中…</span>
</div>
<button v-if="!isPlaying && !buffering" class="vp-bigplay" type="button" title="播放" @click.stop="toggle">
<button v-if="!isPlaying && !buffering" class="vp-bigplay" type="button" aria-label="播放"
@click.stop="toggle">
<CaretRightFilled />
</button>
</div>
@@ -107,7 +108,7 @@
<button class="vp-ctl" type="button" title="上一个" @click="goPrev">
<StepBackwardFilled />
</button>
<button class="vp-play" type="button" :title="isPlaying ? '暂停' : '播放'" @click="toggle">
<button class="vp-play" type="button" :aria-label="isPlaying ? '暂停' : '播放'" @click="toggle">
<PauseOutlined v-if="isPlaying" />
<CaretRightFilled v-else />
</button>
@@ -161,11 +162,20 @@ import {
/** 一个视频 */
export type VideoItem = PublishVideoDetailDisplayData;
const props = withDefaults(defineProps<{ videos?: VideoItem[] }>(), { videos: () => [] });
const props = withDefaults(
defineProps<{
videos?: VideoItem[];
/** 打开时从第几个开始播(点列表里的某一个进来时用) */
startIndex?: number;
/** 挂上播放源后是否立即播放(弹窗里默认自动播) */
autoPlay?: boolean;
}>(),
{ videos: () => [], startIndex: 0, autoPlay: false },
);
/* ---------------- 基础状态 ---------------- */
const videoRef = ref<HTMLVideoElement | null>(null);
const index = ref(0);
const index = ref(props.startIndex);
const isPlaying = ref(false);
const currentTime = ref(0);
const duration = ref(0);
@@ -589,7 +599,8 @@ const fmt = (t: number) => {
};
/* ---------------- 联动 ---------------- */
watch(current, async (t) => {
/** 切到某个视频:重置状态 → 挂播放源 → 按需播放 */
const prepare = async (t: VideoItem | null, play: boolean) => {
currentTime.value = 0;
duration.value = 0;
bufferedEnd.value = 0;
@@ -599,11 +610,13 @@ watch(current, async (t) => {
ensureStageRO();
// 重新挂接播放源:m3u8 走 hls.js,普通文件走 src(内部会销毁上一个 hls 实例)
attachSource(t.FormattedUrl);
if (resumeAfterSwitch) {
if (play || props.autoPlay) {
resumeAfterSwitch = false;
tryPlay();
}
});
};
watch(current, (t) => prepare(t, resumeAfterSwitch));
// 播放列表默认收起,由用户点击列表按钮展开
watch(
@@ -613,6 +626,17 @@ watch(
}
);
// 外部指定了从第几个开始播(弹窗没销毁又换了视频时也要跟随)
watch(
() => props.startIndex,
(i) => {
if (i >= 0 && i < videos.value.length && i !== index.value) {
resumeAfterSwitch = true;
index.value = i;
}
}
);
watch([volume, muted], () => {
const v = videoRef.value;
if (!v) return;
@@ -625,6 +649,8 @@ watch(rate, () => {
let timerId = 0;
onMounted(() => {
// 列表在挂载时就已就绪的情况(例如弹窗里先备好数据再打开),watch 不会触发,这里补一次
if (current.value) prepare(current.value, false);
document.addEventListener("click", onDocClick);
document.addEventListener("fullscreenchange", onFullscreenChange);
timerId = window.setInterval(() => {