4.9 KiB
4.9 KiB
批量更新视频duration说明
📊 当前问题
查询结果:
总视频数:859个
- 未配置duration: 858个 (99.9%)
- 配置为0: 1个
- 已配置: 0个
影响:
- 无法准确判断视频是否真正完成
- 只能根据观看时长和学习次数粗略判断
- 可能导致进度计算不准确
✅ 当前临时解决方案
分级判断标准(已实现):
根据观看时长动态调整要求:
| 观看时长 | 最少观看 | 最少记录数 | 说明 |
|---|---|---|---|
| < 3分钟 | 60秒 | 3次 | 短视频 |
| 3-10分钟 | 180秒 | 5次 | 中等视频 |
| ≥ 10分钟 | 600秒 | 8次 | 长视频 |
优点:
- ✅ 防止看几秒就算完成
- ✅ 考虑了不同长度的视频
- ✅ 要求多次学习记录(防快进)
缺点:
- ❌ 仍然无法精确判断完成
- ❌ 长视频可能要求太严格
- ❌ 短视频可能要求太宽松
🎯 最佳解决方案:配置正确的duration
方式1:前端上传时获取(推荐)
修改上传组件:
// 上传视频时自动获取时长
function handleVideoUpload(file) {
const video = document.createElement('video');
video.preload = 'metadata';
video.onloadedmetadata = function() {
const duration = Math.floor(video.duration); // 秒
// 上传时携带duration参数
uploadFile(file, {
duration: duration
});
};
video.src = URL.createObjectURL(file);
}
方式2:后端自动获取(服务器端)
使用FFmpeg获取视频信息:
# 安装FFmpeg
# Windows: 下载 https://ffmpeg.org/download.html
# Linux: apt-get install ffmpeg
# 获取视频时长
ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 video.mp4
Java代码示例:
public int getVideoDuration(String filePath) {
try {
ProcessBuilder pb = new ProcessBuilder(
"ffprobe",
"-v", "error",
"-show_entries", "format=duration",
"-of", "default=noprint_wrappers=1:nokey=1",
filePath
);
Process process = pb.start();
BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream())
);
String durationStr = reader.readLine();
return (int) Float.parseFloat(durationStr);
} catch (Exception e) {
return 0;
}
}
方式3:批量扫描现有视频(一次性处理)
创建Python脚本扫描所有视频:
# scan_video_duration.py
import os
import subprocess
import mysql.connector
# 连接数据库
db = mysql.connector.connect(
host="localhost",
user="root",
password="root",
database="study"
)
cursor = db.cursor()
# 查询所有视频
cursor.execute("SELECT id, file_path FROM courseware WHERE type='video'")
videos = cursor.fetchall()
# 基础路径
base_path = "D:/wwwroot/study_web/web" # 根据实际情况修改
update_count = 0
for video_id, file_path in videos:
# 构建完整路径
full_path = base_path + file_path
if not os.path.exists(full_path):
print(f"文件不存在: {full_path}")
continue
try:
# 使用ffprobe获取时长
result = subprocess.run([
'ffprobe',
'-v', 'error',
'-show_entries', 'format=duration',
'-of', 'default=noprint_wrappers=1:nokey=1',
full_path
], capture_output=True, text=True)
duration = int(float(result.stdout.strip()))
# 更新数据库
cursor.execute(
"UPDATE courseware SET duration = %s WHERE id = %s",
(duration, video_id)
)
db.commit()
update_count += 1
print(f"✅ ID:{video_id} - {duration}秒")
except Exception as e:
print(f"❌ ID:{video_id} - 错误: {e}")
print(f"\n完成!更新了 {update_count} 个视频的duration")
cursor.close()
db.close()
执行:
python scan_video_duration.py
📋 推荐执行步骤
短期方案(当前已实现):
- ✅ 使用分级判断标准
- ✅ 重新编译部署
- ✅ 测试验证
长期方案(建议实施):
- 前端修改 - 上传视频时自动获取duration
- 现有视频 - 使用Python脚本批量扫描更新
- 后端验证 - 确保所有新上传视频都有duration
⚠️ 注意事项
- 批量更新前先备份数据库
- 确认视频文件路径正确
- 服务器需要安装FFmpeg
- 更新可能需要较长时间(859个视频)
✅ 当前状态
- ✅ 已修复"3秒即完成"的bug
- ✅ 已实现分级判断标准
- ✅ 可以正常使用(虽然不是最精确)
- ⏳ 建议后续批量更新duration
可以先编译部署使用,后续再批量更新duration!