# 批量更新视频duration说明 ## 📊 **当前问题** **查询结果:** ``` 总视频数:859个 - 未配置duration: 858个 (99.9%) - 配置为0: 1个 - 已配置: 0个 ``` **影响:** - 无法准确判断视频是否真正完成 - 只能根据观看时长和学习次数粗略判断 - 可能导致进度计算不准确 --- ## ✅ **当前临时解决方案** ### **分级判断标准(已实现):** 根据观看时长动态调整要求: | 观看时长 | 最少观看 | 最少记录数 | 说明 | |---------|---------|-----------|------| | < 3分钟 | 60秒 | 3次 | 短视频 | | 3-10分钟 | 180秒 | 5次 | 中等视频 | | ≥ 10分钟 | 600秒 | 8次 | 长视频 | **优点:** - ✅ 防止看几秒就算完成 - ✅ 考虑了不同长度的视频 - ✅ 要求多次学习记录(防快进) **缺点:** - ❌ 仍然无法精确判断完成 - ❌ 长视频可能要求太严格 - ❌ 短视频可能要求太宽松 --- ## 🎯 **最佳解决方案:配置正确的duration** ### **方式1:前端上传时获取(推荐)** **修改上传组件:** ```javascript // 上传视频时自动获取时长 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获取视频信息:** ```bash # 安装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代码示例:** ```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脚本扫描所有视频:** ```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() ``` **执行:** ```bash python scan_video_duration.py ``` --- ## 📋 **推荐执行步骤** ### **短期方案(当前已实现):** 1. ✅ 使用分级判断标准 2. ✅ 重新编译部署 3. ✅ 测试验证 ### **长期方案(建议实施):** 1. **前端修改** - 上传视频时自动获取duration 2. **现有视频** - 使用Python脚本批量扫描更新 3. **后端验证** - 确保所有新上传视频都有duration --- ## ⚠️ **注意事项** 1. **批量更新前先备份数据库** 2. **确认视频文件路径正确** 3. **服务器需要安装FFmpeg** 4. **更新可能需要较长时间(859个视频)** --- ## ✅ **当前状态** - ✅ 已修复"3秒即完成"的bug - ✅ 已实现分级判断标准 - ✅ 可以正常使用(虽然不是最精确) - ⏳ 建议后续批量更新duration **可以先编译部署使用,后续再批量更新duration!**