This commit is contained in:
root 2025-07-11 16:16:35 +08:00
parent 2257b3fba9
commit 2030decc8d
3 changed files with 390 additions and 7 deletions

View File

@ -0,0 +1,199 @@
# 素材标签继承问题修复
## 🐛 问题描述
用户反馈:导入素材成功,但在项目详情页面看不到导入的素材。经过分析发现,问题的根本原因是**视频分镜时生成的片段没有继承原始视频的标签**。
## 🔍 问题分析
### 问题定位
`python_core/services/media_manager.py``_split_video_by_scenes` 函数中:
```python
# 问题代码 (第297行和第375行)
segment = VideoSegment(
# ... 其他属性
tags=[], # ❌ 这里硬编码为空数组,没有继承原始视频的标签
# ... 其他属性
)
```
### 调用链分析
```
upload_video_file()
↓ (第487行)
_split_video_by_scenes(video_path, scene_changes, video_id) # ❌ 没有传递tags
创建VideoSegment时 tags=[] # ❌ 片段没有标签
```
### 影响范围
1. **所有通过自动分镜生成的视频片段都没有标签**
2. **项目详情页面通过标签过滤素材,导致无法显示这些片段**
3. **影响所有导入的视频素材(单文件和批量导入)**
## ✅ 修复方案
### 1. 修改函数签名
**文件**: `python_core/services/media_manager.py`
**位置**: 第267-268行
```python
# 修改前
def _split_video_by_scenes(self, video_path: str, scene_changes: List[float],
original_video_id: str) -> List[VideoSegment]:
# 修改后
def _split_video_by_scenes(self, video_path: str, scene_changes: List[float],
original_video_id: str, tags: List[str] = None) -> List[VideoSegment]:
```
### 2. 添加标签处理逻辑
**位置**: 第270-271行
```python
# 新增
if tags is None:
tags = []
```
### 3. 修复片段创建时的标签
**位置**: 第300行和第378行
```python
# 修改前
tags=[],
# 修改后
tags=tags.copy(),
```
### 4. 修改函数调用
**位置**: 第487行主要调用
```python
# 修改前
segments = self._split_video_by_scenes(str(stored_path), scene_changes, video_id)
# 修改后
segments = self._split_video_by_scenes(str(stored_path), scene_changes, video_id, tags)
```
**位置**: 第393行错误处理调用
```python
# 修改前
return self._split_video_by_scenes(video_path, [0.0, self._get_video_info(video_path)['duration']], original_video_id)
# 修改后
return self._split_video_by_scenes(video_path, [0.0, self._get_video_info(video_path)['duration']], original_video_id, tags)
```
## 🧪 验证修复
### 1. 运行测试脚本
```bash
python scripts/test_material_tags_fix.py
```
### 2. 手动测试步骤
1. **导入新视频**:
- 进入项目详情页面
- 点击"导入素材"
- 选择视频文件,确保添加了项目标签
- 完成导入
2. **检查标签继承**:
- 打开开发者工具查看控制台日志
- 确认片段创建时包含了正确的标签
- 在项目详情页面验证素材显示
3. **验证数据文件**:
- 检查 `cache/video_segments.json`
- 确认新生成的片段包含标签
### 3. 预期结果
```json
// video_segments.json 中的片段应该包含标签
{
"id": "segment-uuid",
"original_video_id": "video-uuid",
"filename": "segment_001.mp4",
"tags": ["项目商品名", "其他标签"], // ✅ 现在有标签了
// ... 其他属性
}
```
## 🔧 现有数据修复
### 问题
已经导入的视频片段仍然没有标签,需要手动修复。
### 解决方案
#### 方案1: 重新导入(推荐)
1. 删除现有的无标签素材
2. 重新导入视频文件
3. 新导入的片段将自动包含正确的标签
#### 方案2: 手动添加标签
1. 进入素材管理页面
2. 找到相关的视频片段
3. 手动为每个片段添加项目商品名标签
4. 返回项目详情页面验证
#### 方案3: 批量修复脚本
创建脚本批量为现有片段添加标签:
```python
# 示例修复脚本
def fix_existing_segments():
media_manager = MediaManager()
# 获取所有无标签的片段
segments = media_manager.get_all_segments()
untagged_segments = [s for s in segments if not s.get('tags')]
# 为每个片段添加标签(需要根据实际情况确定标签)
for segment in untagged_segments:
# 根据文件名或其他信息确定应该添加的标签
tags_to_add = ["项目商品名"] # 需要根据实际情况调整
media_manager.add_tags_to_segment(segment['id'], tags_to_add)
```
## 📊 修复效果
### 修复前
```
导入视频 → 生成片段 → tags: [] → 项目页面无法显示
```
### 修复后
```
导入视频 → 生成片段 → tags: ["项目商品名", "其他标签"] → 项目页面正常显示
```
## 🚨 注意事项
1. **现有数据**: 修复只影响新导入的视频,现有无标签片段需要单独处理
2. **标签匹配**: 确保项目设置了正确的商品名称
3. **大小写敏感**: 标签匹配是大小写敏感的
4. **测试验证**: 修复后务必测试新的导入流程
## 📝 相关文件
- `python_core/services/media_manager.py` - 主要修复文件
- `src/pages/ProjectDetailPage.tsx` - 项目素材显示逻辑
- `src/components/ImportMaterialModal.tsx` - 导入界面
- `scripts/test_material_tags_fix.py` - 测试脚本
## 🎯 总结
通过修复 `_split_video_by_scenes` 函数的标签继承问题,现在:
1. ✅ 新导入的视频片段会正确继承原始视频的标签
2. ✅ 项目详情页面能够正确显示导入的素材
3. ✅ 自动分镜功能不再丢失标签信息
4. ✅ 单文件和批量导入都能正常工作
这个修复解决了素材导入后无法在项目中显示的核心问题!

