Commit cce054dc8eb63d825e5daeb353f581958d795570
Merge branch 'feat/device-new-protocol' of http://git.yunteng.com/yunteng/things…
…kit-front into feat/device-new-protocol
Showing
3 changed files
with
72 additions
and
132 deletions
1 | 1 | <script lang="ts" setup> |
2 | 2 | import { isNumber } from 'lodash'; |
3 | - import videoJs, { VideoJsPlayer, VideoJsPlayerOptions } from 'video.js'; | |
3 | + // import videoJs, { VideoJsPlayer, VideoJsPlayerOptions } from 'video.js'; | |
4 | 4 | import 'video.js/dist/video-js.css'; |
5 | - import { computed, CSSProperties, onMounted, onUnmounted, ref, unref } from 'vue'; | |
5 | + import { onMounted, onUnmounted, ref, unref } from 'vue'; | |
6 | 6 | import { useDesign } from '/@/hooks/web/useDesign'; |
7 | - import { getJwtToken, getShareJwtToken } from '/@/utils/auth'; | |
8 | - import { isShareMode } from '/@/views/sys/share/hook'; | |
7 | + // import { getJwtToken, getShareJwtToken } from '/@/utils/auth'; | |
8 | + // import { isShareMode } from '/@/views/sys/share/hook'; | |
9 | 9 | import 'videojs-flvjs-es6'; |
10 | 10 | import { |
11 | 11 | CaretUpOutlined, |
... | ... | @@ -18,73 +18,42 @@ |
18 | 18 | } from '@ant-design/icons-vue'; |
19 | 19 | import { Button } from 'ant-design-vue'; |
20 | 20 | import { nextTick } from 'vue'; |
21 | - import Jessibuca from '../types/jessibuca'; | |
21 | + import { useMessage } from '/@/hooks/web/useMessage'; | |
22 | + import Jessibuca from './types/jessibuca'; | |
22 | 23 | // import JessibucaDemo from './components/JessibucaDemo.vue'; |
23 | 24 | |
24 | 25 | const { prefixCls } = useDesign('basic-video-play'); |
25 | 26 | |
26 | - const props = defineProps<{ | |
27 | - options?: VideoJsPlayerOptions; | |
28 | - withToken?: boolean; | |
29 | - }>(); | |
27 | + // const props = defineProps<{ | |
28 | + // options?: VideoJsPlayerOptions; | |
29 | + // withToken?: boolean; | |
30 | + // }>(); | |
30 | 31 | |
31 | - const emit = defineEmits<{ | |
32 | - (event: 'ready', instance?: Nullable<VideoJsPlayer>): void; | |
33 | - (event: 'onUnmounted'): void; | |
34 | - }>(); | |
35 | - | |
36 | - const videoPlayEl = ref<HTMLVideoElement>(); | |
32 | + // const emit = defineEmits<{ | |
33 | + // (event: 'ready', instance?: Nullable<VideoJsPlayer>): void; | |
34 | + // (event: 'onUnmounted'): void; | |
35 | + // }>(); | |
37 | 36 | |
38 | 37 | const JessibucaRef = ref(); |
39 | 38 | |
40 | - const videoPlayInstance = ref<Nullable<VideoJsPlayer>>(); | |
41 | - | |
42 | - const getOptions = computed(() => { | |
43 | - const { options, withToken } = props; | |
44 | - | |
45 | - const defaultOptions: VideoJsPlayerOptions & Recordable = { | |
46 | - language: 'zh', | |
47 | - muted: true, | |
48 | - liveui: true, | |
49 | - controls: true, | |
50 | - techOrder: ['html5', 'flvjs'], | |
51 | - flvjs: { | |
52 | - mediaDataSource: { | |
53 | - isLive: true, | |
54 | - cors: true, | |
55 | - hasAudio: false, | |
56 | - withCredentials: false, | |
57 | - }, | |
58 | - config: { | |
59 | - headers: { | |
60 | - ...(withToken | |
61 | - ? { | |
62 | - 'X-Authorization': `Bearer ${isShareMode() ? getShareJwtToken() : getJwtToken()}`, | |
63 | - } | |
64 | - : {}), | |
65 | - }, | |
66 | - autoCleanupSourceBuffer: true, | |
67 | - }, | |
68 | - }, | |
69 | - }; | |
70 | - return videoJs.mergeOptions(defaultOptions, options); | |
71 | - }); | |
39 | + // const videoPlayInstance = ref<Nullable<VideoJsPlayer>>(); | |
72 | 40 | |
73 | 41 | const playUrl = ref('http://flv.bdplay.nodemedia.cn/live/bbb.flv'); |
74 | 42 | |
43 | + const { createMessage } = useMessage(); | |
44 | + | |
75 | 45 | let jessibuca: Jessibuca | null = null; |
76 | 46 | const container = ref(null); |
77 | 47 | const createJessibuca = () => { |
78 | 48 | jessibuca = new (window as any).Jessibuca({ |
79 | - container: container.value, | |
49 | + decoder: '/jessibuca/decoder.js', | |
50 | + container: container.value, //播放器容器 | |
80 | 51 | videoBuffer: 0.2, // 缓存时长 |
81 | 52 | isResize: true, |
82 | 53 | isFullResize: true, |
83 | 54 | text: '', |
84 | - debug: false, | |
85 | - // background: "bg.jpg", | |
86 | 55 | loadingText: '加载中', |
87 | - // hasAudio:false, | |
56 | + hasAudio: false, | |
88 | 57 | debug: true, |
89 | 58 | showBandwidth: true, // 显示网速 |
90 | 59 | operateBtns: { |
... | ... | @@ -93,32 +62,25 @@ |
93 | 62 | play: true, |
94 | 63 | audio: true, |
95 | 64 | }, |
96 | - controlAutoHide: true, | |
65 | + controlAutoHide: true, // 底部控制台是否自动隐藏 | |
97 | 66 | ifFlv: false, |
98 | - forceNoOffscreen: true, | |
99 | - isNotMute: false, | |
100 | - decoder: '/jessibuca/decoder.js', | |
67 | + forceNoOffscreen: true, //是否不使用离屏模式(提升渲染能力) | |
68 | + isNotMute: false, // 是否开启声音,默认是关闭声音播放的。 | |
101 | 69 | }) as Jessibuca; |
102 | 70 | }; |
103 | 71 | |
104 | - const getWidthHeight = computed(() => { | |
105 | - let { width = 640, height = 360 } = unref(getOptions); | |
106 | - width = isNumber(width) ? (`${width}px` as unknown as number) : width; | |
107 | - height = isNumber(height) ? (`${height}px` as unknown as number) : height; | |
108 | - return { width, height } as CSSProperties; | |
72 | + const videoInfo = ref<{ width: string | number; height: string | number }>({ | |
73 | + width: 640, | |
74 | + height: 360, | |
109 | 75 | }); |
110 | - | |
111 | - const init = () => { | |
112 | - if (unref(videoPlayInstance)) unref(videoPlayInstance)?.dispose(); | |
113 | - videoPlayInstance.value = videoJs(unref(videoPlayEl)!, unref(getOptions), () => { | |
114 | - emit('ready', unref(videoPlayInstance)); | |
115 | - }); | |
116 | - }; | |
117 | - //播放/暂停s | |
76 | + //播放/暂停 | |
118 | 77 | const handleClick = () => { |
119 | - console.log('播放/暂停'); | |
120 | - unref(isPlay) && unref(videoPlayInstance)?.pause(); | |
121 | - !unref(isPlay) && unref(videoPlayInstance)?.play(); | |
78 | + console.log('播放/暂停', unref(isPlay)); | |
79 | + if (unref(isPlay)) { | |
80 | + jessibuca?.pause(); | |
81 | + } else { | |
82 | + jessibuca?.play(); | |
83 | + } | |
122 | 84 | }; |
123 | 85 | |
124 | 86 | const handleTopClick = async () => { |
... | ... | @@ -153,89 +115,63 @@ |
153 | 115 | |
154 | 116 | const isPlay = ref<Boolean | null | undefined>(true); |
155 | 117 | |
156 | - // 播放 | |
157 | - // const play = () => { | |
158 | - // if (playUrl.value) { | |
159 | - // jessibuca?.play(playUrl.value); | |
160 | - // } | |
161 | - // }; | |
162 | - | |
163 | - // // 暂停 | |
164 | - // const pause = () => { | |
165 | - // jessibuca?.pause(); | |
166 | - // playing.value = false; | |
167 | - // }; | |
168 | - | |
169 | 118 | // // 关闭视频 |
170 | - // const destroy = () => { | |
171 | - // if (jessibuca) { | |
172 | - // jessibuca.destroy(); | |
173 | - // } | |
174 | - // createJessibuca(); | |
175 | - // playing.value = false; | |
176 | - // loaded.value = false; | |
177 | - // }; | |
119 | + const destroy = () => { | |
120 | + if (jessibuca) { | |
121 | + jessibuca.destroy(); | |
122 | + } | |
123 | + createJessibuca(); | |
124 | + isPlay.value = false; | |
125 | + }; | |
178 | 126 | |
179 | 127 | onMounted(async () => { |
180 | - // init(); | |
181 | - // await nextTick(); | |
182 | - // // isPlay.value = unref(videoPlayInstance)?.paused(); | |
183 | - // videoPlayInstance.value?.on('loadedmetadata', () => { | |
184 | - // console.log('视频长度'); | |
185 | - // }); | |
186 | - // videoPlayInstance.value?.on('waiting', () => { | |
187 | - // isPlay.value = false; | |
188 | - // console.log('视频加载中'); | |
189 | - // }); | |
190 | - // videoPlayInstance.value?.on('play', () => { | |
191 | - // isPlay.value = true; | |
192 | - // console.log('视频开始播放'); | |
193 | - // }); | |
194 | - // videoPlayInstance.value?.on('playing', () => { | |
195 | - // isPlay.value = true; | |
196 | - // console.log('正在播放'); | |
197 | - // }); | |
198 | - // videoPlayInstance.value?.on('pause', () => { | |
199 | - // isPlay.value = false; | |
200 | - // console.log('暂停播放'); | |
201 | - // }); | |
202 | - // videoPlayInstance.value?.on('ended', () => { | |
203 | - // isPlay.value = false; | |
204 | - // console.log('结束播放'); | |
205 | - // }); | |
206 | - | |
207 | 128 | createJessibuca(); |
208 | 129 | await nextTick(); |
209 | 130 | jessibuca?.play(playUrl.value); |
131 | + isPlay.value = jessibuca?.isPlaying(); | |
210 | 132 | |
211 | - jessibuca?.on('play', () => { | |
212 | - console.log('播放'); | |
133 | + // 是否播放 | |
134 | + jessibuca?.on('play', function () { | |
135 | + isPlay.value = true; | |
213 | 136 | }); |
214 | - jessibuca.on('pause', () => { | |
215 | - console.log('暂停'); | |
137 | + | |
138 | + // 是否暂停 | |
139 | + jessibuca?.on('pause', () => { | |
140 | + isPlay.value = false; | |
216 | 141 | }); |
217 | 142 | |
218 | 143 | jessibuca?.on('videoInfo', (data) => { |
219 | - console.log(data, 'data'); | |
144 | + let { width, height } = data || {}; | |
145 | + width = isNumber(width) ? (`${width}px` as unknown as number) : width; | |
146 | + height = isNumber(height) ? (`${height}px` as unknown as number) : height; | |
147 | + videoInfo.value = { | |
148 | + width, | |
149 | + height, | |
150 | + }; | |
151 | + }); | |
152 | + | |
153 | + // 播放报错事件 | |
154 | + jessibuca?.on('error', (error) => { | |
155 | + error == 'playError' && createMessage.warning('播放错误'); | |
156 | + error == 'fetchError' && createMessage.warning('http请求失败'); | |
157 | + error == 'websocketError' && createMessage.warning('websocket 请求失败'); | |
158 | + error == 'webcodecsH265NotSupport' && createMessage.warning('webcodecs 解码失败'); | |
159 | + error == 'mediaSourceH265NotSupport' && createMessage.warning('mediaSource 解码失败'); | |
160 | + error == 'wasmDecodeError' && createMessage.warning('wasm 解码失败'); | |
220 | 161 | }); |
221 | 162 | }); |
222 | 163 | |
223 | 164 | onUnmounted(() => { |
224 | - // unref(videoPlayInstance)?.dispose(); | |
225 | - // videoPlayInstance.value = null; | |
226 | - // emit('onUnmounted'); | |
227 | - | |
228 | 165 | jessibuca && jessibuca.destroy(); |
229 | 166 | }); |
230 | 167 | |
231 | 168 | defineExpose({ |
232 | - reloadPlayer: init, | |
233 | - getInstance: () => unref(videoPlayInstance), | |
169 | + handleDestroy: destroy, | |
234 | 170 | }); |
235 | 171 | </script> |
236 | 172 | |
237 | 173 | <template> |
238 | - <div :class="prefixCls" class="!w-full h-full flex" :style="getWidthHeight"> | |
174 | + <div :class="prefixCls" class="!w-full h-full flex" :style="videoInfo"> | |
239 | 175 | <!-- <video |
240 | 176 | ref="videoPlayEl" |
241 | 177 | class="video-js vjs-big-play-centered vjs-show-big-play-button-on-pause !w-8/10 !h-full" | ... | ... |
... | ... | @@ -13,6 +13,7 @@ |
13 | 13 | <div class="flex items-center justify-center w-full h-full min-h-96 video-container"> |
14 | 14 | <Video |
15 | 15 | v-if="showVideo" |
16 | + ref="jessibucaREF" | |
16 | 17 | :options="(options as any)" |
17 | 18 | :withToken="withToken" |
18 | 19 | @on-unmounted="handleCloseFlvPlayUrl" |
... | ... | @@ -41,6 +42,8 @@ |
41 | 42 | |
42 | 43 | const withToken = ref(false); |
43 | 44 | |
45 | + const jessibucaREF = ref(); | |
46 | + | |
44 | 47 | const fingerprintResult = ref<Nullable<GetResult>>(null); |
45 | 48 | |
46 | 49 | const options = reactive<VideoJsPlayerOptions>({ |
... | ... | @@ -92,6 +95,7 @@ |
92 | 95 | }; |
93 | 96 | |
94 | 97 | const handleCancel = () => { |
98 | + unref(jessibucaREF)?.handleDestroy(); | |
95 | 99 | showVideo.value = false; |
96 | 100 | withToken.value = false; |
97 | 101 | }; | ... | ... |