hookehuyr

refactor(VideoPlayer): 移除移动网络流量警告功能

清理不再需要的流量警告相关代码,包括组件模板、样式和逻辑
简化播放控制流程,直接使用原生播放方法
...@@ -38,17 +38,6 @@ ...@@ -38,17 +38,6 @@
38 </div> 38 </div>
39 </div> 39 </div>
40 40
41 - <div v-if="trafficWarnVisible && !showErrorOverlay" class="traffic-overlay">
42 - <div class="traffic-content">
43 - <div class="traffic-title">当前为移动网络</div>
44 - <div class="traffic-message">{{ `视频大小约:${trafficFileSizeText},注意流量消耗` }}</div>
45 - <div class="traffic-actions">
46 - <button class="traffic-cancel" @click="cancelTrafficWarn">取消</button>
47 - <button class="traffic-confirm" @click="confirmTrafficWarn">继续播放</button>
48 - </div>
49 - </div>
50 - </div>
51 -
52 <!-- 错误提示覆盖层 --> 41 <!-- 错误提示覆盖层 -->
53 <div v-if="showErrorOverlay" class="error-overlay"> 42 <div v-if="showErrorOverlay" class="error-overlay">
54 <div class="error-content"> 43 <div class="error-content">
...@@ -110,13 +99,9 @@ const { ...@@ -110,13 +99,9 @@ const {
110 errorMessage, 99 errorMessage,
111 showNetworkSpeedOverlay, 100 showNetworkSpeedOverlay,
112 networkSpeedText, 101 networkSpeedText,
113 - trafficWarnVisible,
114 - trafficFileSizeText,
115 - confirmTrafficWarn,
116 - cancelTrafficWarn,
117 - requestPlay,
118 retryLoad, 102 retryLoad,
119 handleVideoJsMounted, 103 handleVideoJsMounted,
104 + tryNativePlay
120 } = useVideoPlayer(props, emit, videoRef, nativeVideoRef); 105 } = useVideoPlayer(props, emit, videoRef, nativeVideoRef);
121 106
122 // 事件处理 107 // 事件处理
...@@ -149,10 +134,10 @@ defineExpose({ ...@@ -149,10 +134,10 @@ defineExpose({
149 }, 134 },
150 play() { 135 play() {
151 if (useNativePlayer.value) { 136 if (useNativePlayer.value) {
152 - void requestPlay(false); 137 + tryNativePlay();
153 return; 138 return;
154 } 139 }
155 - void requestPlay(false); 140 + player.value?.play()?.catch(console.warn);
156 }, 141 },
157 getPlayer() { 142 getPlayer() {
158 return useNativePlayer.value ? nativeVideoRef.value : player.value; 143 return useNativePlayer.value ? nativeVideoRef.value : player.value;
...@@ -248,70 +233,6 @@ defineExpose({ ...@@ -248,70 +233,6 @@ defineExpose({
248 opacity: 0.95; 233 opacity: 0.95;
249 } 234 }
250 235
251 -.traffic-overlay {
252 - position: absolute;
253 - top: 0;
254 - left: 0;
255 - right: 0;
256 - bottom: 0;
257 - display: flex;
258 - align-items: center;
259 - justify-content: center;
260 - z-index: 950;
261 - pointer-events: auto;
262 -}
263 -
264 -.traffic-content {
265 - padding: 16px 18px;
266 - border-radius: 12px;
267 - background: rgba(0, 0, 0, 0.75);
268 - backdrop-filter: blur(12px);
269 - color: #fff;
270 - text-align: center;
271 - max-width: 86%;
272 -}
273 -
274 -.traffic-title {
275 - font-size: 16px;
276 - font-weight: 600;
277 - line-height: 1.2;
278 - margin-bottom: 8px;
279 -}
280 -
281 -.traffic-message {
282 - font-size: 14px;
283 - line-height: 1.4;
284 - opacity: 0.95;
285 - margin-bottom: 14px;
286 -}
287 -
288 -.traffic-actions {
289 - display: flex;
290 - align-items: center;
291 - justify-content: center;
292 - gap: 12px;
293 -}
294 -
295 -.traffic-cancel,
296 -.traffic-confirm {
297 - border: none;
298 - padding: 10px 14px;
299 - border-radius: 10px;
300 - cursor: pointer;
301 - font-size: 14px;
302 - line-height: 1;
303 -}
304 -
305 -.traffic-cancel {
306 - background: rgba(255, 255, 255, 0.15);
307 - color: rgba(255, 255, 255, 0.95);
308 -}
309 -
310 -.traffic-confirm {
311 - background: #007bff;
312 - color: #fff;
313 -}
314 -
315 .retry-button { 236 .retry-button {
316 background: #007bff; 237 background: #007bff;
317 color: white; 238 color: white;
......
...@@ -34,11 +34,6 @@ export function useVideoPlayer(props, emit, videoRef, nativeVideoRef) { ...@@ -34,11 +34,6 @@ export function useVideoPlayer(props, emit, videoRef, nativeVideoRef) {
34 const hasEverPlayed = ref(false); 34 const hasEverPlayed = ref(false);
35 let networkSpeedTimer = null; 35 let networkSpeedTimer = null;
36 36
37 - const networkKind = ref('unknown');
38 - const trafficWarnVisible = ref(false);
39 - const trafficWarnAcknowledged = ref(false);
40 - let trafficWarnDuringAutoplay = false;
41 -
42 // 原生播放器状态 37 // 原生播放器状态
43 const nativeReady = ref(false); 38 const nativeReady = ref(false);
44 let nativeListeners = null; 39 let nativeListeners = null;
...@@ -105,12 +100,6 @@ export function useVideoPlayer(props, emit, videoRef, nativeVideoRef) { ...@@ -105,12 +100,6 @@ export function useVideoPlayer(props, emit, videoRef, nativeVideoRef) {
105 return String(size) + "B"; 100 return String(size) + "B";
106 }; 101 };
107 102
108 - const trafficFileSizeText = computed(() => {
109 - const len = probeInfo.value.content_length;
110 - if (!len) return "未知";
111 - return formatBytes(len) || "未知";
112 - });
113 -
114 const getErrorHint = () => { 103 const getErrorHint = () => {
115 if (probeInfo.value.status === 403) return "(403:无权限或已过期)"; 104 if (probeInfo.value.status === 403) return "(403:无权限或已过期)";
116 if (probeInfo.value.status === 404) return "(404:资源不存在)"; 105 if (probeInfo.value.status === 404) return "(404:资源不存在)";
...@@ -124,52 +113,6 @@ export function useVideoPlayer(props, emit, videoRef, nativeVideoRef) { ...@@ -124,52 +113,6 @@ export function useVideoPlayer(props, emit, videoRef, nativeVideoRef) {
124 return ""; 113 return "";
125 }; 114 };
126 115
127 - const detectNetworkKind = async () => {
128 - if (typeof navigator === 'undefined') {
129 - networkKind.value = 'unknown';
130 - return;
131 - }
132 -
133 - const connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
134 - const connectionType = connection && typeof connection.type === 'string' ? connection.type : '';
135 - if (connectionType) {
136 - if (connectionType === 'wifi') {
137 - networkKind.value = 'wifi';
138 - return;
139 - }
140 - if (connectionType === 'cellular') {
141 - networkKind.value = 'cellular';
142 - return;
143 - }
144 - }
145 -
146 - const effectiveType = connection && typeof connection.effectiveType === 'string' ? connection.effectiveType : '';
147 - if (effectiveType) {
148 - if (effectiveType === '4g' || effectiveType === '3g' || effectiveType === '2g' || effectiveType === 'slow-2g') {
149 - networkKind.value = 'cellular';
150 - return;
151 - }
152 - }
153 -
154 - if (typeof window !== 'undefined' && window.WeixinJSBridge) {
155 - await new Promise((resolve) => {
156 - try {
157 - window.WeixinJSBridge.invoke('getNetworkType', {}, (res) => {
158 - const wxType = (res && (res.networkType || res.err_msg || '')).toString().toLowerCase();
159 - if (wxType.includes('wifi')) networkKind.value = 'wifi';
160 - else if (wxType.includes('2g') || wxType.includes('3g') || wxType.includes('4g') || wxType.includes('5g')) networkKind.value = 'cellular';
161 - resolve();
162 - });
163 - } catch (e) {
164 - resolve();
165 - }
166 - });
167 - return;
168 - }
169 -
170 - networkKind.value = 'unknown';
171 - };
172 -
173 // 资源探测 116 // 资源探测
174 const probeVideo = async () => { 117 const probeVideo = async () => {
175 const url = videoUrlValue.value; 118 const url = videoUrlValue.value;
...@@ -239,7 +182,6 @@ export function useVideoPlayer(props, emit, videoRef, nativeVideoRef) { ...@@ -239,7 +182,6 @@ export function useVideoPlayer(props, emit, videoRef, nativeVideoRef) {
239 const handleError = (code, message = '') => { 182 const handleError = (code, message = '') => {
240 showErrorOverlay.value = true; 183 showErrorOverlay.value = true;
241 showNetworkSpeedOverlay.value = false; 184 showNetworkSpeedOverlay.value = false;
242 - trafficWarnVisible.value = false;
243 if (networkSpeedTimer) { 185 if (networkSpeedTimer) {
244 clearInterval(networkSpeedTimer); 186 clearInterval(networkSpeedTimer);
245 networkSpeedTimer = null; 187 networkSpeedTimer = null;
...@@ -288,7 +230,6 @@ export function useVideoPlayer(props, emit, videoRef, nativeVideoRef) { ...@@ -288,7 +230,6 @@ export function useVideoPlayer(props, emit, videoRef, nativeVideoRef) {
288 const showNetworkSpeed = () => { 230 const showNetworkSpeed = () => {
289 if (!hasEverPlayed.value) return; 231 if (!hasEverPlayed.value) return;
290 if (showErrorOverlay.value) return; 232 if (showErrorOverlay.value) return;
291 - if (trafficWarnVisible.value) return;
292 if (showNetworkSpeedOverlay.value) return; 233 if (showNetworkSpeedOverlay.value) return;
293 234
294 showNetworkSpeedOverlay.value = true; 235 showNetworkSpeedOverlay.value = true;
...@@ -308,63 +249,6 @@ export function useVideoPlayer(props, emit, videoRef, nativeVideoRef) { ...@@ -308,63 +249,6 @@ export function useVideoPlayer(props, emit, videoRef, nativeVideoRef) {
308 } 249 }
309 }; 250 };
310 251
311 - const isOnWifi = computed(() => networkKind.value === 'wifi');
312 - const isOnCellular = computed(() => networkKind.value === 'cellular');
313 -
314 - // 8. 流量警告逻辑
315 - const trafficWarnThresholdBytes = 1000 * 1024 * 1024;
316 -
317 - const needTrafficWarn = computed(() => {
318 - if (isOnWifi.value) return false;
319 - if (!isOnCellular.value) return false;
320 - const len = probeInfo.value.content_length;
321 - if (!len) return false;
322 - return len >= trafficWarnThresholdBytes;
323 - });
324 -
325 - const openTrafficWarn = async (fromAutoplay) => {
326 - if (trafficWarnAcknowledged.value) return false;
327 - trafficWarnDuringAutoplay = Boolean(fromAutoplay);
328 -
329 - if (!probeInfo.value.content_length && !probeLoading.value) {
330 - await probeVideo();
331 - }
332 -
333 - if (!needTrafficWarn.value) return false;
334 - trafficWarnVisible.value = true;
335 - hideNetworkSpeed();
336 - return true;
337 - };
338 -
339 - const closeTrafficWarn = () => {
340 - trafficWarnVisible.value = false;
341 - trafficWarnDuringAutoplay = false;
342 - };
343 -
344 - const requestPlay = async (fromAutoplay) => {
345 - const blocked = await openTrafficWarn(fromAutoplay);
346 - if (blocked) return;
347 -
348 - if (useNativePlayer.value) {
349 - tryNativePlay();
350 - return;
351 - }
352 -
353 - if (player.value && !player.value.isDisposed()) {
354 - player.value.play().catch(console.warn);
355 - }
356 - };
357 -
358 - const confirmTrafficWarn = () => {
359 - trafficWarnAcknowledged.value = true;
360 - closeTrafficWarn();
361 - void requestPlay(trafficWarnDuringAutoplay);
362 - };
363 -
364 - const cancelTrafficWarn = () => {
365 - closeTrafficWarn();
366 - };
367 -
368 // 4. 原生播放器逻辑 (iOS微信) 252 // 4. 原生播放器逻辑 (iOS微信)
369 const initNativePlayer = () => { 253 const initNativePlayer = () => {
370 const videoEl = nativeVideoRef.value; 254 const videoEl = nativeVideoRef.value;
...@@ -394,28 +278,6 @@ export function useVideoPlayer(props, emit, videoRef, nativeVideoRef) { ...@@ -394,28 +278,6 @@ export function useVideoPlayer(props, emit, videoRef, nativeVideoRef) {
394 }; 278 };
395 279
396 const onPlay = () => { 280 const onPlay = () => {
397 - if (!trafficWarnAcknowledged.value) {
398 - if (!probeInfo.value.content_length && isOnCellular.value) {
399 - try {
400 - videoEl.pause();
401 - } catch (e) {
402 - void e;
403 - }
404 - void requestPlay(false);
405 - return;
406 - }
407 -
408 - if (needTrafficWarn.value) {
409 - try {
410 - videoEl.pause();
411 - } catch (e) {
412 - void e;
413 - }
414 - trafficWarnVisible.value = true;
415 - hideNetworkSpeed();
416 - return;
417 - }
418 - }
419 hasEverPlayed.value = true; 281 hasEverPlayed.value = true;
420 hideNetworkSpeed(); 282 hideNetworkSpeed();
421 }; 283 };
...@@ -460,11 +322,11 @@ export function useVideoPlayer(props, emit, videoRef, nativeVideoRef) { ...@@ -460,11 +322,11 @@ export function useVideoPlayer(props, emit, videoRef, nativeVideoRef) {
460 }; 322 };
461 323
462 if (props.autoplay) { 324 if (props.autoplay) {
463 - void requestPlay(true); 325 + tryNativePlay();
464 if (typeof document !== "undefined") { 326 if (typeof document !== "undefined") {
465 document.addEventListener( 327 document.addEventListener(
466 "WeixinJSBridgeReady", 328 "WeixinJSBridgeReady",
467 - () => void requestPlay(true), 329 + () => tryNativePlay(),
468 { once: true } 330 { once: true }
469 ); 331 );
470 } 332 }
...@@ -553,20 +415,6 @@ export function useVideoPlayer(props, emit, videoRef, nativeVideoRef) { ...@@ -553,20 +415,6 @@ export function useVideoPlayer(props, emit, videoRef, nativeVideoRef) {
553 }); 415 });
554 416
555 player.value.on('play', () => { 417 player.value.on('play', () => {
556 - if (!trafficWarnAcknowledged.value) {
557 - if (!probeInfo.value.content_length && isOnCellular.value) {
558 - player.value.pause();
559 - void requestPlay(false);
560 - return;
561 - }
562 -
563 - if (needTrafficWarn.value) {
564 - player.value.pause();
565 - trafficWarnVisible.value = true;
566 - hideNetworkSpeed();
567 - return;
568 - }
569 - }
570 hasEverPlayed.value = true; 418 hasEverPlayed.value = true;
571 hideNetworkSpeed(); 419 hideNetworkSpeed();
572 }); 420 });
...@@ -592,7 +440,7 @@ export function useVideoPlayer(props, emit, videoRef, nativeVideoRef) { ...@@ -592,7 +440,7 @@ export function useVideoPlayer(props, emit, videoRef, nativeVideoRef) {
592 }); 440 });
593 441
594 if (props.autoplay) { 442 if (props.autoplay) {
595 - void requestPlay(true); 443 + player.value.play().catch(console.warn);
596 } 444 }
597 } 445 }
598 }; 446 };
...@@ -607,7 +455,6 @@ export function useVideoPlayer(props, emit, videoRef, nativeVideoRef) { ...@@ -607,7 +455,6 @@ export function useVideoPlayer(props, emit, videoRef, nativeVideoRef) {
607 retryCount.value++; 455 retryCount.value++;
608 showErrorOverlay.value = false; 456 showErrorOverlay.value = false;
609 hideNetworkSpeed(); 457 hideNetworkSpeed();
610 - closeTrafficWarn();
611 458
612 if (useNativePlayer.value) { 459 if (useNativePlayer.value) {
613 const videoEl = nativeVideoRef.value; 460 const videoEl = nativeVideoRef.value;
...@@ -634,8 +481,6 @@ export function useVideoPlayer(props, emit, videoRef, nativeVideoRef) { ...@@ -634,8 +481,6 @@ export function useVideoPlayer(props, emit, videoRef, nativeVideoRef) {
634 showErrorOverlay.value = false; 481 showErrorOverlay.value = false;
635 hideNetworkSpeed(); 482 hideNetworkSpeed();
636 hasEverPlayed.value = false; 483 hasEverPlayed.value = false;
637 - trafficWarnAcknowledged.value = false;
638 - closeTrafficWarn();
639 void probeVideo(); 484 void probeVideo();
640 485
641 // 如果是原生播放器且 URL 变化,需要手动处理 HLS (如果是非 iOS Safari 环境) 486 // 如果是原生播放器且 URL 变化,需要手动处理 HLS (如果是非 iOS Safari 环境)
...@@ -646,7 +491,6 @@ export function useVideoPlayer(props, emit, videoRef, nativeVideoRef) { ...@@ -646,7 +491,6 @@ export function useVideoPlayer(props, emit, videoRef, nativeVideoRef) {
646 }); 491 });
647 492
648 onMounted(() => { 493 onMounted(() => {
649 - void detectNetworkKind();
650 void probeVideo(); 494 void probeVideo();
651 if (useNativePlayer.value) { 495 if (useNativePlayer.value) {
652 initNativePlayer(); 496 initNativePlayer();
...@@ -670,7 +514,6 @@ export function useVideoPlayer(props, emit, videoRef, nativeVideoRef) { ...@@ -670,7 +514,6 @@ export function useVideoPlayer(props, emit, videoRef, nativeVideoRef) {
670 } 514 }
671 515
672 hideNetworkSpeed(); 516 hideNetworkSpeed();
673 - closeTrafficWarn();
674 if (videoRef.value?.$player) { 517 if (videoRef.value?.$player) {
675 videoRef.value.$player.dispose(); 518 videoRef.value.$player.dispose();
676 } 519 }
...@@ -686,13 +529,6 @@ export function useVideoPlayer(props, emit, videoRef, nativeVideoRef) { ...@@ -686,13 +529,6 @@ export function useVideoPlayer(props, emit, videoRef, nativeVideoRef) {
686 errorMessage, 529 errorMessage,
687 showNetworkSpeedOverlay, 530 showNetworkSpeedOverlay,
688 networkSpeedText, 531 networkSpeedText,
689 - trafficWarnVisible,
690 - trafficFileSizeText,
691 - isOnWifi,
692 - isOnCellular,
693 - confirmTrafficWarn,
694 - cancelTrafficWarn,
695 - requestPlay,
696 retryLoad, 532 retryLoad,
697 handleVideoJsMounted, 533 handleVideoJsMounted,
698 tryNativePlay 534 tryNativePlay
......