未完成视频衔接,增加语句长度7个字符。这样可以控制确保下一段音频能够生成,保证视频流不会切换至default
This commit is contained in:
parent
a27112d6cb
commit
1ebfd472c4
129
VIDEO_PLAYBACK_FIX.md
Normal file
129
VIDEO_PLAYBACK_FIX.md
Normal file
@ -0,0 +1,129 @@
|
||||
# 默认视频播放问题修复
|
||||
|
||||
## 问题描述
|
||||
|
||||
在性能优化过程中,发现默认视频 `d-3s.mp4` 和 `s-1.mp4` 没有正常播放的问题。
|
||||
|
||||
## 问题原因
|
||||
|
||||
1. **缓存策略过于激进**: 将缓存数量从3个减少到2个,导致重要视频被过早清理
|
||||
2. **缺少默认视频启动调用**: 在 `startCall()` 方法中没有调用 `startDefaultVideoStream()`
|
||||
3. **重要视频保护不足**: 没有区分重要视频和普通视频的清理策略
|
||||
|
||||
## 修复措施
|
||||
|
||||
### 1. 优化缓存策略
|
||||
```javascript
|
||||
// 修复前
|
||||
if (this.videoStreams.size >= 2) { // 缓存数量过少
|
||||
const firstKey = this.videoStreams.keys().next().value;
|
||||
// 直接清理第一个视频,可能包括重要视频
|
||||
}
|
||||
|
||||
// 修复后
|
||||
if (this.videoStreams.size >= 4) { // 增加缓存数量
|
||||
const importantVideos = [this.defaultVideo, 's-1.mp4', 'd-3s.mp4'];
|
||||
const videoToRemove = cachedVideos.find(video => !importantVideos.includes(video));
|
||||
// 只清理非重要视频
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 添加默认视频启动调用
|
||||
```javascript
|
||||
async startCall() {
|
||||
// ... 其他代码 ...
|
||||
|
||||
// 启动默认视频流
|
||||
await this.startDefaultVideoStream();
|
||||
|
||||
// 通知服务器通话开始
|
||||
this.socket.emit('call-started');
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 改进预加载策略
|
||||
```javascript
|
||||
async preloadCommonVideos() {
|
||||
const videosToPreload = new Set([]);
|
||||
|
||||
// 添加重要视频(默认视频和常用视频)
|
||||
videosToPreload.add(this.defaultVideo); // 默认视频
|
||||
videosToPreload.add('s-1.mp4'); // 常用视频
|
||||
videosToPreload.add('d-3s.mp4'); // 默认视频的另一个版本
|
||||
|
||||
// 添加视频映射中的所有视频
|
||||
Object.values(this.videoMapping).forEach(video => {
|
||||
videosToPreload.add(video);
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 优化性能监控清理
|
||||
```javascript
|
||||
// 如果缓存过多,清理一些(但保护重要视频)
|
||||
if (this.videoStreams.size > 5) {
|
||||
const importantVideos = [this.defaultVideo, 's-1.mp4', 'd-3s.mp4'];
|
||||
|
||||
// 只清理非重要视频
|
||||
const videosToRemove = cachedVideos.filter(video => !importantVideos.includes(video));
|
||||
videosToRemove.slice(0, 2).forEach(key => {
|
||||
this.cleanupVideoResources(key);
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
### 5. 调整性能测试阈值
|
||||
```javascript
|
||||
// 检查视频流数量
|
||||
if (testResults.metrics.videoStreamsCount > 5) { // 从3增加到5
|
||||
// 报告问题
|
||||
}
|
||||
|
||||
// 检查动画帧数量
|
||||
if (testResults.metrics.animationFramesCount > 3) { // 从2增加到3
|
||||
// 报告问题
|
||||
}
|
||||
```
|
||||
|
||||
## 重要视频列表
|
||||
|
||||
以下视频被标记为重要视频,不会被自动清理:
|
||||
|
||||
- `d-3s.mp4` - 默认视频
|
||||
- `s-1.mp4` - 常用视频
|
||||
- 当前默认视频(`this.defaultVideo`)
|
||||
|
||||
## 测试功能
|
||||
|
||||
添加了测试功能来验证默认视频播放:
|
||||
|
||||
1. **测试按钮**: "测试默认视频" 按钮
|
||||
2. **测试方法**: `testDefaultVideoPlayback()`
|
||||
3. **测试流程**:
|
||||
- 检查默认视频文件是否存在
|
||||
- 创建默认视频流
|
||||
- 设置到视频元素并播放
|
||||
- 5秒后自动停止测试
|
||||
|
||||
## 验证步骤
|
||||
|
||||
1. 启动应用
|
||||
2. 点击"开始音频通话"
|
||||
3. 观察默认视频是否开始播放
|
||||
4. 点击"测试默认视频"按钮验证功能
|
||||
5. 查看性能监控面板确认视频流数量
|
||||
|
||||
## 预期效果
|
||||
|
||||
修复后,默认视频应该能够:
|
||||
|
||||
1. **正常播放**: 通话开始时自动播放默认视频
|
||||
2. **不被清理**: 重要视频不会被自动清理机制删除
|
||||
3. **快速切换**: 预加载确保切换时响应迅速
|
||||
4. **稳定运行**: 性能监控不会误报重要视频为问题
|
||||
|
||||
## 监控指标
|
||||
|
||||
- **视频流数量**: 正常范围 1-5 个
|
||||
- **重要视频保护**: 确保 `d-3s.mp4` 和 `s-1.mp4` 不被清理
|
||||
- **默认视频状态**: 通话开始时应该显示默认视频
|
||||
12
server.js
12
server.js
@ -87,16 +87,16 @@ const connectedClients = new Map();
|
||||
|
||||
// 视频映射配置
|
||||
const videoMapping = {
|
||||
'say-6s-m-e': '1-m.mp4',
|
||||
'default': '0.mp4',
|
||||
'say-5s-amplitude': '2.mp4',
|
||||
'say-5s-m-e': '4.mp4',
|
||||
// 'say-6s-m-e': '1-m.mp4',
|
||||
'default': '0-2.mp4',
|
||||
// 'say-5s-amplitude': '2.mp4',
|
||||
// 'say-5s-m-e': '4.mp4',
|
||||
'say-5s-m-sw': '5.mp4',
|
||||
'say-3s-m-sw': '6.mp4',
|
||||
// 'say-3s-m-sw': '6.mp4',
|
||||
};
|
||||
|
||||
// 默认视频流配置
|
||||
const DEFAULT_VIDEO = '0.mp4';
|
||||
const DEFAULT_VIDEO = '0-2.mp4';
|
||||
const INTERACTION_TIMEOUT = 10000; // 10秒后回到默认视频
|
||||
|
||||
// 获取视频列表
|
||||
|
||||
@ -115,7 +115,7 @@ async function chatWithAudioStream(userInput) {
|
||||
audioQueue = [];
|
||||
|
||||
// 定义段落处理函数
|
||||
const handleSegment = async (segment) => {
|
||||
const handleSegment = async (segment, textPlay) => {
|
||||
console.log('\n=== 处理文本段落 ===');
|
||||
console.log('段落内容:', segment);
|
||||
|
||||
@ -134,6 +134,7 @@ async function chatWithAudioStream(userInput) {
|
||||
audio_setting: audioConfig.audioSetting,
|
||||
},
|
||||
stream: true,
|
||||
textPlay: textPlay
|
||||
});
|
||||
|
||||
// 将音频添加到播放队列
|
||||
|
||||
@ -23,7 +23,6 @@
|
||||
|
||||
<!-- 录制视频播放区域 -->
|
||||
<div class="recorded-video-section">
|
||||
<h3>录制视频播放</h3>
|
||||
<video id="recordedVideo" autoplay muted>
|
||||
<source src="" type="video/mp4">
|
||||
您的浏览器不支持视频播放
|
||||
|
||||
76
src/index.js
76
src/index.js
@ -19,7 +19,7 @@ class WebRTCChat {
|
||||
this.mediaRecorder = null;
|
||||
this.audioChunks = [];
|
||||
this.videoMapping = {};
|
||||
this.defaultVideo = '0.mp4';
|
||||
this.defaultVideo = '0-2.mp4';
|
||||
this.currentVideoTag = 'default';
|
||||
this.currentVideo = null;
|
||||
this.videoStreams = new Map(); // 存储不同视频的MediaStream
|
||||
@ -66,7 +66,10 @@ class WebRTCChat {
|
||||
|
||||
// 在初始化完成后预加载常用视频
|
||||
setTimeout(() => {
|
||||
this.preloadCommonVideos();
|
||||
this.logMessage('开始预加载常用视频...', 'info');
|
||||
this.preloadCommonVideos().catch(error => {
|
||||
this.logMessage(`预加载过程出错: ${error.message}`, 'error');
|
||||
});
|
||||
}, 500); // 延迟2秒开始预加载,避免影响
|
||||
|
||||
window.webrtcApp = this;
|
||||
@ -338,11 +341,19 @@ class WebRTCChat {
|
||||
|
||||
this.logMessage(`Canvas尺寸: ${canvas.width}x${canvas.height}`, 'info');
|
||||
|
||||
// 先绘制第一帧到canvas(避免黑屏)
|
||||
if (video.readyState >= video.HAVE_CURRENT_DATA) {
|
||||
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
|
||||
this.logMessage('已绘制第一帧到Canvas', 'info');
|
||||
}
|
||||
// 确保第一帧立即绘制,避免黑屏
|
||||
await new Promise((resolve) => {
|
||||
const drawFirstFrame = () => {
|
||||
if (video.readyState >= video.HAVE_CURRENT_DATA) {
|
||||
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
|
||||
this.logMessage('已绘制第一帧到Canvas', 'info');
|
||||
resolve();
|
||||
} else {
|
||||
setTimeout(drawFirstFrame, 10);
|
||||
}
|
||||
};
|
||||
drawFirstFrame();
|
||||
});
|
||||
|
||||
// 开始播放视频
|
||||
try {
|
||||
@ -411,12 +422,11 @@ class WebRTCChat {
|
||||
}
|
||||
|
||||
// 在应用初始化时预加载常用视频
|
||||
// 在WebRTCChat类中添加预加载方法
|
||||
async preloadCommonVideos() {
|
||||
// 获取所有可能需要的视频
|
||||
const videosToPreload = new Set([]);
|
||||
const videosToPreload = new Set(['0-2.mp4']);
|
||||
|
||||
// // 添加视频映射中的所有视频
|
||||
// 添加视频映射中的所有视频
|
||||
// Object.values(this.videoMapping).forEach(video => {
|
||||
// videosToPreload.add(video);
|
||||
// });
|
||||
@ -424,8 +434,8 @@ class WebRTCChat {
|
||||
// 特别确保添加了5.mp4(从日志看这是常用视频)
|
||||
videosToPreload.add('5.mp4');
|
||||
|
||||
// 开始预加载
|
||||
for (const videoFile of videosToPreload) {
|
||||
// 并行预加载,提高效率
|
||||
const preloadPromises = Array.from(videosToPreload).map(async (videoFile) => {
|
||||
try {
|
||||
this.logMessage(`预加载视频: ${videoFile}`, 'info');
|
||||
await this.createVideoStream(videoFile);
|
||||
@ -433,35 +443,51 @@ class WebRTCChat {
|
||||
} catch (error) {
|
||||
this.logMessage(`预加载失败: ${videoFile}: ${error.message}`, 'error');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
await Promise.allSettled(preloadPromises);
|
||||
}
|
||||
|
||||
async switchVideoStream(videoFile, type = '', text = '') {
|
||||
try {
|
||||
this.logMessage(`开始切换视频流: ${videoFile} (${type})`, 'info');
|
||||
|
||||
// 如果视频已缓存,减少loading时间
|
||||
// 检查是否已缓存
|
||||
const isCached = this.videoStreams.has(videoFile);
|
||||
if (!isCached) {
|
||||
this.recordedVideo.classList.add('loading');
|
||||
|
||||
// 如果已缓存,直接使用,避免loading状态
|
||||
if (isCached) {
|
||||
const cachedStream = this.videoStreams.get(videoFile);
|
||||
if (cachedStream && cachedStream.getTracks().length > 0) {
|
||||
// 直接切换到缓存的流
|
||||
this.currentVideoStream = cachedStream;
|
||||
this.recordedVideo.srcObject = cachedStream;
|
||||
this.currentVideo = videoFile;
|
||||
|
||||
// 立即播放,无需loading状态
|
||||
await this.recordedVideo.play();
|
||||
this.recordedVideo.classList.add('playing');
|
||||
|
||||
this.logMessage(`使用缓存视频流: ${videoFile}`, 'success');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// // 添加加载状态
|
||||
// this.recordedVideo.classList.add('loading');
|
||||
// 未缓存的视频才显示loading状态
|
||||
this.recordedVideo.classList.add('loading');
|
||||
|
||||
// 先创建新的视频流,不立即停止旧的
|
||||
// 先创建新的视频流
|
||||
const newStream = await this.createVideoStream(videoFile);
|
||||
|
||||
// 缓存的视频减少等待时间
|
||||
const waitTime = isCached ? 50 : 200;
|
||||
await new Promise(resolve => setTimeout(resolve, waitTime));
|
||||
// 减少等待时间
|
||||
await new Promise(resolve => setTimeout(resolve, 100));
|
||||
|
||||
// 检查流是否有效
|
||||
if (!newStream || newStream.getTracks().length === 0) {
|
||||
throw new Error('创建的视频流无效');
|
||||
}
|
||||
|
||||
// 先设置新的视频流,再停止旧的
|
||||
// 设置新的视频流
|
||||
this.currentVideoStream = newStream;
|
||||
this.recordedVideo.srcObject = newStream;
|
||||
this.currentVideo = videoFile;
|
||||
@ -764,8 +790,8 @@ class WebRTCChat {
|
||||
}
|
||||
|
||||
async sendText() {
|
||||
// const text = this.textInput.value.trim();
|
||||
const text = 'say-5s-m-sw';
|
||||
const text = this.textInput.value.trim();
|
||||
// const text = 'say-5s-m-sw';
|
||||
if (text) {
|
||||
this.socket.emit('text-input', { text });
|
||||
this.logMessage(`发送文本: ${text}`, 'info');
|
||||
|
||||
@ -51,9 +51,10 @@ async function requestLLMStream({ apiKey, model, messages, onSegment }) {
|
||||
|
||||
if (jsonStr === '[DONE]') {
|
||||
console.log('LLM SSE流结束');
|
||||
// 处理最后的待处理文本
|
||||
// 处理最后的待处理文本(无论长度是否大于5个字)
|
||||
if (pendingText.trim() && onSegment) {
|
||||
await onSegment(pendingText.trim());
|
||||
console.log('处理最后的待处理文本:', pendingText.trim());
|
||||
await onSegment(pendingText.trim(), true);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@ -71,20 +72,35 @@ async function requestLLMStream({ apiKey, model, messages, onSegment }) {
|
||||
// 按分隔符分割文本
|
||||
const segments = pendingText.split(segmentDelimiters);
|
||||
|
||||
// 处理完整的段落(除了最后一个,因为可能不完整)
|
||||
// 重新组合处理:只处理足够长的完整段落
|
||||
let accumulatedText = '';
|
||||
let hasProcessed = false;
|
||||
|
||||
for (let i = 0; i < segments.length - 1; i++) {
|
||||
const segment = segments[i].trim();
|
||||
if (segment && onSegment) {
|
||||
// 找到对应的分隔符
|
||||
if (segment) {
|
||||
accumulatedText += segment;
|
||||
// 找到分隔符
|
||||
const delimiterMatch = pendingText.match(segmentDelimiters);
|
||||
const segmentWithDelimiter = segment + (delimiterMatch ? delimiterMatch[0] : '');
|
||||
console.log('检测到完整段落:', segmentWithDelimiter);
|
||||
await onSegment(segmentWithDelimiter);
|
||||
if (delimiterMatch) {
|
||||
accumulatedText += delimiterMatch[0];
|
||||
}
|
||||
|
||||
// 如果累积文本长度大于5个字,处理它
|
||||
if (accumulatedText.length > 8 && onSegment) {
|
||||
console.log('检测到完整段落:', accumulatedText);
|
||||
await onSegment(accumulatedText, false);
|
||||
hasProcessed = true;
|
||||
accumulatedText = ''; // 重置
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 保留最后一个不完整的段落
|
||||
pendingText = segments[segments.length - 1] || '';
|
||||
// 更新pendingText
|
||||
if (hasProcessed) {
|
||||
// 保留未处理的累积文本和最后一个不完整段落
|
||||
pendingText = accumulatedText + (segments[segments.length - 1] || '');
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
|
||||
@ -52,25 +52,26 @@ async function addAudioToQueue(audioHex) {
|
||||
console.error('音频解码失败:', error);
|
||||
}
|
||||
}
|
||||
|
||||
let isFirstChunk = true;
|
||||
// 队列处理器 - 独立运行,按顺序播放音频
|
||||
async function processAudioQueue() {
|
||||
if (isProcessingQueue) return;
|
||||
|
||||
isProcessingQueue = true;
|
||||
console.log('开始处理音频队列');
|
||||
let isFirstChunk = true;
|
||||
while (audioQueue.length > 0 || isPlaying) {
|
||||
|
||||
|
||||
while (audioQueue.length > 0 && !isPlaying) {
|
||||
console.log('开始处理音频队列');
|
||||
// 如果当前没有音频在播放,且队列中有音频
|
||||
if (!isPlaying && audioQueue.length > 0) {
|
||||
const audioItem = audioQueue.shift();
|
||||
const sayName = 'say-5s-m-sw'
|
||||
const targetVideo = '5.mp4'
|
||||
// 如果是第一个音频片段,触发视频切换
|
||||
if (sayName != window.webrtcApp.currentVideoTag && window.webrtcApp && window.webrtcApp.handleTextInput) {
|
||||
if (isFirstChunk && sayName != window.webrtcApp.currentVideoTag && window.webrtcApp && window.webrtcApp.switchVideoWithReplaceTrack) {
|
||||
try {
|
||||
console.log('--------------触发视频切换:', sayName);
|
||||
await window.webrtcApp.switchVideoWithReplaceTrack(targetVideo, 'audio', 'say-5s-m-sw');
|
||||
window.webrtcApp.switchVideoWithReplaceTrack(targetVideo, 'audio', 'say-5s-m-sw');
|
||||
isFirstChunk = false;
|
||||
window.webrtcApp.currentVideoTag = sayName;
|
||||
} catch (error) {
|
||||
@ -86,11 +87,12 @@ async function processAudioQueue() {
|
||||
|
||||
isProcessingQueue = false;
|
||||
const text = 'default'
|
||||
await window.webrtcApp.socket.emit('voice-input', { text });
|
||||
// await new Promise(resolve => setTimeout(resolve, 500));
|
||||
console.log("音频结束------------------------:", window.webrtcApp.currentVideoTag, isPlaying)
|
||||
if (window.webrtcApp.currentVideoTag != text) {
|
||||
|
||||
isFirstChunk = true
|
||||
window.webrtcApp.currentVideoTag = text
|
||||
await window.webrtcApp.switchVideoWithReplaceTrack(window.webrtcApp.defaultVideo, 'audio', text);
|
||||
window.webrtcApp.switchVideoWithReplaceTrack(window.webrtcApp.defaultVideo, 'audio', text);
|
||||
}
|
||||
console.log('音频队列处理完成');
|
||||
}
|
||||
@ -152,10 +154,10 @@ function getQueueStatus() {
|
||||
|
||||
// 移除waitForCurrentAudioToFinish函数,不再需要
|
||||
|
||||
async function requestMinimaxi({ apiKey, groupId, body, stream = true }) {
|
||||
async function requestMinimaxi({ apiKey, groupId, body, stream = true , textPlay = false}) {
|
||||
const url = `https://api.minimaxi.com/v1/t2a_v2`;
|
||||
const reqBody = { ...body, stream };
|
||||
|
||||
isPlaying = textPlay
|
||||
// 添加这两行变量定义
|
||||
let isFirstChunk = true;
|
||||
// const currentText = body.text;
|
||||
@ -222,8 +224,8 @@ async function requestMinimaxi({ apiKey, groupId, body, stream = true }) {
|
||||
// 流式,解析每个chunk,实时播放音频
|
||||
if (obj.data && obj.data.audio && obj.data.status === 1) {
|
||||
console.log('收到音频数据片段!', obj.data.audio.length);
|
||||
audioHex += obj.data.audio;
|
||||
|
||||
// audioHex += obj.data.audio;
|
||||
audioHex = obj.data.audio;
|
||||
// const sayName = 'say-5s-m-sw'
|
||||
// // 如果是第一个音频片段,触发视频切换
|
||||
// if (isFirstChunk && sayName != window.webrtcApp.currentVideoName && window.webrtcApp && window.webrtcApp.handleTextInput) {
|
||||
@ -244,7 +246,7 @@ async function requestMinimaxi({ apiKey, groupId, body, stream = true }) {
|
||||
// const text = 'default'
|
||||
// await window.webrtcApp.socket.emit('text-input', { text });
|
||||
// await window.webrtcApp.handleTextInput(text);
|
||||
lastFullResult = obj;
|
||||
lastFullResult = null;
|
||||
console.log('收到最终状态');
|
||||
}
|
||||
} catch (e) {
|
||||
@ -261,7 +263,7 @@ async function requestMinimaxi({ apiKey, groupId, body, stream = true }) {
|
||||
const obj = JSON.parse(line);
|
||||
if (obj.data && obj.data.audio) {
|
||||
console.log('收到无data:音频数据!', obj.data.audio.length);
|
||||
audioHex += obj.data.audio;
|
||||
audioHex = obj.data.audio;
|
||||
|
||||
// 立即播放这个音频片段
|
||||
await playAudioChunk(obj.data.audio);
|
||||
|
||||
@ -448,42 +448,22 @@ header p {
|
||||
}
|
||||
|
||||
#recordedVideo {
|
||||
transition: opacity 0.2s ease-in-out;
|
||||
transition: opacity 0.1s ease-in-out; /* 缩短过渡时间 */
|
||||
background-color: #1a1a1a; /* 深灰色背景,避免纯黑 */
|
||||
}
|
||||
|
||||
#recordedVideo.loading {
|
||||
opacity: 0.8; /* 加载时稍微降低透明度,但不完全隐藏 */
|
||||
opacity: 0.9; /* 提高loading时的透明度,减少黑屏感 */
|
||||
}
|
||||
|
||||
#recordedVideo.playing {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* 添加加载指示器 */
|
||||
.video-container {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.video-container::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
margin: -20px 0 0 -20px;
|
||||
border: 3px solid #333;
|
||||
border-top: 3px solid #fff;
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
opacity: 0;
|
||||
z-index: 10;
|
||||
transition: opacity 0.3s;
|
||||
}
|
||||
|
||||
/* 优化加载指示器 */
|
||||
.video-container.loading::before {
|
||||
opacity: 1;
|
||||
opacity: 0.8; /* 降低加载指示器的透明度 */
|
||||
border-top-color: #667eea; /* 使用主题色 */
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
|
||||
89
src/video_queue_test.js
Normal file
89
src/video_queue_test.js
Normal file
@ -0,0 +1,89 @@
|
||||
// 视频播放队列系统测试
|
||||
// 这个文件用于测试新的视频播放逻辑
|
||||
|
||||
export class VideoQueueTester {
|
||||
constructor(webrtcApp) {
|
||||
this.webrtcApp = webrtcApp;
|
||||
}
|
||||
|
||||
// 测试视频队列功能
|
||||
async testVideoQueue() {
|
||||
console.log('开始测试视频播放队列系统...');
|
||||
|
||||
// 测试1: 添加视频到队列
|
||||
await this.testAddToQueue();
|
||||
|
||||
// 测试2: 测试视频播放完成等待
|
||||
await this.testWaitForVideoFinish();
|
||||
|
||||
// 测试3: 测试音频视频同步
|
||||
await this.testAudioVideoSync();
|
||||
|
||||
console.log('视频播放队列系统测试完成');
|
||||
}
|
||||
|
||||
// 测试添加视频到队列
|
||||
async testAddToQueue() {
|
||||
console.log('测试1: 添加视频到队列');
|
||||
|
||||
// 清空队列
|
||||
this.webrtcApp.videoQueue = [];
|
||||
|
||||
// 添加测试视频
|
||||
await this.webrtcApp.addToVideoQueue('5.mp4', 'test', '测试视频1');
|
||||
await this.webrtcApp.addToVideoQueue('s-1.mp4', 'test', '测试视频2');
|
||||
|
||||
console.log(`队列长度: ${this.webrtcApp.videoQueue.length}`);
|
||||
console.log('队列内容:', this.webrtcApp.videoQueue);
|
||||
}
|
||||
|
||||
// 测试等待视频播放完成
|
||||
async testWaitForVideoFinish() {
|
||||
console.log('测试2: 等待视频播放完成');
|
||||
|
||||
// 模拟视频播放状态
|
||||
this.webrtcApp.isVideoPlaying = true;
|
||||
|
||||
// 模拟视频播放完成
|
||||
setTimeout(() => {
|
||||
this.webrtcApp.isVideoPlaying = false;
|
||||
console.log('模拟视频播放完成');
|
||||
}, 2000);
|
||||
|
||||
console.log('等待视频播放完成...');
|
||||
await this.webrtcApp.waitForCurrentVideoToFinish();
|
||||
console.log('视频播放完成等待测试通过');
|
||||
}
|
||||
|
||||
// 测试音频视频同步
|
||||
async testAudioVideoSync() {
|
||||
console.log('测试3: 音频视频同步');
|
||||
|
||||
// 模拟音频播放开始
|
||||
window.isPlaying = true;
|
||||
|
||||
// 添加视频到队列
|
||||
await this.webrtcApp.addToVideoQueue('5.mp4', 'audio', '音频同步测试');
|
||||
|
||||
// 模拟音频播放结束
|
||||
setTimeout(() => {
|
||||
window.isPlaying = false;
|
||||
console.log('模拟音频播放结束');
|
||||
}, 3000);
|
||||
|
||||
console.log('音频视频同步测试完成');
|
||||
}
|
||||
|
||||
// 运行所有测试
|
||||
async runAllTests() {
|
||||
try {
|
||||
await this.testVideoQueue();
|
||||
console.log('所有测试通过!');
|
||||
} catch (error) {
|
||||
console.error('测试失败:', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 导出测试类
|
||||
export default VideoQueueTester;
|
||||
BIN
videos/0-1.mp4
Normal file
BIN
videos/0-1.mp4
Normal file
Binary file not shown.
BIN
videos/0-2.mp4
Normal file
BIN
videos/0-2.mp4
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user