|
@@ -0,0 +1,94 @@
|
|
|
+<script setup lang='ts'>
|
|
|
+import videojs from "video.js";
|
|
|
+import "video.js/dist/video-js.css";
|
|
|
+import { nextTick } from 'vue';
|
|
|
+const props = defineProps({
|
|
|
+ src: {
|
|
|
+ type: String,
|
|
|
+ required: true,
|
|
|
+ },
|
|
|
+ poster: {
|
|
|
+ type: String,
|
|
|
+ required: false,
|
|
|
+ },
|
|
|
+});
|
|
|
+
|
|
|
+const emits = defineEmits(["scoreAtTarget"]);
|
|
|
+
|
|
|
+const videoPlayerRef = shallowRef();
|
|
|
+const player = ref();
|
|
|
+
|
|
|
+function getSourceType(src: string) {
|
|
|
+ const ext = src.split(".").pop();
|
|
|
+ console.log(src);
|
|
|
+
|
|
|
+ // if (ext?.includes('/'))
|
|
|
+ // return 'application/x-mpegURL'
|
|
|
+ // else
|
|
|
+ if (ext === "m3u8") return "application/x-mpegURL";
|
|
|
+ else return `video/${ext}`;
|
|
|
+}
|
|
|
+
|
|
|
+onMounted(() => {
|
|
|
+ if (!videoPlayerRef.value) return;
|
|
|
+ nextTick(() => {
|
|
|
+ player.value = videojs(
|
|
|
+ videoPlayerRef.value as HTMLVideoElement,
|
|
|
+ {
|
|
|
+ autoplay: false,
|
|
|
+ controls: true,
|
|
|
+ lang: "zh-CN",
|
|
|
+ playbackRates: [0.5, 1, 1.25, 1.5, 2], // 倍速数组
|
|
|
+ controlBar: {
|
|
|
+ children: [
|
|
|
+ "PlayToggle", // 播放
|
|
|
+ "NextBtn", // 下一个
|
|
|
+ "CurrentTimeDisplay", // 当前时间
|
|
|
+ 'ProgressControl', // 进度条
|
|
|
+ "DurationDisplay", // 时长
|
|
|
+ "VolumePanel", // 音量
|
|
|
+ "PlaybackRateMenuButton", // 倍速
|
|
|
+ "FullscreenToggle", // 全屏
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ poster: props.poster,
|
|
|
+ sources: [
|
|
|
+ {
|
|
|
+ src: props.src,
|
|
|
+ type: getSourceType(props.src),
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ () => {
|
|
|
+ console.log("player is ready");
|
|
|
+ const p = player.value;
|
|
|
+ let callbackExecuted = false;
|
|
|
+ p.on("timeupdate", () => {
|
|
|
+ // 计算视频已经播放的百分比
|
|
|
+ const percentagePlayed = p.currentTime() / p.duration();
|
|
|
+
|
|
|
+ if (percentagePlayed >= 0.9 && !callbackExecuted) {
|
|
|
+ // 执行回调函数
|
|
|
+ console.log("达到目标时间");
|
|
|
+ emits("scoreAtTarget");
|
|
|
+ p.off("timeupdate");
|
|
|
+ callbackExecuted = true;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ );
|
|
|
+ });
|
|
|
+});
|
|
|
+
|
|
|
+onUnmounted(() => {
|
|
|
+ if (player.value) player.value?.dispose?.();
|
|
|
+});
|
|
|
+</script>
|
|
|
+
|
|
|
+<template>
|
|
|
+ <video
|
|
|
+ ref="videoPlayerRef"
|
|
|
+ :poster="props.poster"
|
|
|
+ class="video-js w-100vw h-56.25vw"
|
|
|
+ />
|
|
|
+</template>
|