|
@@ -45,7 +45,8 @@
|
|
|
</div>
|
|
|
<!-- 添加字幕覆盖层 :data-time="formatTime(recordingTimerCount) || '03:30'"-->
|
|
|
<div class="subtitle-overlay" v-if="currentSubtitle" >
|
|
|
- {{ currentSubtitle }}
|
|
|
+ <div class="subtitle-main">{{ currentSubtitle }}</div>
|
|
|
+ <!-- <div class="subtitle-translation" v-if="currentTranslation">{{ currentTranslation }}</div> -->
|
|
|
</div>
|
|
|
|
|
|
<!-- 添加答题按钮 -->
|
|
@@ -197,6 +198,7 @@ export default {
|
|
|
useMiniProgramCameraComponent: false, // 添加小程序相机组件标志
|
|
|
cameraContext: null, // 添加相机上下文
|
|
|
currentSubtitle: '',
|
|
|
+ currentTranslation: '', // 添加翻译文本
|
|
|
subtitles: [], // 修改为空数组,将通过API获取
|
|
|
// 移除硬编码的字幕数组
|
|
|
// secondVideoSubtitles: [...],
|
|
@@ -261,6 +263,7 @@ export default {
|
|
|
lastQuestionWasFollowUp: false,
|
|
|
lastFollowUpQuestionId: null,
|
|
|
lastUpdateTime: Date.now(), // 添加最后更新时间戳
|
|
|
+ subtitleMap: {}, // 用于存储字幕和翻译的映射
|
|
|
}
|
|
|
},
|
|
|
mounted() {
|
|
@@ -2266,96 +2269,51 @@ export default {
|
|
|
|
|
|
// 如果正在播放低分提示视频,使用专门的字幕数组
|
|
|
if (this.isPlayingLowScoreVideo) {
|
|
|
- if (this.lowScoreVideoSubtitles) {
|
|
|
- const subtitle = this.lowScoreVideoSubtitles.find(
|
|
|
- sub => currentTime >= sub.startTime && currentTime < sub.endTime
|
|
|
- );
|
|
|
- this.currentSubtitle = subtitle ? subtitle.text : '';
|
|
|
+ if (this.lowScoreVideoSubtitles && this.lowScoreVideoSubtitles.length > 0) {
|
|
|
+ const subtitle = this.lowScoreVideoSubtitles[0]; // 使用第一个字幕
|
|
|
+ this.currentSubtitle = subtitle.text;
|
|
|
}
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- // 获取视频总时长
|
|
|
- const videoElement = this.$refs.videoPlayer;
|
|
|
- const duration = videoElement ? videoElement.duration : 0;
|
|
|
-
|
|
|
- // 检测视频是否刚刚切换(新视频开始时currentTime接近0)
|
|
|
- if (currentTime < 0.5 && this.historyTime > 0) {
|
|
|
- console.log('检测到视频切换,重置历史时间');
|
|
|
- this.historyTime = currentTime;
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- // 计算时间差
|
|
|
- const timeDiff = Math.abs(currentTime - this.historyTime);
|
|
|
-
|
|
|
- // 更宽松的跳转检测:
|
|
|
- // 1. 只有大于1秒的时间跳跃才视为异常
|
|
|
- // 2. 排除视频自然结束和新视频开始的情况
|
|
|
- // 3. 添加自然播放速率的容差
|
|
|
- if (timeDiff > 1 && this.historyTime > 0) {
|
|
|
- // 排除视频接近结束的情况
|
|
|
- const isNearEnd = duration > 0 && (duration - this.historyTime < 1);
|
|
|
- // 排除视频刚开始的情况
|
|
|
- const isJustStarted = currentTime < 1;
|
|
|
- // 检查是否是自然播放速率(允许0.9-1.1倍的播放速度)
|
|
|
- const isNaturalPlayback = timeDiff < 1.1 * (Date.now() - this.lastUpdateTime) / 1000;
|
|
|
-
|
|
|
- // 如果不是以上任何情况,则视为异常跳转
|
|
|
- if (!isNearEnd && !isJustStarted && !isNaturalPlayback) {
|
|
|
- console.log('检测到视频时间异常跳转,回退到历史时间', this.historyTime);
|
|
|
- let videoContext = uni.createVideoContext('myVideo', this);
|
|
|
- videoContext.seek(this.historyTime);
|
|
|
- return; // 提前返回,避免更新字幕
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 更新历史时间和最后更新时间戳
|
|
|
- this.historyTime = currentTime;
|
|
|
- this.lastUpdateTime = Date.now();
|
|
|
-
|
|
|
- // 以下是字幕处理逻辑
|
|
|
+ // 获取当前视频对应的字幕数组
|
|
|
let currentSubtitles = null;
|
|
|
|
|
|
- // 如果是追问问题,查找对应的字幕数组
|
|
|
if (this.isFollowUpQuestion && this.currentFollowUpQuestion) {
|
|
|
- // 使用当前追问问题ID查找对应的字幕数组
|
|
|
+ // 追问问题字幕处理
|
|
|
const subtitleKey = `followUpSubtitles_${this.currentFollowUpQuestion.id}`;
|
|
|
- if (this[subtitleKey]) {
|
|
|
- currentSubtitles = this[subtitleKey];
|
|
|
- console.log(`使用追问问题字幕数组: ${subtitleKey}`, currentSubtitles);
|
|
|
- } else {
|
|
|
- // 如果没有找到对应的字幕数组,创建一个默认的
|
|
|
- currentSubtitles = [{
|
|
|
- startTime: 0,
|
|
|
- endTime: 30, // 默认30秒
|
|
|
- text: this.currentFollowUpQuestion.digital_human_video_subtitle || this.currentFollowUpQuestion.question
|
|
|
- }];
|
|
|
- console.log('使用默认追问问题字幕');
|
|
|
- }
|
|
|
+ currentSubtitles = this[subtitleKey] || [{
|
|
|
+ startTime: 0,
|
|
|
+ endTime: 30,
|
|
|
+ text: this.currentFollowUpQuestion.digital_human_video_subtitle ||
|
|
|
+ this.currentFollowUpQuestion.question
|
|
|
+ }];
|
|
|
} else {
|
|
|
- // 根据当前播放的视频索引选择对应的字幕数组
|
|
|
+ // 常规问题字幕处理
|
|
|
if (this.currentVideoIndex === 0) {
|
|
|
currentSubtitles = this.subtitles;
|
|
|
} else {
|
|
|
- // 动态获取字幕数组
|
|
|
const subtitleArrayName = `question${this.currentVideoIndex}Subtitles`;
|
|
|
- currentSubtitles = this[subtitleArrayName] || [];
|
|
|
+ currentSubtitles = this[subtitleArrayName];
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // 查找当前时间应该显示的字幕
|
|
|
+ // 确保字幕持续显示
|
|
|
if (currentSubtitles && currentSubtitles.length > 0) {
|
|
|
- const subtitle = currentSubtitles.find(
|
|
|
- sub => currentTime >= sub.startTime && currentTime < sub.endTime
|
|
|
- );
|
|
|
-
|
|
|
- // 更新当前字幕
|
|
|
- this.currentSubtitle = subtitle ? subtitle.text : '';
|
|
|
- } else {
|
|
|
- // 如果没有找到字幕数组或字幕数组为空,清空当前字幕
|
|
|
- this.currentSubtitle = '';
|
|
|
+ // 找到当前时间对应的字幕
|
|
|
+ const subtitle = currentSubtitles.find(sub =>
|
|
|
+ currentTime >= sub.startTime && currentTime <= sub.endTime
|
|
|
+ ) || currentSubtitles[0]; // 如果找不到对应时间的字幕,使用第一个字幕
|
|
|
+
|
|
|
+ // 只显示字幕文本
|
|
|
+ if (subtitle) {
|
|
|
+ this.currentSubtitle = subtitle.text;
|
|
|
+ }
|
|
|
}
|
|
|
+
|
|
|
+ // 更新历史时间和时间戳
|
|
|
+ this.historyTime = currentTime;
|
|
|
+ this.lastUpdateTime = Date.now();
|
|
|
},
|
|
|
|
|
|
// Add a new method to handle the "Start Recording" button click
|
|
@@ -2788,7 +2746,7 @@ export default {
|
|
|
// 首先添加介绍视频
|
|
|
this.videoList.push(this.introVideoUrl);
|
|
|
|
|
|
- // 为介绍视频设置字幕
|
|
|
+ // 修改介绍视频的字幕,移除翻译
|
|
|
this.subtitles = [
|
|
|
{
|
|
|
startTime: 0,
|
|
@@ -2814,23 +2772,22 @@ export default {
|
|
|
const questionsToUse = sortedQuestions.slice(0, 5);
|
|
|
|
|
|
// 为每个问题添加视频URL和字幕
|
|
|
- questionsToUse.forEach(question => {
|
|
|
- // 如果有视频URL,添加到视频列表
|
|
|
+ questionsToUse.forEach((question, index) => {
|
|
|
if (question.digital_human_video_url) {
|
|
|
this.videoList.push(question.digital_human_video_url);
|
|
|
|
|
|
- // 为这个问题创建字幕数组
|
|
|
+ // 创建字幕映射,只保留文本
|
|
|
const subtitleArray = [{
|
|
|
startTime: 0,
|
|
|
- endTime: 10, // 默认10秒,可以根据实际情况调整
|
|
|
+ endTime: 30, // 延长字幕显示时间到30秒
|
|
|
text: question.digital_human_video_subtitle || question.question
|
|
|
}];
|
|
|
|
|
|
- // 根据问题的序号存储字幕
|
|
|
- const index = this.videoList.length - 1; // 减1是因为我们已经添加了视频URL
|
|
|
+ const videoIndex = this.videoList.length - 1;
|
|
|
+ this[`question${videoIndex}Subtitles`] = subtitleArray;
|
|
|
|
|
|
- // 动态创建字幕数组属性
|
|
|
- this[`question${index}Subtitles`] = subtitleArray;
|
|
|
+ // 存储字幕映射
|
|
|
+ this.subtitleMap[question.digital_human_video_url] = subtitleArray;
|
|
|
}
|
|
|
});
|
|
|
|
|
@@ -3042,8 +2999,9 @@ export default {
|
|
|
this.lowScoreVideoSubtitles = [
|
|
|
{
|
|
|
startTime: 0,
|
|
|
- endTime: 10, // 假设视频长度为10秒,可根据实际情况调整
|
|
|
- text: '我未听清楚您在说什么,请您再说一遍!'
|
|
|
+ endTime: 30, // 假设视频长度为10秒,可根据实际情况调整
|
|
|
+ text: '我未听清楚您在说什么,请您再说一遍!',
|
|
|
+ translation: 'I didn\'t quite catch what you said, could you please repeat it?'
|
|
|
}
|
|
|
];
|
|
|
}, 500);
|
|
@@ -3222,30 +3180,26 @@ export default {
|
|
|
playFollowUpQuestionVideo(followUpQuestion) {
|
|
|
console.log('播放追问问题视频:', followUpQuestion.digital_human_video_url);
|
|
|
|
|
|
- // 设置视频URL
|
|
|
this.videoUrl = followUpQuestion.digital_human_video_url;
|
|
|
this.videoPlaying = true;
|
|
|
|
|
|
- // 设置追问问题的字幕,延长字幕显示时间
|
|
|
+ // 设置追问问题的字幕
|
|
|
const followUpSubtitles = [{
|
|
|
startTime: 0,
|
|
|
- endTime: 30, // 延长到30秒,确保字幕能够在整个视频播放过程中显示
|
|
|
+ endTime: 60, // 延长显示时间到60秒
|
|
|
text: followUpQuestion.digital_human_video_subtitle || followUpQuestion.question
|
|
|
}];
|
|
|
|
|
|
- // 动态创建字幕数组属性
|
|
|
const subtitleKey = `followUpSubtitles_${followUpQuestion.id}`;
|
|
|
this[subtitleKey] = followUpSubtitles;
|
|
|
- console.log(`创建追问问题字幕数组: ${subtitleKey}`, followUpSubtitles);
|
|
|
|
|
|
- // 播放视频
|
|
|
this.$nextTick(() => {
|
|
|
const videoContext = uni.createVideoContext('myVideo', this);
|
|
|
if (videoContext) {
|
|
|
videoContext.play();
|
|
|
|
|
|
- // 立即显示字幕,不等待时间更新
|
|
|
- this.currentSubtitle = followUpQuestion.digital_human_video_subtitle || followUpQuestion.question;
|
|
|
+ // 立即显示字幕
|
|
|
+ this.currentSubtitle = followUpSubtitles[0].text;
|
|
|
}
|
|
|
});
|
|
|
},
|
|
@@ -3354,19 +3308,32 @@ video::-webkit-media-controls-fullscreen-button {
|
|
|
/* 修改字幕覆盖层样式,使其与图片中的样式一致 */
|
|
|
.subtitle-overlay {
|
|
|
position: absolute;
|
|
|
- bottom: 180px; /* 调整位置,使其更靠近底部 */
|
|
|
- left: 5%; /* 从左侧留出5%的空间 */
|
|
|
- width: 80%; /* 宽度设为90%,两侧各留5%实现居中 */
|
|
|
- padding: 15px 20px; /* 增加左右内边距 */
|
|
|
+ bottom: 180px;
|
|
|
+ left: 5%;
|
|
|
+ width: 80%;
|
|
|
+ padding: 15px 20px;
|
|
|
border-radius: 15px;
|
|
|
- background-color: rgba(255, 255, 255, 0.9); /* 白色半透明背景 */
|
|
|
- color: #333; /* 文字颜色为深色 */
|
|
|
- text-align: left; /* 文字左对齐 */
|
|
|
+ background-color: rgba(255, 255, 255, 0.9);
|
|
|
+ color: #333;
|
|
|
+ text-align: left;
|
|
|
font-size: 16px;
|
|
|
line-height: 1.5;
|
|
|
z-index: 10;
|
|
|
- margin: 0 auto; /* 添加自动边距实现居中 */
|
|
|
- box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); /* 添加轻微阴影 */
|
|
|
+ margin: 0 auto;
|
|
|
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 8px;
|
|
|
+}
|
|
|
+
|
|
|
+.subtitle-main {
|
|
|
+ font-weight: 500;
|
|
|
+}
|
|
|
+
|
|
|
+.subtitle-translation {
|
|
|
+ font-size: 14px;
|
|
|
+ color: #666;
|
|
|
+ font-style: italic;
|
|
|
}
|
|
|
|
|
|
/* 添加计时器样式,右侧显示橙色圆点和时间 */
|