hookehuyr

refactor: 更新视频播放器配置和视频链接

调整视频播放器的配置项,优化代码格式,并更新视频链接以使用新的资源地址
...@@ -12,79 +12,80 @@ ...@@ -12,79 +12,80 @@
12 </template> 12 </template>
13 13
14 <script setup> 14 <script setup>
15 -import { ref, computed, onMounted, onBeforeUnmount, defineProps, defineEmits } from 'vue' 15 +import { ref, computed, onMounted, onBeforeUnmount, defineProps, defineEmits } from "vue";
16 -import { VideoPlayer } from '@videojs-player/vue' 16 +import { VideoPlayer } from "@videojs-player/vue";
17 -import videojs from 'video.js' 17 +import videojs from "video.js";
18 -import 'video.js/dist/video-js.css' 18 +import "video.js/dist/video-js.css";
19 19
20 const props = defineProps({ 20 const props = defineProps({
21 options: { 21 options: {
22 type: Object, 22 type: Object,
23 required: false, 23 required: false,
24 - default: () => ({}) 24 + default: () => ({}),
25 }, 25 },
26 videoUrl: { 26 videoUrl: {
27 type: String, 27 type: String,
28 - required: true 28 + required: true,
29 - } 29 + },
30 -}) 30 +});
31 31
32 -const emit = defineEmits(['onPlay', 'onPause']) 32 +const emit = defineEmits(["onPlay", "onPause"]);
33 -const videoRef = ref(null) 33 +const videoRef = ref(null);
34 -const player = ref(null) 34 +const player = ref(null);
35 -const state = ref(null) 35 +const state = ref(null);
36 36
37 const videoOptions = computed(() => ({ 37 const videoOptions = computed(() => ({
38 - fluid: true,
39 controls: true, 38 controls: true,
40 - preload: 'auto', 39 + preload: "auto",
41 responsive: true, 40 responsive: true,
42 autoplay: props.options?.autoplay || false, 41 autoplay: props.options?.autoplay || false,
43 - sources: [{ 42 + sources: [
43 + {
44 src: props.videoUrl, 44 src: props.videoUrl,
45 - type: 'video/mp4' 45 + type: "video/mp4",
46 - }], 46 + },
47 - onPlay: () => emit('onPlay'), 47 + ],
48 - onPause: () => emit('onPause'), 48 + onPlay: () => emit("onPlay"),
49 + onPause: () => emit("onPause"),
49 userActions: { 50 userActions: {
50 hotkeys: true, 51 hotkeys: true,
51 - doubleClick: true 52 + doubleClick: true,
52 }, 53 },
53 controlBar: { 54 controlBar: {
54 progressControl: { 55 progressControl: {
55 seekBar: { 56 seekBar: {
56 mouseTimeDisplay: { 57 mouseTimeDisplay: {
57 - keepTooltipsInside: true 58 + keepTooltipsInside: true,
58 - } 59 + },
59 - } 60 + },
60 - }
61 }, 61 },
62 - ...props.options 62 + },
63 -})) 63 + ...props.options,
64 +}));
64 65
65 const onPlayerReady = (instance) => { 66 const onPlayerReady = (instance) => {
66 - player = instance 67 + player = instance;
67 -} 68 +};
68 69
69 const handleMounted = (payload) => { 70 const handleMounted = (payload) => {
70 - console.log('Advanced player mounted', payload) 71 + console.log("Advanced player mounted", payload);
71 - state.value = payload.state 72 + state.value = payload.state;
72 - player.value = payload.player 73 + player.value = payload.player;
73 -} 74 +};
74 75
75 onBeforeUnmount(() => { 76 onBeforeUnmount(() => {
76 if (videoRef.value?.$player) { 77 if (videoRef.value?.$player) {
77 - videoRef.value.$player.dispose() 78 + videoRef.value.$player.dispose();
78 } 79 }
79 -}) 80 +});
80 81
81 defineExpose({ 82 defineExpose({
82 pause() { 83 pause() {
83 if (videoRef.value?.$player) { 84 if (videoRef.value?.$player) {
84 - videoRef.value.$player.pause() 85 + videoRef.value.$player.pause();
85 - }
86 } 86 }
87 -}) 87 + },
88 +});
88 </script> 89 </script>
89 90
90 <style scoped> 91 <style scoped>
...@@ -93,4 +94,15 @@ defineExpose({ ...@@ -93,4 +94,15 @@ defineExpose({
93 height: 100%; 94 height: 100%;
94 position: relative; 95 position: relative;
95 } 96 }
97 +
98 +.video-player {
99 + width: 100%;
100 + height: 100%;
101 + display: block;
102 + aspect-ratio: 16/9;
103 +}
104 +
105 +.video-player.loading {
106 + opacity: 0.6;
107 +}
96 </style> 108 </style>
......
1 <!-- 1 <!--
2 * @Date: 2025-03-20 19:55:21 2 * @Date: 2025-03-20 19:55:21
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2025-03-24 15:14:00 4 + * @LastEditTime: 2025-03-24 16:17:17
5 * @FilePath: /mlaj/src/views/HomePage.vue 5 * @FilePath: /mlaj/src/views/HomePage.vue
6 * @Description: 文件描述 6 * @Description: 文件描述
7 --> 7 -->
...@@ -443,9 +443,9 @@ ...@@ -443,9 +443,9 @@
443 <div class="space-y-4"> 443 <div class="space-y-4">
444 <div 444 <div
445 v-for="(item, index) in [ 445 v-for="(item, index) in [
446 - { title: '亲子沟通的艺术', views: '1.2万', duration: '08:25', image: 'https://cdn.ipadbiz.cn/mlaj/images/video-1.jpg', video_url: 'http://vjs.zencdn.net/v/oceans.mp4' }, 446 + { title: '亲子沟通的艺术', views: '1.2万', duration: '08:25', image: 'https://cdn.ipadbiz.cn/mlaj/images/video-1.jpg', video_url: 'https://sf1-cdn-tos.huoshanstatic.com/obj/media-fe/xgplayer_doc_video/mp4/xgplayer-demo-360p.mp4' },
447 - { title: '如何做好家庭教育', views: '8千', duration: '12:40', image: 'https://cdn.ipadbiz.cn/mlaj/images/video-2.jpg', video_url: 'http://vjs.zencdn.net/v/oceans.mp4' }, 447 + { title: '如何做好家庭教育', views: '8千', duration: '12:40', image: 'https://cdn.ipadbiz.cn/mlaj/images/video-2.jpg', video_url: 'https://sf1-cdn-tos.huoshanstatic.com/obj/media-fe/xgplayer_doc_video/mp4/xgplayer-demo-360p.mp4' },
448 - { title: '孩子营养餐制作指南', views: '5千', duration: '15:18', image: 'https://cdn.ipadbiz.cn/mlaj/images/video-3.jpg', video_url: 'http://vjs.zencdn.net/v/oceans.mp4' } 448 + { title: '孩子营养餐制作指南', views: '5千', duration: '15:18', image: 'https://cdn.ipadbiz.cn/mlaj/images/video-3.jpg', video_url: 'https://sf1-cdn-tos.huoshanstatic.com/obj/media-fe/xgplayer_doc_video/mp4/xgplayer-demo-360p.mp4' }
449 ]" 449 ]"
450 :key="index" 450 :key="index"
451 class="relative rounded-xl overflow-hidden shadow-md h-48" 451 class="relative rounded-xl overflow-hidden shadow-md h-48"
......