130 lines
4.2 KiB
Markdown
130 lines
4.2 KiB
Markdown
|
|
# 视频播放器缓冲遮罩问题修复指南
|
|||
|
|
|
|||
|
|
## 问题描述
|
|||
|
|
视频已经在播放(有 timeupdate 事件),但缓冲遮罩一直显示,遮挡视频内容。
|
|||
|
|
|
|||
|
|
## 需要修改的3个地方
|
|||
|
|
|
|||
|
|
### 1. 修改 `showLoadingOverlay` 计算属性(约第72-80行)
|
|||
|
|
|
|||
|
|
**找到:**
|
|||
|
|
```javascript
|
|||
|
|
showLoadingOverlay() {
|
|||
|
|
if (!this.localVideoPath) return true;
|
|||
|
|
if (this.userPaused && !this.videoHasStarted && !this.isVideoDownloading && !this.videoWaiting) return false;
|
|||
|
|
if (this.isVideoDownloading && !this.videoHasStarted) return true;
|
|||
|
|
if (!this.videoHasStarted) return true;
|
|||
|
|
if (this.videoWaiting) return true;
|
|||
|
|
return false;
|
|||
|
|
},
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**改为:**
|
|||
|
|
```javascript
|
|||
|
|
showLoadingOverlay() {
|
|||
|
|
if (!this.localVideoPath) return true;
|
|||
|
|
if (this.userPaused && !this.videoHasStarted && !this.isVideoDownloading && !this.videoWaiting) return false;
|
|||
|
|
if (this.isVideoDownloading && !this.videoHasStarted) return true;
|
|||
|
|
if (!this.videoHasStarted) return true;
|
|||
|
|
// 视频已经在播放且有正常的 timeupdate,不显示加载遮罩
|
|||
|
|
if (this.isVideoPlaying && this.lastVideoTime > 0) return false;
|
|||
|
|
if (this.videoWaiting) return true;
|
|||
|
|
return false;
|
|||
|
|
},
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. 修改 `onVideoWaiting` 方法(约第1145行)
|
|||
|
|
|
|||
|
|
**在方法开头添加:**
|
|||
|
|
```javascript
|
|||
|
|
onVideoWaiting() {
|
|||
|
|
// 如果视频已经在正常播放(有持续的 timeupdate),忽略偶发的 waiting 事件
|
|||
|
|
const now = Date.now();
|
|||
|
|
if (this.isVideoPlaying && this.lastVideoTimeUpdateAt && (now - this.lastVideoTimeUpdateAt) < 500) {
|
|||
|
|
console.log('[VideoPlayer] 视频正在播放中,忽略偶发 waiting 事件');
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
this.videoWaiting = true;
|
|||
|
|
// ... 保持其余代码不变
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. 修改 `onTimeUpdate` 方法(约第1210行)
|
|||
|
|
|
|||
|
|
**找到:**
|
|||
|
|
```javascript
|
|||
|
|
onTimeUpdate(e) {
|
|||
|
|
if (!e || !e.detail) return;
|
|||
|
|
const currentTime = e.detail.currentTime;
|
|||
|
|
this.lastVideoTime = currentTime;
|
|||
|
|
this.lastVideoTimeUpdateAt = Date.now();
|
|||
|
|
if (this.videoWaiting) {
|
|||
|
|
this.videoWaiting = false;
|
|||
|
|
this.waitingNeedsUserAction = false;
|
|||
|
|
}
|
|||
|
|
// ... 其余代码
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**改为:**
|
|||
|
|
```javascript
|
|||
|
|
onTimeUpdate(e) {
|
|||
|
|
if (!e || !e.detail) return;
|
|||
|
|
const currentTime = e.detail.currentTime;
|
|||
|
|
this.lastVideoTime = currentTime;
|
|||
|
|
this.lastVideoTimeUpdateAt = Date.now();
|
|||
|
|
|
|||
|
|
// 视频正常播放中,清除所有等待状态
|
|||
|
|
if (this.videoWaiting) {
|
|||
|
|
console.log('[VideoPlayer] timeupdate 清除 waiting 状态,currentTime=', currentTime);
|
|||
|
|
this.videoWaiting = false;
|
|||
|
|
this.waitingNeedsUserAction = false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 清除 waiting 定时器
|
|||
|
|
if (this.waitingTimer) {
|
|||
|
|
clearTimeout(this.waitingTimer);
|
|||
|
|
this.waitingTimer = null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 确保播放状态正确
|
|||
|
|
if (!this.isVideoPlaying && !this.userPaused) {
|
|||
|
|
this.isVideoPlaying = true;
|
|||
|
|
}
|
|||
|
|
// ... 保持其余代码不变
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 4. 修改 `onVideoPlay` 方法(约第1060行)
|
|||
|
|
|
|||
|
|
**在方法开头添加清除 waiting 定时器的代码:**
|
|||
|
|
```javascript
|
|||
|
|
onVideoPlay() {
|
|||
|
|
console.log('[VideoPlayer] 视频开始播放');
|
|||
|
|
if (this.appNetworkFallbackTimer) {
|
|||
|
|
clearTimeout(this.appNetworkFallbackTimer);
|
|||
|
|
this.appNetworkFallbackTimer = null;
|
|||
|
|
}
|
|||
|
|
this.waitingNeedsUserAction = false;
|
|||
|
|
|
|||
|
|
// 清除 waiting 定时器
|
|||
|
|
if (this.waitingTimer) {
|
|||
|
|
clearTimeout(this.waitingTimer);
|
|||
|
|
this.waitingTimer = null;
|
|||
|
|
}
|
|||
|
|
// ... 保持其余代码不变
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 修复原理
|
|||
|
|
|
|||
|
|
1. **优先级判断**:在 `showLoadingOverlay` 中,如果视频已经在播放且有正常的时间更新,直接返回 false,不显示遮罩
|
|||
|
|
2. **忽略偶发事件**:在 `onVideoWaiting` 中,如果视频正在正常播放(最近500ms内有 timeupdate),忽略偶发的 waiting 事件
|
|||
|
|
3. **及时清除状态**:在 `onTimeUpdate` 中,一旦收到时间更新,立即清除 waiting 状态和定时器
|
|||
|
|
4. **状态同步**:确保 `isVideoPlaying` 状态与实际播放状态保持同步
|
|||
|
|
|
|||
|
|
## 测试验证
|
|||
|
|
|
|||
|
|
修改后,测试以下场景:
|
|||
|
|
- ✅ 视频正常播放时不应显示缓冲遮罩
|
|||
|
|
- ✅ 真正缓冲时应显示遮罩
|
|||
|
|
- ✅ 首次加载时应显示遮罩
|
|||
|
|
- ✅ 下载进度应正常显示
|