View File

@ -265,8 +265,11 @@ class MediaManager:
return False
def _split_video_by_scenes(self, video_path: str, scene_changes: List[float],
original_video_id: str) -> List[VideoSegment]:
original_video_id: str, tags: List[str] = None) -> List[VideoSegment]:
"""根据场景变化分割视频"""
if tags is None:
tags = []
if not VIDEO_LIBS_AVAILABLE:
logger.warning("Video processing not available, creating single segment")
# 创建单个片段
@ -294,7 +297,7 @@ class MediaManager:
format='mp4',
start_time=0.0,
end_time=video_info['duration'],
tags=[],
tags=tags.copy(),
use_count=0,
created_at=now,
updated_at=now
@ -372,7 +375,7 @@ class MediaManager:
format='mp4',
start_time=start_time,
end_time=end_time,
tags=[],
tags=tags.copy(),
use_count=0,
thumbnail_path=str(thumbnail_path) if thumbnail_generated else None,
created_at=now,
@ -387,7 +390,7 @@ class MediaManager:
except Exception as e:
logger.error(f"Failed to split video: {e}")
# 如果分割失败,创建单个片段
return self._split_video_by_scenes(video_path, [0.0, self._get_video_info(video_path)['duration']], original_video_id)
return self._split_video_by_scenes(video_path, [0.0, self._get_video_info(video_path)['duration']], original_video_id, tags)
return segments
@ -480,9 +483,9 @@ class MediaManager:
updated_at=now
)
# 分割视频成片段
segments = self._split_video_by_scenes(str(stored_path), scene_changes, video_id)
# 分割视频成片段,传递标签给片段
segments = self._split_video_by_scenes(str(stored_path), scene_changes, video_id, tags)
# 保存数据
self.original_videos.append(original_video)
self.video_segments.extend(segments)

View File

