211 lines
4.9 KiB
Markdown
211 lines
4.9 KiB
Markdown
# 批量更新视频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!**
|