智能包装系统技术文档
目录
概述
智能包装系统是对标剪映"智能包装"功能的 AI 驱动视频增强系统,通过自动化音乐匹配、视觉分析、风格化处理等技术,实现一键生成专业级视频效果。
核心能力
| 功能模块 | 实现状态 | 覆盖率 |
|---|---|---|
| AI 智能 BGM | ✅ Phase 1 | 100% |
| AI 卡点同步 | ✅ Phase 1 | 100% |
| 智能转场 | ✅ Phase 1 | 100% |
| 片头片尾生成 | ✅ Phase 2 | 80% |
| 调色预设 | ✅ Phase 2 | 100% |
| CLIP 场景识别 | ✅ Phase 3 | 领先 |
| 模板市场 | ✅ Phase 3 | 60% |
| 花字贴纸 | ❌ 未实现 | 0% |
| 音效库 | ❌ 未实现 | 0% |
综合功能覆盖率:85%
差异化优势:CLIP 驱动的智能推荐(剪映暂无此功能)
系统架构
技术栈
前端层(Vue 3)
↓
FastAPI 服务
↓
AI 处理层
├── MusicSelector(BGM 智能选择)
├── BeatSyncEngine(AI 卡点)
├── TransitionEngine(智能转场)
├── IntroOutroGenerator(片头片尾)
├── ColorGrading(调色预设)
├── CLIPAnalyzer(场景识别)
└── TemplateManager(模板管理)
↓
FFmpeg 合成引擎数据流
用户输入(分镜 + 参数)
↓
Phase 1: 音乐处理
- Freesound API 获取 BGM
- 智能循环到视频长度
- Librosa 分析节奏
- 卡点同步
↓
Phase 2: 视觉包装
- FFmpeg 调色滤镜
- 生成片头片尾
- 拼接主视频
↓
Phase 3: 智能推荐(可选)
- CLIP 分析场景
- 匹配模板
- 应用配置
↓
最终输出功能实现
Phase 1: MVP(已完成)
1.1 AI 智能 BGM
文件:src/ai_processors/music_selector.py
功能:
- 从 Freesound API 获取免费音乐
- 支持 4 种情绪:calm/energetic/dramatic/upbeat
- Fallback 到本地音乐库(
music_library.json)
配置:
# pybridge/.env
ENABLE_AUTO_BGM=false # 全局开关(默认关闭,前端控制)
BGM_PROVIDER=freesound # 音乐源
BGM_REMOTE_ENABLED=true # 启用远程 API
DEFAULT_BGM_VOLUME=3.0 # 默认音量(对话密集场景)使用:
// 前端配置
options.enable_auto_bgm = true
options.bgm_mood = 'auto' // 自动推断情绪
options.bgm_volume = 3.01.2 智能循环
文件:src/ai_processors/music_engine.py
功能:
- 自动检测 BGM 时长
- 智能循环到视频长度
- 交叉淡化拼接(3s)
配置:
ENABLE_SMART_LOOP=true
BGM_CROSSFADE_DURATION=3.01.3 AI 卡点
文件:src/ai_processors/beat_sync_engine.py(需 librosa)
功能:
- 使用 librosa 检测 BGM 节奏
- 自动调整视频速度(±10%)对齐节拍
- Speech-heavy 场景自动降敏
配置:
ENABLE_BEAT_SYNC=true
BEAT_SYNC_MAX_SPEED_CHANGE=0.1
BEAT_SYNC_SPEECH_HEAVY_THRESHOLD=0.71.4 智能转场
文件:src/ai_processors/transition_engine.py
功能:
- 根据 BGM 节奏选择转场类型
- 3 种强度:low/medium/high
- 支持 fade/wipe/slide 等效果
配置:
ENABLE_AI_TRANSITIONS=true
TRANSITION_INTENSITY=medium1.5 智能 Ducking
文件:src/bridge/ffmpeg_runner.py(第 1196-1233 行)
功能:
- 人声时段自动降低 BGM 音量
- 使用 FFmpeg sidechaincompress 滤镜
- 实时响应人声能量变化
配置:
ENABLE_AUTO_DUCKING=true
DUCKING_THRESHOLD=0.1
DUCKING_RATIO=4.0Phase 2: 增强版(已完成)
2.1 片头片尾生成
文件:src/ai_processors/intro_outro_generator.py
功能:
- 3 种模板:minimal/elegant/energetic
- 3 种动画:fade/slide/zoom
- 自定义标题/副标题/时长
使用:
# Python 接口
intro_config = {
'title': '我的旅行记录',
'subtitle': '精心制作',
'duration': 3.0,
'template': 'minimal'
}
outro_config = {
'text': '感谢观看',
'duration': 2.0,
'template': 'minimal'
}2.2 调色预设
文件:src/ai_processors/color_grading.py
功能:
- 5 种风格:
fresh:清新(提升绿色/蓝色)vintage:复古(胶片感)cyberpunk:赛博(蓝紫色调)warm:暖色(红/橙)cool:冷色(蓝色)
- 基于 FFmpeg curves + eq 滤镜
使用:
// 前端配置
options.color_preset = 'fresh'Phase 3: 完整版(已完成)
3.1 CLIP 场景识别
文件:src/ai_processors/clip_analyzer.py
功能:
- 使用 OpenAI CLIP 模型分析视频
- 识别 6 种场景:nature/urban/portrait/product/food/tech
- 自动推荐调色/转场/BGM 风格
依赖(可选):
# 需手动安装(约 2GB)
pip install torch torchvision --index-url https://download.pytorch.org/whl/cpu
pip install git+https://github.com/openai/CLIP.git
pip install pillowAPI:
POST /ai/analyze-scene
{
"video_path": "/path/to/video.mp4",
"title": "我的旅行记录"
}
# 响应
{
"success": true,
"config": {
"color_preset": "fresh",
"bgm_mood": "calm",
"intro_config": {...},
"clip_analysis": {
"scene_type": "nature",
"confidence": 0.85
}
}
}3.2 模板市场
文件:
template_market.json:模板配置src/ai_processors/template_manager.py:管理器
预设模板:
- 旅行 Vlog:清新自然风格
- 科技测评:赛博风格
- 美食日记:暖色温馨
- 城市街拍:冷色现代
- 复古胶片:怀旧氛围
API:
GET /templates # 获取模板列表
GET /templates/{template_id} # 获取模板详情部署指南
配置文件更新
pybridge/.env
# Phase 1 配置
ENABLE_AUTO_BGM=false # 前端控制
ENABLE_SMART_LOOP=true # 启用智能循环
ENABLE_BEAT_SYNC=true # 启用 AI 卡点
ENABLE_AI_TRANSITIONS=true # 启用智能转场
ENABLE_AUTO_DUCKING=true # 启用 Ducking
DEFAULT_BGM_VOLUME=3.0 # 默认音量
# Phase 2/3 配置(通过前端传参,无需全局配置)前端配置
web/src/views/aigc/component/components/StoryBoardStep4Export.vue
新增字段:
options: {
enable_auto_bgm: false,
bgm_volume: 3.0,
bgm_mood: 'auto',
color_preset: 'none', // Phase 2
intro_config: null, // Phase 2
outro_config: null, // Phase 2
}一键智能包装:
applySmartPackaging() {
const title = this.storyboardMeta?.title || '精彩视频'
this.options = {
...this.options,
enable_auto_bgm: true,
enable_auto_ducking: true,
enable_beat_sync: true,
enable_ai_transitions: true,
enable_smart_loop: true,
bgm_mood: 'auto',
bgm_volume: 3.0,
color_preset: 'fresh',
intro_config: {
title: title,
subtitle: '精心制作',
duration: 3.0,
template: 'minimal'
},
outro_config: {
text: '感谢观看',
duration: 2.0,
template: 'minimal'
}
}
}部署步骤
# 1. 更新后端
cd /Users/mzy/docker/dnmp/www/stooland/pybridge
scp .env root@MZY-Kylin-server:/home/wwwroot/stooland/pybridge/
scp src/bridge/ffmpeg_runner.py root@MZY-Kylin-server:/home/wwwroot/stooland/pybridge/src/bridge/
scp src/ai_processors/*.py root@MZY-Kylin-server:/home/wwwroot/stooland/pybridge/src/ai_processors/
scp template_market.json root@MZY-Kylin-server:/home/wwwroot/stooland/pybridge/
scp src/service/fastapi_app.py root@MZY-Kylin-server:/home/wwwroot/stooland/pybridge/src/service/
# 2. 安装依赖(可选 CLIP)
ssh root@MZY-Kylin-server
cd /home/wwwroot/stooland/pybridge
pip install torch torchvision --index-url https://download.pytorch.org/whl/cpu
pip install git+https://github.com/openai/CLIP.git
pip install pillow
# 3. 重启服务
bash start.sh restart
# 4. 前端构建
cd /Users/mzy/docker/dnmp/www/stooland/web
yarn buildAPI 文档
模板市场
GET /templates
功能:获取智能包装模板列表
参数:
category(可选):分类过滤
响应:
{
"success": true,
"templates": [
{
"id": "travel_vlog",
"name": "旅行 Vlog",
"category": "生活",
"description": "适合旅行记录,清新自然风格",
"tags": ["旅行", "风景", "清新"],
"config": {
"color_preset": "fresh",
"bgm_mood": "calm",
"intro_config": {...},
"outro_config": {...}
}
}
]
}GET /templates/
功能:获取指定模板详情
响应:
{
"success": true,
"template": {
"id": "travel_vlog",
"name": "旅行 Vlog",
...
}
}CLIP 分析
POST /ai/analyze-scene
功能:使用 CLIP 分析视频场景并推荐配置
请求体:
{
"video_path": "/path/to/video.mp4",
"title": "我的旅行记录"
}响应:
{
"success": true,
"config": {
"color_preset": "fresh",
"bgm_mood": "calm",
"intro_config": {
"title": "我的旅行记录",
"subtitle": "Nature Scene",
"duration": 3.0,
"template": "minimal"
},
"outro_config": {
"text": "感谢观看",
"duration": 2.0,
"template": "minimal"
},
"clip_analysis": {
"scene_type": "nature",
"confidence": 0.85,
"keywords": ["landscape", "mountain"]
}
}
}失败回退:
{
"success": false,
"error": "CLIP not installed",
"fallback_config": {
"color_preset": "fresh",
"bgm_mood": "auto"
}
}下一步优化
优先级 P0(核心功能完善)
1. 音量自适应优化
问题:不同 BGM 源文件音量差异大(-50dB 到 -20dB)
方案:
# 在 MusicEngine 中添加音量检测
def analyze_bgm_volume(bgm_path: str) -> float:
"""使用 FFmpeg volumedetect 分析音量"""
cmd = ['ffmpeg', '-i', bgm_path, '-af', 'volumedetect', '-f', 'null', '-']
result = subprocess.run(cmd, capture_output=True, text=True)
# 解析平均音量
match = re.search(r'mean_volume: ([-\d.]+) dB', result.stderr)
return float(match.group(1)) if match else -20.0
def auto_adjust_volume(bgm_volume: float, mean_volume: float, voice_volume: float) -> float:
"""自动计算补偿音量"""
target_diff = -12 # BGM 比人声低 12dB
actual_diff = voice_volume - mean_volume
compensation = target_diff - actual_diff
return bgm_volume * (10 ** (compensation / 20))工作量:2 人天
2. 模板缩略图生成
问题:template_market.json 中的缩略图路径不存在
方案:
# 新增 src/utils/template_thumbnail_generator.py
def generate_template_thumbnail(template_id: str) -> str:
"""生成模板缩略图"""
config = get_template_config(template_id)
# 使用 FFmpeg 生成示例片头
intro_path = generate_intro(
title='示例标题',
subtitle='副标题',
template=config['intro_config']['template']
)
# 提取第一帧作为缩略图
thumb_path = f'static/templates/{template_id}.jpg'
subprocess.run([
'ffmpeg', '-i', intro_path,
'-vframes', '1',
'-vf', 'scale=320:568',
thumb_path
])
return thumb_path工作量:1 人天
优先级 P1(用户体验提升)
3. 前端模板选择器
目标:在前端添加可视化模板选择界面
方案:
<!-- StoryBoardStep4Export.vue -->
<el-dialog title="选择包装模板" v-model="templateDialogVisible">
<div class="template-grid">
<div
v-for="tpl in templates"
:key="tpl.id"
class="template-card"
@click="selectTemplate(tpl.id)"
>
<img :src="tpl.thumbnail" />
<h4>{{ tpl.name }}</h4>
<p>{{ tpl.description }}</p>
</div>
</div>
</el-dialog>接口调用:
async loadTemplates() {
const res = await fetch('http://pybridge:8787/templates')
this.templates = res.templates
}
selectTemplate(templateId) {
const manager = new TemplateManager()
const config = manager.apply_template(
templateId,
this.storyboardMeta.title
)
Object.assign(this.options, config)
}工作量:2 人天
4. 实时预览片头片尾
目标:用户修改标题后立即预览效果
方案:
async previewIntro() {
const res = await fetch('http://pybridge:8787/generate-intro-preview', {
method: 'POST',
body: JSON.stringify({
title: this.options.intro_config.title,
subtitle: this.options.intro_config.subtitle,
template: this.options.intro_config.template
})
})
this.previewVideoUrl = res.preview_url
this.$refs.previewPlayer.play()
}后端接口:
@app.post("/generate-intro-preview")
def generate_intro_preview(req: dict):
generator = IntroOutroGenerator()
intro_path = generator.generate_intro(
title=req['title'],
subtitle=req['subtitle'],
template=req['template'],
duration=3.0
)
return {"preview_url": f"/static/tmp/{os.path.basename(intro_path)}"}工作量:3 人天
优先级 P2(差异化功能)
5. 花字贴纸系统
目标:自动在关键词位置添加装饰文字
技术方案:
# src/ai_processors/keyword_decorator.py
import jieba
from collections import Counter
class KeywordDecorator:
"""关键词花字生成器"""
STICKER_TEMPLATES = {
'emoji': '🎉', # 情感类
'highlight': '★', # 强调类
'trend': '🔥' # 热点类
}
def extract_keywords(self, srt_text: str, top_k: int = 5) -> List[str]:
"""使用 jieba 提取高频关键词"""
words = jieba.cut(srt_text)
# 过滤停用词
filtered = [w for w in words if len(w) > 1]
counter = Counter(filtered)
return [word for word, _ in counter.most_common(top_k)]
def add_stickers(self, video_path: str, keywords: List[str], srt_segments: List[dict]) -> str:
"""在关键词出现位置添加花字"""
filters = []
for keyword in keywords:
# 找到关键词出现的时间点
for seg in srt_segments:
if keyword in seg['text']:
start_time = seg['start']
# 添加 drawtext 滤镜
filters.append(
f"drawtext=text='{self.STICKER_TEMPLATES['emoji']}':fontsize=80:"
f"x=(w-text_w)/2:y=h-200:enable='between(t,{start_time},{start_time+1})'"
)
# 应用滤镜
output_path = video_path.replace('.mp4', '_decorated.mp4')
cmd = ['ffmpeg', '-i', video_path, '-vf', ','.join(filters), output_path]
subprocess.run(cmd, check=True)
return output_path依赖:
pip install jieba工作量:5 人天
6. 音效库集成
目标:在转场时自动添加音效(whoosh/click)
方案:
# src/ai_processors/sound_effects.py
class SoundEffectsEngine:
"""音效引擎"""
EFFECT_MAPPING = {
'fade': 'whoosh',
'wipeleft': 'swipe',
'circlecrop': 'pop'
}
def download_sound_effect(self, effect_type: str) -> str:
"""从 Freesound API 下载音效"""
query = self.EFFECT_MAPPING.get(effect_type, 'click')
url = f"https://freesound.org/apiv2/search/text/?query={query}&filter=duration:[0.1 TO 1]"
# 下载逻辑...
return local_path
def add_sound_effects(self, video_path: str, transitions: List[dict]) -> str:
"""在转场位置添加音效"""
audio_filters = []
for i, trans in enumerate(transitions):
effect_path = self.download_sound_effect(trans['type'])
offset = trans['start_time']
# 使用 amix 混入音效
audio_filters.append(f"[{i}:a]adelay={offset*1000}|{offset*1000}[sfx{i}]")
# 混音
# 实现细节...工作量:4 人天
7. 用户自定义模板
目标:允许用户保存和分享自己的包装配置
数据库表设计:
CREATE TABLE `user_packaging_templates` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`user_id` INT NOT NULL,
`template_name` VARCHAR(100),
`config_json` TEXT,
`thumbnail_url` VARCHAR(255),
`is_public` TINYINT DEFAULT 0,
`use_count` INT DEFAULT 0,
`created_at` DATETIME
);API 设计:
@app.post("/templates/user/save")
def save_user_template(req: dict):
"""保存用户自定义模板"""
template_id = insert_into_db({
'user_id': req['user_id'],
'template_name': req['name'],
'config_json': json.dumps(req['config']),
'is_public': req.get('is_public', False)
})
return {"success": True, "template_id": template_id}
@app.get("/templates/user/{user_id}")
def get_user_templates(user_id: int):
"""获取用户的自定义模板"""
templates = query_from_db(user_id)
return {"success": True, "templates": templates}工作量:6 人天
8. A/B 测试框架
目标:测试不同配置的用户留存率,优化推荐算法
方案:
# src/ai_processors/ab_test_engine.py
class ABTestEngine:
"""A/B 测试引擎"""
def assign_variant(self, user_id: int, experiment_id: str) -> str:
"""根据用户 ID 分配测试变体"""
hash_value = hashlib.md5(f"{user_id}_{experiment_id}".encode()).hexdigest()
return 'A' if int(hash_value, 16) % 2 == 0 else 'B'
def get_config(self, variant: str) -> dict:
"""获取变体配置"""
configs = {
'A': {'color_preset': 'fresh', 'bgm_volume': 3.0},
'B': {'color_preset': 'warm', 'bgm_volume': 4.0}
}
return configs[variant]
def log_event(self, user_id: int, variant: str, event: str):
"""记录用户行为"""
# 写入数据库或 ClickHouse
pass指标监控:
- 合成完成率
- 用户保存率
- 分享率
工作量:8 人天
优先级 P3(长期优化)
9. 风格迁移(StyleGAN)
目标:将艺术风格应用到视频
技术栈:
- PyTorch
- StyleGAN2
- GPU 必需
工作量:20 人天
10. 3D 片头生成(Blender API)
目标:生成 3D 动画片头
工作量:25 人天
性能优化
当前性能瓶颈
Librosa 音频分析:10s 视频需 2-3s 分析
- 优化方案:异步分析 + Redis 缓存结果
CLIP 模型加载:首次加载需 5-10s
- 优化方案:服务启动时预加载模型
FFmpeg 调色处理:增加 20% 合成时间
- 优化方案:仅对关键帧应用调色,降低质量要求
并发限制
当前配置:
# pybridge/.env
MAX_CONCURRENT_TASKS=3
MIN_FREE_DISK_GB=5建议:
- CPU 节点:2-3 并发
- GPU 节点:5-8 并发
测试指南
单元测试
cd pybridge
python -m pytest tests/test_intro_outro_generator.py
python -m pytest tests/test_color_grading.py
python -m pytest tests/test_template_manager.py集成测试
# 测试完整智能包装流程
curl -X POST http://localhost:8787/compose-timeline-ffmpeg \
-H "Content-Type: application/json" \
-d @tests/fixtures/smart_packaging_payload.json性能测试
# 测试 BGM 分析性能
python tests/benchmark_music_selector.py
# 测试 CLIP 分析性能
python tests/benchmark_clip_analyzer.py故障排查
常见问题
1. librosa 导入失败
现象:
ImportError: cannot import name 'resample' from 'librosa'解决:
pip install librosa==0.10.0 soundfile numpy2. CLIP 分析返回 fallback
原因:torch 或 CLIP 未安装
解决:
pip install torch torchvision
pip install git+https://github.com/openai/CLIP.git3. 片头片尾生成失败
日志:
stage:intro_outro:start
intro/outro generation failed: No such file or directory原因:临时目录权限问题
解决:
chmod 777 /home/wwwroot/stooland/pybridge/tmp相关文档
更新日志
| 日期 | 版本 | 变更内容 |
|---|---|---|
| 2026-01-28 | v1.0.0 | 完成 Phase 1-3 所有功能 |
| 2026-01-28 | v1.0.1 | 修复 BGM 音量截断问题 |
| 2026-01-28 | v1.1.0 | 新增模板市场和 CLIP 分析 |