@ -0,0 +1,181 @@
#!/usr/bin/env python3
"""
测试素材标签修复的脚本
验证导入的视频片段是否正确继承了原始视频的标签
"""
import sys
import os
import json
from pathlib import Path
# 添加项目根目录到Python路径
project_root = Path(__file__).parent.parent
sys.path.insert(0, str(project_root))
from python_core.services.media_manager import MediaManager
def test_video_tags_inheritance():
"""测试视频标签继承功能"""
print("🧪 开始测试视频标签继承功能...")
# 创建MediaManager实例
media_manager = MediaManager()
# 测试标签
test_tags = ["测试项目", "商业", "产品展示"]
print(f"📋 测试标签: {test_tags}")
# 模拟上传视频文件(这里只是测试标签传递逻辑)
print("\n🔍 检查_split_video_by_scenes函数签名...")
# 检查函数是否接受tags参数
import inspect
sig = inspect.signature(media_manager._split_video_by_scenes)
params = list(sig.parameters.keys())
print(f"函数参数: {params}")
if 'tags' in params:
print("✅ _split_video_by_scenes函数已正确添加tags参数")
else:
print("❌ _split_video_by_scenes函数缺少tags参数")
return False
# 检查现有数据中的标签情况
print("\n📊 检查现有素材的标签情况...")
segments = media_manager.get_all_segments()
if segments:
print(f"找到 {len(segments)} 个视频片段")
# 统计标签情况
tagged_segments = [s for s in segments if s.get('tags')]
untagged_segments = [s for s in segments if not s.get('tags')]
print(f"有标签的片段: {len(tagged_segments)}")
print(f"无标签的片段: {len(untagged_segments)}")
if tagged_segments:
print("\n🏷️ 有标签的片段示例:")
for i, segment in enumerate(tagged_segments[:3]):
print(f" {i+1}. {segment['filename']}: {segment['tags']}")
if untagged_segments:
print("\n🚫 无标签的片段示例:")
for i, segment in enumerate(untagged_segments[:3]):
print(f" {i+1}. {segment['filename']}: 无标签")
else:
print("没有找到视频片段")
# 检查原始视频的标签情况
print("\n📹 检查原始视频的标签情况...")
original_videos = media_manager.get_all_original_videos()
if original_videos:
print(f"找到 {len(original_videos)} 个原始视频")
for i, video in enumerate(original_videos[:5]):
print(f" {i+1}. {video['filename']}: {video.get('tags', [])}")
else:
print("没有找到原始视频")
return True
def check_data_files():
"""检查数据文件的内容"""
print("\n📁 检查数据文件...")
# 获取数据文件路径
from python_core.config import settings
cache_dir = settings.temp_dir / "cache"
segments_file = cache_dir / "video_segments.json"
original_videos_file = cache_dir / "original_videos.json"
print(f"片段文件: {segments_file}")
print(f"原始视频文件: {original_videos_file}")
# 检查片段文件
if segments_file.exists():
try:
with open(segments_file, 'r', encoding='utf-8') as f:
segments_data = json.load(f)
print(f"✅ 片段文件存在,包含 {len(segments_data)} 个片段")
# 分析标签情况
tagged_count = sum(1 for s in segments_data if s.get('tags'))
print(f" 有标签的片段: {tagged_count}")
print(f" 无标签的片段: {len(segments_data) - tagged_count}")
except Exception as e:
print(f"❌ 读取片段文件失败: {e}")
else:
print("❌ 片段文件不存在")
# 检查原始视频文件
if original_videos_file.exists():
try:
with open(original_videos_file, 'r', encoding='utf-8') as f:
videos_data = json.load(f)
print(f"✅ 原始视频文件存在,包含 {len(videos_data)} 个视频")
# 分析标签情况
tagged_count = sum(1 for v in videos_data if v.get('tags'))
print(f" 有标签的视频: {tagged_count}")
print(f" 无标签的视频: {len(videos_data) - tagged_count}")
except Exception as e:
print(f"❌ 读取原始视频文件失败: {e}")
else:
print("❌ 原始视频文件不存在")
def suggest_manual_fix():
"""建议手动修复方案"""
print("\n🔧 手动修复建议:")
print("1. 如果现有片段没有标签,可以通过以下方式修复:")
print(" - 进入素材管理页面")
print(" - 为相关素材手动添加项目标签")
print(" - 或者重新导入素材")
print("\n2. 验证修复效果:")
print(" - 导入新的测试视频")
print(" - 检查生成的片段是否包含正确的标签")
print(" - 在项目详情页面查看是否显示导入的素材")
print("\n3. 调试信息:")
print(" - 打开浏览器开发者工具")
print(" - 查看控制台输出的标签信息")
print(" - 确认项目商品名和素材标签匹配")
def main():
"""主函数"""
print("🚀 素材标签修复测试")
print("=" * 50)
try:
# 测试标签继承功能
test_video_tags_inheritance()
# 检查数据文件
check_data_files()
# 提供修复建议
suggest_manual_fix()
print("\n✅ 测试完成!")
print("\n📝 总结:")
print("- _split_video_by_scenes函数已修复现在会继承原始视频的标签")
print("- 新导入的视频片段将包含正确的标签")
print("- 现有的无标签片段需要手动修复或重新导入")
except Exception as e:
print(f"❌ 测试过程中出现错误: {e}")
import traceback
traceback.print_exc()
if __name__ == "__main__":
main()