yusheng vor 14 Stunden
Ursprung
Commit
09a47aaa2e
2 geänderte Dateien mit 55 neuen und 3 gelöschten Zeilen
  1. 53 1
      src/utils/audioManager.js
  2. 2 2
      src/views/equipmentOperationMonitoring/index.vue

+ 53 - 1
src/utils/audioManager.js

@@ -11,6 +11,12 @@ class AudioManager {
 
     // 🎯 全局默认播放次数(你可以根据需要改为 1 或 3)
     this.defaultRepeatCount = 3; // 默认循环3次
+
+    // 被浏览器策略拦截后待重试的播放队列
+    this._pendingPlaybacks = [];
+
+    // 全局用户手势监听(用于重试被拦截的播放)
+    this._setupUserGestureRetry();
   }
 
   /**
@@ -26,6 +32,36 @@ class AudioManager {
     console.log('🛑 已停止所有音频');
   }
 
+  /**
+   * 恢复 AudioContext(绕过浏览器自动播放限制)
+   */
+  _resumeAudioContext() {
+    if (this._audioContext && this._audioContext.state === 'suspended') {
+      this._audioContext.resume().catch(() => {});
+    }
+  }
+
+  /**
+   * 设置用户手势后重试被拦截的播放
+   */
+  _setupUserGestureRetry() {
+    const retryAll = () => {
+      if (!this._pendingPlaybacks.length) return;
+      const tasks = [...this._pendingPlaybacks];
+      this._pendingPlaybacks = [];
+      tasks.forEach((fn) => fn());
+    };
+    const handler = () => {
+      retryAll();
+      document.removeEventListener('click', handler);
+      document.removeEventListener('touchstart', handler);
+      document.removeEventListener('keydown', handler);
+    };
+    document.addEventListener('click', handler, { once: true });
+    document.addEventListener('touchstart', handler, { once: true });
+    document.addEventListener('keydown', handler, { once: true });
+  }
+
   /**
    * 播放音频(自动停止之前的音频,并支持自定义重复次数)
    * @param {string} src - 音频文件路径
@@ -88,10 +124,18 @@ class AudioManager {
       onEnded,
     });
 
+    // 播放前先尝试恢复 AudioContext(绕过浏览器自动播放限制)
+    this._resumeAudioContext();
+
     // 开始播放
     audio.play().catch((err) => {
-      // 静音状态下一般不会报错,但若报错则忽略
+      // 被浏览器策略拦截时,保存到待播放队列,等下次用户交互时重试
       console.warn('音频播放失败(自动播放策略):', err);
+      if (err.name === 'NotAllowedError') {
+        this._pendingPlaybacks.push(() => {
+          audio.play().catch(() => {});
+        });
+      }
     });
 
     return audio;
@@ -108,6 +152,14 @@ class AudioManager {
     });
     sessionStorage.setItem('audioUnlocked', 'true');
     this.hasUnlockedBefore = true;
+
+    // 解锁后重试被拦截的播放
+    if (this._pendingPlaybacks.length) {
+      const tasks = [...this._pendingPlaybacks];
+      this._pendingPlaybacks = [];
+      tasks.forEach((fn) => fn());
+    }
+
     console.log('🔊 音频已解除静音');
   }
 

+ 2 - 2
src/views/equipmentOperationMonitoring/index.vue

@@ -969,8 +969,8 @@
 
           .alarm-badge {
             position: absolute;
-            top: 15px;
-            right: 130px;
+            top: 5px;
+            right:70px;
             display: flex;
             align-items: center;
             gap: 4px;