Commit 6529af996f5bf4131426cdd9d21403303d742e74

Authored by ww
1 parent b7ab75dd

perf: use video.js refactor camera manage split mode

@@ -26,6 +26,7 @@ @@ -26,6 +26,7 @@
26 muted: true, 26 muted: true,
27 liveui: true, 27 liveui: true,
28 controls: true, 28 controls: true,
  29 + fluid: true,
29 }; 30 };
30 return { ...defaultOptions, ...options }; 31 return { ...defaultOptions, ...options };
31 }); 32 });
@@ -57,7 +58,7 @@ @@ -57,7 +58,7 @@
57 <div :class="prefixCls" class="w-full h-full" :style="getWidthHeight"> 58 <div :class="prefixCls" class="w-full h-full" :style="getWidthHeight">
58 <video 59 <video
59 ref="videoPlayEl" 60 ref="videoPlayEl"
60 - class="video-js vjs-big-play-centered vjs-show-big-play-button-on-pause w-full h-full" 61 + class="video-js vjs-big-play-centered vjs-show-big-play-button-on-pause !w-full !h-full"
61 ></video> 62 ></video>
62 </div> 63 </div>
63 </template> 64 </template>
@@ -5,21 +5,27 @@ @@ -5,21 +5,27 @@
5 import { Spin, Button, Pagination, Space, List } from 'ant-design-vue'; 5 import { Spin, Button, Pagination, Space, List } from 'ant-design-vue';
6 import { cameraPage } from '/@/api/camera/cameraManager'; 6 import { cameraPage } from '/@/api/camera/cameraManager';
7 import { CameraRecord } from '/@/api/camera/model/cameraModel'; 7 import { CameraRecord } from '/@/api/camera/model/cameraModel';
8 - import { videoPlay as VideoPlay } from 'vue3-video-play';  
9 import 'vue3-video-play/dist/style.css'; 8 import 'vue3-video-play/dist/style.css';
10 import { useFullscreen } from '@vueuse/core'; 9 import { useFullscreen } from '@vueuse/core';
11 import CameraDrawer from './CameraDrawer.vue'; 10 import CameraDrawer from './CameraDrawer.vue';
12 import { useDrawer } from '/@/components/Drawer'; 11 import { useDrawer } from '/@/components/Drawer';
13 - import { AccessMode, MediaType, PageMode } from './config.data'; 12 + import { AccessMode, PageMode } from './config.data';
14 import SvgIcon from '/@/components/Icon/src/SvgIcon.vue'; 13 import SvgIcon from '/@/components/Icon/src/SvgIcon.vue';
15 - import { isDef } from '/@/utils/is';  
16 import { getStreamingPlayUrl } from '/@/api/camera/cameraManager'; 14 import { getStreamingPlayUrl } from '/@/api/camera/cameraManager';
17 import { buildUUID } from '/@/utils/uuid'; 15 import { buildUUID } from '/@/utils/uuid';
  16 + import { BasicVideoPlay, getVideoTypeByUrl } from '/@/components/Video';
  17 + import { VideoJsPlayerOptions } from 'video.js';
18 18
19 type CameraRecordItem = CameraRecord & { 19 type CameraRecordItem = CameraRecord & {
20 canPlay?: boolean; 20 canPlay?: boolean;
21 - type?: string;  
22 isTransform?: boolean; 21 isTransform?: boolean;
  22 + videoPlayerOptions?: VideoJsPlayerOptions;
  23 + };
  24 +
  25 + const basicVideoPlayOptions: VideoJsPlayerOptions = {
  26 + width: '100%' as unknown as number,
  27 + height: '100%' as unknown as number,
  28 + autoplay: true,
23 }; 29 };
24 30
25 const emit = defineEmits(['switchMode']); 31 const emit = defineEmits(['switchMode']);
@@ -36,32 +42,6 @@ @@ -36,32 +42,6 @@
36 total: 0, 42 total: 0,
37 }); 43 });
38 44
39 - const options = reactive({  
40 - width: '200px',  
41 - height: '200px',  
42 - color: '#409eff',  
43 - muted: true, //静音  
44 - webFullScreen: false,  
45 - autoPlay: true, //自动播放  
46 - currentTime: 0,  
47 - loop: false, //循环播放  
48 - mirror: false, //镜像画面  
49 - ligthOff: false, //关灯模式  
50 - volume: 0.3, //默认音量大小  
51 - control: true, //是否显示控制器  
52 - type: 'm3u8',  
53 - controlBtns: [  
54 - 'audioTrack',  
55 - 'quality',  
56 - 'speedRate',  
57 - 'volume',  
58 - 'setting',  
59 - 'pip',  
60 - 'pageFullScreen',  
61 - 'fullScreen',  
62 - ],  
63 - });  
64 -  
65 // 树形选择器 45 // 树形选择器
66 const handleSelect = (orgId: string) => { 46 const handleSelect = (orgId: string) => {
67 organizationId.value = orgId; 47 organizationId.value = orgId;
@@ -80,7 +60,6 @@ @@ -80,7 +60,6 @@
80 pagination.total = total; 60 pagination.total = total;
81 61
82 for (const item of items) { 62 for (const item of items) {
83 - // await beforeVideoPlay(item);  
84 (item as CameraRecordItem).isTransform = false; 63 (item as CameraRecordItem).isTransform = false;
85 beforeVideoPlay(item); 64 beforeVideoPlay(item);
86 } 65 }
@@ -91,36 +70,46 @@ @@ -91,36 +70,46 @@
91 })); 70 }));
92 items = [...items, ...fillArr]; 71 items = [...items, ...fillArr];
93 } 72 }
  73 + console.log(items);
