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 | 26 | muted: true, |
| 27 | 27 | liveui: true, |
| 28 | 28 | controls: true, |
| 29 | + fluid: true, | |
| 29 | 30 | }; |
| 30 | 31 | return { ...defaultOptions, ...options }; |
| 31 | 32 | }); |
| ... | ... | @@ -57,7 +58,7 @@ |
| 57 | 58 | <div :class="prefixCls" class="w-full h-full" :style="getWidthHeight"> |
| 58 | 59 | <video |
| 59 | 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 | 62 | ></video> |
| 62 | 63 | </div> |
| 63 | 64 | </template> | ... | ... |
| ... | ... | @@ -5,21 +5,27 @@ |
| 5 | 5 | import { Spin, Button, Pagination, Space, List } from 'ant-design-vue'; |
| 6 | 6 | import { cameraPage } from '/@/api/camera/cameraManager'; |
| 7 | 7 | import { CameraRecord } from '/@/api/camera/model/cameraModel'; |
| 8 | - import { videoPlay as VideoPlay } from 'vue3-video-play'; | |
| 9 | 8 | import 'vue3-video-play/dist/style.css'; |
| 10 | 9 | import { useFullscreen } from '@vueuse/core'; |
| 11 | 10 | import CameraDrawer from './CameraDrawer.vue'; |
| 12 | 11 | import { useDrawer } from '/@/components/Drawer'; |
| 13 | - import { AccessMode, MediaType, PageMode } from './config.data'; | |
| 12 | + import { AccessMode, PageMode } from './config.data'; | |
| 14 | 13 | import SvgIcon from '/@/components/Icon/src/SvgIcon.vue'; |
| 15 | - import { isDef } from '/@/utils/is'; | |
| 16 | 14 | import { getStreamingPlayUrl } from '/@/api/camera/cameraManager'; |
| 17 | 15 | import { buildUUID } from '/@/utils/uuid'; |
| 16 | + import { BasicVideoPlay, getVideoTypeByUrl } from '/@/components/Video'; | |
| 17 | + import { VideoJsPlayerOptions } from 'video.js'; | |
| 18 | 18 | |
| 19 | 19 | type CameraRecordItem = CameraRecord & { |
| 20 | 20 | canPlay?: boolean; |
| 21 | - type?: string; | |
| 22 | 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 | 31 | const emit = defineEmits(['switchMode']); |
| ... | ... | @@ -36,32 +42,6 @@ |
| 36 | 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 | 46 | const handleSelect = (orgId: string) => { |
| 67 | 47 | organizationId.value = orgId; |
| ... | ... | @@ -80,7 +60,6 @@ |
| 80 | 60 | pagination.total = total; |
| 81 | 61 | |
| 82 | 62 | for (const item of items) { |
| 83 | - // await beforeVideoPlay(item); | |
| 84 | 63 | (item as CameraRecordItem).isTransform = false; |
| 85 | 64 | beforeVideoPlay(item); |
| 86 | 65 | } |
| ... | ... | @@ -91,36 +70,46 @@ |
| 91 | 70 | })); |
| 92 | 71 | items = [...items, ...fillArr]; |
| 93 | 72 | } |
| 73 | + console.log(items); | |
| 94 | 74 | cameraList.value = items; |
| 95 | 75 | } catch (error) { |
| 96 | 76 | } finally { |
| 97 | 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 | 81 | const beforeVideoPlay = async (record: CameraRecordItem) => { |
| 105 | - let reg = /(?:.*)(?<=\.)/; | |
| 106 | 82 | if (record.accessMode === AccessMode.ManuallyEnter) { |
| 107 | 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 | 93 | record.isTransform = true; |
| 111 | 94 | } |
| 112 | 95 | } |
| 113 | 96 | if (record.accessMode === AccessMode.Streaming) { |
| 114 | 97 | try { |
| 115 | 98 | const { data: { url } = { url: '' } } = await getStreamingPlayUrl(record.id!); |
| 116 | - const type = url.replace(reg, ''); | |
| 117 | 99 | const index = unref(cameraList).findIndex((item) => item.id === record.id); |
| 118 | 100 | if (~index) { |
| 119 | 101 | const oldRecord = unref(cameraList).at(index)!; |
| 120 | 102 | unref(cameraList)[index] = { |
| 121 | 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 | 113 | isTransform: true, |
| 125 | 114 | }; |
| 126 | 115 | } |
| ... | ... | @@ -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 | 152 | const [registerDrawer, { openDrawer }] = useDrawer(); |
| 178 | 153 | |
| 179 | 154 | const handleAddCamera = () => { |
| ... | ... | @@ -264,24 +239,12 @@ |
| 264 | 239 | v-if="!item.placeholder" |
| 265 | 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 | 248 | <div |
| 286 | 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 | 250 | style="height: 100%; background-color: rgba(0, 0, 0, 0.5)" | ... | ... |