Jelajahi Sumber

修复 VideoAudit.vue 中连续审核视频稿件时 内存与硬件解码器泄漏问题

reghao 3 hari lalu
induk
melakukan
170a71f5b5
1 mengubah file dengan 59 tambahan dan 27 penghapusan
  1. 59 27
      src/views/admin/aaa/VideoAudit.vue

+ 59 - 27
src/views/admin/aaa/VideoAudit.vue

@@ -10,6 +10,7 @@
         <div class="player-wrapper">
           <video
             ref="videoPlayer"
+            :key="currentVideo.videoId"
             :src="currentVideo.videoUrl"
             controls
             autoplay
@@ -186,15 +187,24 @@ export default {
       }
     }
   },
-  watch: {
-    $route() {
-      this.$router.go()
-    }
-  },
   created() {
     const videoId = this.$route.params.id
     this.fetchNextVideo(videoId)
   },
+  watch: {
+    // 🌟 【核心修复】当 URL 中的 videoId 发生变化时,优雅地清理并重新加载
+    '$route.params.id': {
+      handler(newVideoId) {
+        if (newVideoId) {
+          // 1. 先安全地把当前的播放器彻底断流、卸载,腾出硬件解码器空间
+          this.releaseVideoPlayer();
+          // 2. 传入新的 ID,重新请求后端数据
+          this.fetchNextVideo(newVideoId);
+        }
+      },
+      immediate: false // 首次进页面交给 created,后续切换交给 watch
+    }
+  },
   mounted() {
     // 全局监听键盘事件,开启极限盲审模式
     window.addEventListener('keydown', this.handleKeyboardShortcuts)
@@ -203,52 +213,74 @@ export default {
     window.removeEventListener('keydown', this.handleKeyboardShortcuts)
   },
   methods: {
+    releaseVideoPlayer() {
+      const player = this.$refs.videoPlayer;
+      if (player) {
+        try {
+          player.pause();
+          player.src = '';                  // 切断视频网络流
+          player.removeAttribute('src');    // 彻底移除资源属性
+          player.load();                    // 强制浏览器对该 DOM 节点触发垃圾回收
+        } catch (e) {
+          console.warn('释放播放器时发生异常:', e);
+        }
+      }
+    },
+    // 获取下一条待审核视频
     // 获取下一条待审核视频
     fetchNextVideo(videoId) {
-      this.loading = true
+      this.loading = true;
       // 重置表单状态
-      this.auditForm = { decision: null, reasonTags: [], remark: '' }
-      this.currentTime = 0
-      this.duration = 0
+      this.auditForm = { decision: null, reasonTags: [], remark: '' };
+      this.currentTime = 0;
+      this.duration = 0;
 
-      const queryParams = {}
-      queryParams.videoId = videoId
+      const queryParams = { videoId };
       getAuditVideo(queryParams).then(resp => {
         if (resp.code === 0) {
-          this.currentVideo = resp.data
-          this.auditForm.videoId = this.currentVideo.videoId
+          this.currentVideo = resp.data;
+          this.auditForm.videoId = this.currentVideo.videoId;
+
+          // 确保 DOM 渲染完新地址后,播放器干净利开跑
+          this.$nextTick(() => {
+            const player = this.$refs.videoPlayer;
+            if (player) player.load();
+          });
         } else {
-          this.$message.warning(resp.msg)
+          this.$message.warning(resp.msg);
         }
       }).finally(() => {
-        this.loading = false
-      })
+        this.loading = false;
+      });
     },
 
     // 提交审核决策
     submitAudit(status) {
-      this.auditForm.decision = status
+      this.auditForm.decision = status;
 
-      // 校验逻辑:如果不通过,必须选择至少一个违规标签或填写备注
       if (status === this.auditResult.REVIEW_REJECTED && this.auditForm.reasonTags.length === 0 && !this.auditForm.remark.trim()) {
-        this.$message.error('请选择违规标签或填写不通过的具体审核意见!')
-        return
+        this.$message.error('请选择违规标签或填写不通过的具体审核意见!');
+        return;
       }
 
-      this.submitting = true
+      this.submitting = true;
       submitAuditVideo(this.auditForm).then(resp => {
         if (resp.code === 0) {
-          var nextVideoId = resp.data
-          this.submitting = false
+          const nextVideoId = resp.data;
+          this.submitting = false;
           this.$notify({
             title: status === this.auditResult.PUBLISHED ? '审核通过' : '已驳回',
-            message: `视频 [${this.currentVideo.videoId}] 处理完毕,已自动加载下一条。`,
+            message: `视频 [${this.currentVideo.videoId}] 处理完毕,已自动加载下一条视频 [${nextVideoId}]。`,
             type: status === this.auditResult.PUBLISHED ? 'success' : 'warning',
             duration: 2500
-          })
-          this.$router.push('/vod_audit/' + nextVideoId)
+          });
+
+          // 🌟 这里正常 push。URL 会发生变化,从而触发上面的 '$route.params.id' 监听器
+          this.$router.push('/vod_audit/' + nextVideoId);
         }
-      })
+      }).catch(() => {
+        this.submitting = false;
+      });
     },
 
     // 播放器时间更新