Commit 6529af996f5bf4131426cdd9d21403303d742e74
1 parent
b7ab75dd
perf: use video.js refactor camera manage split mode
Showing
2 changed files
with
36 additions
and
72 deletions
@@ -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)" |