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)" |