94 cameraList.value = items; 74 cameraList.value = items;
95 } catch (error) { 75 } catch (error) {
96 } finally { 76 } finally {
97 loading.value = false; 77 loading.value = false;
98 } 78 }
99 }; 79 };
100 - const getMediaType = (suffix: string) => {  
101 - return suffix === MediaType.M3U8 ? suffix : `video/${suffix}`;  
102 - };  
103 80
104 const beforeVideoPlay = async (record: CameraRecordItem) => { 81 const beforeVideoPlay = async (record: CameraRecordItem) => {
105 - let reg = /(?:.*)(?<=\.)/;  
106 if (record.accessMode === AccessMode.ManuallyEnter) { 82 if (record.accessMode === AccessMode.ManuallyEnter) {
107 if (record.videoUrl) { 83 if (record.videoUrl) {
108 - const type = record.videoUrl.replace(reg, '');  
109 - record.type = getMediaType(type); 84 + (record as CameraRecordItem).videoPlayerOptions = {
  85 + ...basicVideoPlayOptions,
  86 + sources: [
  87 + {
  88 + src: record.videoUrl,
  89 + type: getVideoTypeByUrl(record.videoUrl),
  90 + },
  91 + ],
  92 + };
110 record.isTransform = true; 93 record.isTransform = true;
111 } 94 }
112 } 95 }
113 if (record.accessMode === AccessMode.Streaming) { 96 if (record.accessMode === AccessMode.Streaming) {
114 try { 97 try {
115 const { data: { url } = { url: '' } } = await getStreamingPlayUrl(record.id!); 98 const { data: { url } = { url: '' } } = await getStreamingPlayUrl(record.id!);
116 - const type = url.replace(reg, '');  
117 const index = unref(cameraList).findIndex((item) => item.id === record.id); 99 const index = unref(cameraList).findIndex((item) => item.id === record.id);
118 if (~index) { 100 if (~index) {
119 const oldRecord = unref(cameraList).at(index)!; 101 const oldRecord = unref(cameraList).at(index)!;
120 unref(cameraList)[index] = { 102 unref(cameraList)[index] = {
121 ...oldRecord, 103 ...oldRecord,
122 - videoUrl: url,  
123 - type: getMediaType(type), 104 + videoPlayerOptions: {
  105 + ...basicVideoPlayOptions,
  106 + sources: [
  107 + {
  108 + src: url,
  109 + type: getVideoTypeByUrl(url),
  110 + },
  111 + ],
  112 + },
124 isTransform: true, 113 isTransform: true,
125 }; 114 };
126 } 115 }
@@ -160,20 +149,6 @@ @@ -160,20 +149,6 @@
160 } 149 }
161 }; 150 };
162 151
163 - const handleLoadStart = (record: CameraRecordItem) => {  
164 - const index = unref(cameraList).findIndex((item) => item.id === record.id);  
165 - setTimeout(() => {  
166 - ~index &&  
167 - !unref(cameraList).at(index)!.canPlay &&  
168 - (unref(cameraList).at(index)!.canPlay = false);  
169 - }, 30000);  
170 - };  
171 -  
172 - const handleLoadData = (record: CameraRecordItem) => {  
173 - const index = unref(cameraList).findIndex((item) => item.id === record.id);  
174 - ~index && (unref(cameraList).at(index)!.canPlay = true);  
175 - };  
176 -  
177 const [registerDrawer, { openDrawer }] = useDrawer(); 152 const [registerDrawer, { openDrawer }] = useDrawer();
178 153
179 const handleAddCamera = () => { 154 const handleAddCamera = () => {
@@ -264,24 +239,12 @@ @@ -264,24 +239,12 @@
264 v-if="!item.placeholder" 239 v-if="!item.placeholder"
265 class="bg-black w-full h-full overflow-hidden relative video-container" 240 class="bg-black w-full h-full overflow-hidden relative video-container"
266 > 241 >
267 - <Spin v-show="!item.isTransform" :spinning="!item.isTransform">  
268 - <div class="bg-black text-light-50"> </div>  
269 - </Spin>  
270 - <VideoPlay  
271 - v-show="item.isTransform"  
272 - @loadstart="handleLoadStart(item)"  
273 - @loadeddata="handleLoadData(item)"  
274 - v-bind="options"  
275 - :src="item.videoUrl"  
276 - :title="item.name"  
277 - :type="item.type" 242 + <Spin
  243 + class="!absolute top-1/2 left-1/2 transform -translate-1/2"
  244 + v-show="!item.isTransform"
  245 + :spinning="!item.isTransform"
278 /> 246 />
279 - <div  
280 - v-if="item.isTransform && isDef(item.canPlay) && !item.canPlay"  
281 - class="video-container-error-msk absolute top-0 left-0 text-lg w-full h-full text-light-50 flex justify-center items-center z-50 bg-black"  
282 - >  
283 - 视频加载出错了!  
284 - </div> 247 + <BasicVideoPlay v-if="item.isTransform" :options="item.videoPlayerOptions" />
285 <div 248 <div
286 class="video-container-mask absolute top-0 left-0 z-50 text-lg w-full text-light-50 flex justify-center items-center" 249 class="video-container-mask absolute top-0 left-0 z-50 text-lg w-full text-light-50 flex justify-center items-center"
287 style="height: 100%; background-color: rgba(0, 0, 0, 0.5)" 250 style="height: 100%; background-color: rgba(0, 0, 0, 0.5)"