aivideo 开发手册
版本: v2.0
日期: 2026-04-16
基于: 三方框架集成审查、重构方案、Bug修复记录、功能总结等8份核心文档 + 代码库深度扫描整合
目录
第一章 项目概述与架构
1.1 项目定位
aivideo 是一个从原子素材到剪映工程文件的自动化工厂,同时支持正向生成(图文→视频)与逆向解析(视频→可编辑工程)。它不是简单的"文案转视频"工具,而是一个视频工程编译器,既能从零生成,也能从成品逆向重建。
核心能力矩阵
| 能力维度 |
具体能力 |
说明 |
| 双向桥梁 |
正向:文字/图片→结构化草稿;逆向:MP4→可编辑剪映工程 |
支持完整的双向工作流 |
| 多引擎编排 |
TTS四后端(Kokoro/Edge/Piper/Chatterbox)自动降级;导出三策略(剪映自动/FFmpeg直出/MoviePy) |
灵活的引擎选择与降级机制 |
| 模板化视频语言 |
运动库(10种镜头)、转场库(5种)、节奏库(3种)可组合 |
代码描述"视频语言" |
| 生产级草稿兼容 |
100%复刻剪映draft_content.json结构 |
含关键帧/遮罩/滤镜/动画 |
| 可扩展钩子 |
12个生命周期的HookPoint,可注入Whisper/RealESRGAN/RIFE |
灵活的扩展机制 |
| 配置化流水线 |
9大配置模块,支持环境变量/YAML/JSON,一键切换风格 |
快速风格切换 |
1.2 架构总览
aivideo/ # v19.0.0
├── __init__.py # 顶层导出: AivideoConfig, VideoService, EventBus, HookManager...
├── __main__.py # 入口
├── cli.py # CLI命令行 (20+子命令)
├── container.py # DI容器 (ApplicationContainer)
│
├── document/ # 文档模型层 (pyCapCut兼容)
│ ├── script_file.py # 脚本文件(核心)
│ ├── draft_folder.py # 草稿目录管理
│ ├── track.py # 轨道模型
│ ├── segment.py # 片段基类
│ ├── video_segment.py # 视频/贴纸/图片片段
│ ├── text_segment.py # 文本片段
│ ├── audio_segment.py # 音频片段
│ ├── effect_segment.py # 特效/滤镜片段
│ ├── animation.py # 动画模型
│ ├── keyframe.py # 关键帧
│ ├── local_materials.py # 本地素材模型
│ ├── time_util.py # 时间工具
│ ├── template_mode.py # 模板模式
│ ├── narration_sync.py # 旁白同步
│ ├── synonym_search.py # 同义词搜索
│ ├── exceptions.py # 异常体系
│ ├── compat.py # 兼容层
│ ├── util.py # 通用工具
│ ├── metadata/ # 元数据枚举 (16个文件)
│ └── assets/ # 资产定义
│
├── skills/jianying_editor/ # 剪映技能层 (jianying-skill兼容)
│ ├── jy_wrapper.py # JyProject (组合: Base+Media+Text+Vfx)
│ ├── core/
│ │ ├── project_base.py # 项目基类(生命周期管理)
│ │ ├── media_ops.py # 媒体操作
│ │ ├── text_ops.py # 文本操作
│ │ └── vfx_ops.py # 特效操作
│ ├── utils/
│ │ ├── config.py # 配置管理
│ │ └── errors.py # 技能层错误
│ ├── scripts/ # 10+独立脚本
│ └── data/ # 数据资产
│
├── engines/ # 引擎层 (25个文件)
│ ├── base.py # BaseEngine (ABC)
│ ├── base_video_engine.py # IVideoEngine (ABC) + EngineCapability
│ ├── engine_factory.py # EngineFactory (注册/创建/自动选择)
│ ├── draft_builder_core.py # 草稿构建核心
│ ├── draft_builder_engine.py # 草稿构建引擎(门面)
│ ├── reverse_engine.py # 逆向引擎
│ ├── dual_style_engine.py # 双风格引擎
│ ├── export_engine.py # 导出引擎(3种策略)
│ ├── tts_engine.py # TTS引擎(4后端)
│ ├── asr_engine.py # ASR引擎
│ ├── asr_sync.py # ASR同步引擎
│ ├── ai_content_engine.py # AI内容生成引擎
│ ├── image_engine.py # 图片处理引擎
│ ├── moviepy_engine.py # MoviePy渲染引擎
│ ├── ffmpeg_engine.py # FFmpeg渲染引擎
│ ├── hardware_detector.py # 硬件检测
│ ├── jianying_controller.py # 剪映UI自动化
│ ├── video_importer.py # 视频导入器
│ ├── draft_template.py # 模板管理+质量检查+批量生成
│ ├── track_builder.py # 轨道构建器
│ ├── draft_renderer.py # 草稿渲染器
│ ├── draft_remixer_engine.py # 草稿混剪引擎
│ ├── adaptive_encoder.py # 自适应编码器
│ └── render_enhancements.py # 渲染增强(CRF/音频归一化/Ken Burns)
│
├── core/ # 核心基础设施层 (37个文件)
│ ├── video_service.py # VideoService (DI门面)
│ ├── event_bus.py # EventBus (30+事件类型)
│ ├── state_machine.py # BuildStateMachine (11个状态)
│ ├── error_handler.py # BuildErrorHandler
│ ├── exceptions.py # 统一异常体系 (25+异常类)
│ ├── artifact_store.py # ArtifactStore (产物版本化存储)
│ ├── quality_gate.py # QualityGate (质量门控)
│ ├── project.py # Project (项目工程管理)
│ ├── result.py # Result[T] (统一返回类型)
│ ├── draft_ops.py # 草稿操作工具
│ ├── draft_validator.py # DraftValidator
│ ├── timeline_manager.py # TimelineManager
│ ├── subtitle_timing.py # SubtitleTimingCalculator
│ ├── audio_sync_service.py # AudioSyncService
│ ├── template_engine.py # TemplateFactory + DraftAssembler
│ ├── motion_library.py # MotionLibrary (10种镜头)
│ ├── rhythm_library.py # RhythmLibrary (3种节奏)
│ ├── transition_library.py # TransitionLibrary (5种转场)
│ ├── visual_hierarchy.py # VisualHierarchyBuilder
│ ├── audio_mixer.py # AudioMixer
│ ├── storyboard.py # StoryboardPlanner
│ ├── storyboard_strategies.py # 神话场景分镜策略
│ ├── storyboard_remixer.py # StoryboardRemixer
│ ├── style_presets.py # StylePresetLibrary
│ ├── vision_provider.py # VisionProvider (图片分析)
│ ├── bgm_search.py # BgmSearchService
│ ├── media_normalizer.py # MediaNormalizer
│ ├── media_probe.py # 媒体探测
│ ├── id_generator.py # ID生成器
│ ├── subprocess_utils.py # 安全子进程封装
│ ├── safe_path.py # SafePathHandler
│ ├── rule_engine.py # RuleEngine
│ ├── constants.py # 全局常量
│ ├── base_service.py # BaseService (ABC)
│ ├── workflow_context.py # WorkflowContext
│ └── logging_config.py # 日志配置
│
├── pipeline/ # 流水线编排层
│ ├── pipeline.py # Pipeline (18步完整流程)
│ ├── models.py # EssayData, BuildResult, StyleProfile...
│ ├── batch.py # BatchPipelineExecutor
│ ├── state.py # PipelineState (断点续传)
│ ├── nodes.py # PipelineNode (ABC) + PipelineScheduler (DAG)
│ ├── style_comparison.py # StyleComparisonReport
│ └── mythology_builder.py # 神话风格构建器
│
├── config/ # 配置中心
│ ├── defaults.py # AivideoConfig (9个子配置)
│ ├── schema.py # 配置校验Schema
│ ├── settings.py # Settings (YAML/JSON加载)
│ ├── config_manager.py # ConfigManager (多环境分层合并)
│ └── templates.py # SceneTemplate + 预置模板
│
├── api/ # 高级API层
│ ├── director_api.py # DirectorAPI (AI Agent接口)
│ ├── command_api.py # VideoCommandAPI
│ ├── media_api.py # MediaAPI
│ ├── text_api.py # TextAPI
│ ├── vfx_api.py # VFXAPI
│ ├── export_api.py # ExportAPI
│ ├── mcp_server.py # MCPRpcHandler (JSON-RPC 2.0)
│ └── http_api.py # HTTP API
│
├── hooks/ # 钩子系统 (9个文件)
│ ├── base.py # BaseHook + HookPoint + HookManager
│ ├── context.py # HookContext
│ ├── whisper_hook.py # WhisperHook (字幕生成)
│ ├── realesrgan_hook.py # RealESRGANHook (图片超分)
│ ├── clipsai_hook.py # ClipsAIHook (高光提取)
│ ├── videogrep_hook.py # VideogrepHook (超剪)
│ ├── rife_hook.py # RIFEHook (视频插帧)
│ ├── ken_burns_hook.py # KenBurnsHook (Ken Burns效果)
│ └── quality_gate_hook.py # QualityGateHook (质量门控)
│
├── integrations/ # 外部集成抽象层
│ ├── plugin_manager.py # PluginManager
│ ├── capcut_mate.py # CapCutMateClient
│ ├── llm/base.py # LLMProvider (ABC)
│ ├── tts/base.py # TTSBackend (ABC)
│ ├── tts/edge_tts.py # EdgeTTSBackend
│ ├── asr/base.py # ASRBackend (ABC)
│ ├── asr/whisper_asr.py # WhisperASRBackend
│ └── image_gen/ # ImageGenerator (ABC) + OpenAI实现
│
├── adapters/ # 剪映版本适配层
│ ├── base_adapter.py # DraftAdapter (ABC)
│ ├── jianying_v5_adapter.py # JianyingV5Adapter
│ └── capcut_api_adapter.py # CapCutAPIAdapter
│
├── workflow/ # DAG工作流引擎
│ ├── engine.py # WorkflowEngine
│ ├── nodes.py # 7个标准节点
│ └── advanced_nodes.py # 8个高级节点(条件/并行/循环/人工审核)
│
├── features/ # 创新功能模块
│ ├── smart_cut_scheduler.py # SmartCutScheduler
│ ├── audio_master.py # AudioMaster
│ ├── ai_video_generator.py # AIVideoGenerator
│ ├── multi_platform_exporter.py # MultiPlatformExporter
│ └── video_analytics.py # VideoAnalytics
│
├── services/ # 服务层
│ ├── video_draft_service.py # VideoDraftService (统一服务)
│ ├── asset_providers.py # 素材提供者
│ ├── cloud_manager.py # CloudManager
│ ├── auto_import_service.py # AutoImportService
│ ├── draft_sync_service.py # DraftSyncService (双向同步)
│ ├── draft_watcher.py # DraftWatcher (自动监控)
│ └── remix_service.py # RemixService
│
├── templates/ # 模板系统
│ ├── export_configs.py # 导出配置模板
│ ├── scene_templates.py # 场景模板
│ └── tts_configs.py # TTS配置模板
│
├── tools/ # 命令行工具
│ ├── run_dual_style.py # 双风格运行工具
│ └── draft_polish.py # 草稿润色工具
│
└── utils/ # 工具函数
├── retry.py # 重试工具
└── structured_logging.py # 结构化日志
1.3 数据流概览
1.3.1 正向生成流程
Pipeline.run()
│
├─ 1. AIContentEngine.generate_essay() → EssayData
├─ 2. AIContentEngine.extract_vocabulary() → VocabularyItem[]
├─ 3. AIContentEngine.generate_image_prompt() → prompt[]
├─ 4. ImageEngine.process() → images[]
├─ 5. TTSEngine.synthesize_sync() → audio_paths[]
├─ 6. ASREngine.recognize() → subtitles[]
├─ 7. DraftBuilderCore.build() → draft_path
│ ├─ TrackBuilder → Track + Segment
│ ├─ ScriptFile.add_segment() → 素材注册
│ └─ DraftFolder.finalize_draft() → 素材打包+路径修正+封面
├─ 8. QualityGate.check() → ValidationReport
├─ 9. ExportEngine.export_mp4() → output.mp4
└─ 10. DraftFolder.import_draft() → 剪映目录
1.3.2 逆向解析流程
VideoReverseEngine.reverse_to_draft()
│
├─ detect_scenes() → scene_list
├─ extract_keyframes() → keyframes[]
├─ ASREngine.recognize() → subtitles[]
├─ DraftBuilderCore.build() → draft_path
└─ DraftFolder.import_draft() → 剪映目录
1.3.3 双风格对比流程
DualStyleEngine.generate_all()
│
├─ _run_single_style(style_1) → draft_1
├─ _run_single_style(style_2) → draft_2
├─ StyleComparisonReport.generate() → comparison_report.json
└─ _import_to_jianying() → 剪映目录
1.3.4 核心数据转换链
ScriptFile.dumps() → draft_content.json
DraftFolder.finalize_draft() → 素材打包 + 路径修正 + 封面生成
DraftFolder.import_draft() → 复制到剪映目录 + update_content_paths() + update_meta_paths()
第二章 模块参考
2.1 文档模型层 (document/)
2.1.1 ScriptFile — 脚本文件核心
ScriptFile 是草稿内容的核心容器,管理轨道、片段和素材的注册关系。
from aivideo.document.script_file import ScriptFile
from aivideo.document.time_util import Timerange
script = ScriptFile(height=1080, width=1920, fps=30.0)
script.add_track("VideoTrack0", track_type=TrackType.video)
script.add_segment(video_segment, "VideoTrack0")
output_json = script.dumps()
关键方法:
| 方法 |
说明 |
返回值 |
add_track(name, track_type) |
添加轨道 |
Track 对象 |
add_segment(segment, track_name) |
添加片段并注册素材 |
BaseSegment |
add_segment_chain(segment, track_name) |
链式调用版本(返回self) |
ScriptFile |
dumps() |
导出为JSON字符串 |
str |
load_template(path) |
加载模板 |
ScriptFile |
素材注册机制: add_segment() 会根据片段类型自动将素材注册到 ScriptMaterial 的对应列表中:
| 片段类型 |
注册的素材列表 |
| VideoSegment |
videos, speeds |
| AudioSegment |
audios, speeds, loudnesses, sound_channel_mappings, vocal_separations |
| TextSegment |
texts, animations, filters(speed/bubble/effect) |
| EffectSegment |
effects |
| FilterSegment |
filters |
| StickerSegment |
stickers |
重要: add_segment() 内部的 if-elif 链中,同一类型只能出现一次分支。重复的 elif 分支会成为死代码,导致素材注册遗漏(参见5.1.2 Bug 2)。
2.1.2 Timerange — 时间范围
所有时间值以微秒为单位。
from aivideo.document.time_util import Timerange, tim, tim_seconds, SEC
tr = Timerange(start=0, duration=5_000_000) # 5秒
tim(1000000) # int → 直接返回: 1000000
tim(1.5) # float → 视为微秒取整: 2
tim_seconds(1.5) # 秒 → 微秒: 1500000
tim("00:00:05.000") # 时间字符串 → 微秒
tim() 函数语义:
| 输入类型 |
pycapcut语义 |
aivideo语义 |
说明 |
int |
直接返回 |
直接返回 |
一致 |
float |
视为微秒,取整 |
视为微秒,取整 |
统一后一致 |
str |
时间字符串解析 |
时间字符串解析 |
一致 |
注意: 使用 tim_seconds() 将秒数转换为微秒,避免语义混淆。
2.1.3 片段模型
VideoSegment / AudioSegment
from aivideo.document.video_segment import VideoSegment
from aivideo.document.audio_segment import AudioSegment
seg = VideoSegment(
material=video_material,
target_timerange=Timerange(0, 5_000_000),
source_timerange=Timerange(0, 5_000_000),
speed=2.0 # 2倍速
)
source_timerange + speed 联动逻辑: 当 source_timerange 和 speed 同时指定时,自动计算 target_timerange.duration:
if source_timerange is not None and speed is not None:
calculated_duration = int(source_timerange.duration / speed)
if target_timerange is not None:
target_timerange.duration = calculated_duration
else:
target_timerange = Timerange(start=0, duration=calculated_duration)
素材时长越界检查: 构造时检查 source_timerange.end > material.duration,越界抛出 CoreValidationError。
TextSegment
from aivideo.document.text_segment import TextSegment
tseg = TextSegment(
content="Hello World",
target_timerange=Timerange(0, 3_000_000),
style=TextStyle(font_size=8.0, color=(1.0, 1.0, 1.0)),
font=FontResource(path="D:/.../zh-hans.ttf"),
border=TextBorder(width=0.08, color=(0.94, 0.92, 0.92))
)
export_material() 字段填充: 顶层字段(font_path, border_color, text_color等)从内部属性动态填充,而非硬编码空值。
EffectSegment / FilterSegment
from aivideo.document.effect_segment import EffectSegment, FilterSegment
eff = EffectSegment(effect=effect_data, ...)
filt = FilterSegment(filter_meta=filter_data, ...)
兼容参数名: effect_type 是 effect 的别名,meta 是 filter_meta 的别名。
2.1.4 轨道模型 (Track)
from aivideo.document.track import Track, TrackType, Track_meta
track = Track(name="VideoTrack0", track_type=TrackType.video)
TrackType 与 render_index 对照:
| TrackType |
片段类 |
render_index |
is_default |
| video |
VideoSegment |
0 |
True |
| audio |
AudioSegment |
10000 |
True |
| text |
TextSegment |
15000 |
True |
| effect |
EffectSegment |
20000 |
False |
| filter |
FilterSegment |
25000 |
False |
| sticker |
StickerSegment |
30000 |
False |
注意: text 的 render_index 必须为 15000(非14000),否则与 sticker 冲突。
2.1.5 异常体系
from aivideo.document.exceptions import (
TrackNotFound, # 继承 UniVideoError + NameError
AmbiguousTrack, # 继承 UniVideoError + ValueError
SegmentOverlapError, # 继承 UniVideoError + ValueError
MaterialNotFound, # 继承 UniVideoError + NameError
ExtensionFailed, # 继承 UniVideoError + ValueError
AutomationError, # 继承 UniVideoError + Exception
ExportTimeoutError, # 继承 UniVideoError + Exception
)
双继承设计: 异常类同时继承 UniVideoError 和标准异常(NameError/ValueError/Exception),确保 isinstance(e, ValueError) 和 isinstance(e, UniVideoError) 都能正确匹配。
兼容别名:
SegmentOverlap = SegmentOverlapError
ExportTimeout = ExportTimeoutError
2.1.6 动画模型 (Animation)
from aivideo.document.animation import TextAnimationClip, Text_animation
anim = TextAnimationClip(
name="模糊渐显",
animation_type="in",
resource_id="7473710410428846608",
start=0,
duration=2_000_000
)
export_json() 必需字段:
| 字段 |
说明 |
示例值 |
| category_id |
动画分类ID |
“in” / “out” / “group” / “loop” |
| category_name |
动画分类名称 |
“入场” / “出场” / “组合” / “循环” |
| request_id |
请求ID |
“” |
| path |
路径 |
“” |
| type |
动画类型 |
“in” |
| name |
动画名称 |
“模糊渐显” |
| id |
效果ID |
UUID |
| resource_id |
资源ID |
资源ID字符串 |
| start |
开始时间(微秒) |
0 |
| duration |
持续时间(微秒) |
2000000 |
category_id 映射:
category_map = {
"in": ("in", "入场"),
"out": ("out", "出场"),
"group": ("group", "组合"),
"loop": ("loop", "循环"),
}
兼容别名: Text_animation = TextAnimationClip
2.1.7 本地素材模型 (LocalMaterials)
from aivideo.document.local_materials import VideoMaterial, AudioMaterial
vmat = VideoMaterial(path="D:/images/img1.png")
amat = AudioMaterial(path="D:/audio/voiceover.mp3")
路径机制:
VideoMaterial._get_placeholder_path() → 返回绝对路径
AudioMaterial._get_placeholder_path() → 返回绝对路径
- 占位符前缀:
##_draftpath_placeholder_{draft_id}_##
2.1.8 关键帧模型 (Keyframe)
from aivideo.document.keyframe import KeyframeProperty, KeyframeList
# uniform_scale 与 scale_x/scale_y 互斥
segment.add_keyframe(KeyframeProperty.uniform_scale, 0, 1.2)
# ❌ 不能再添加 scale_x 或 scale_y
互斥规则: uniform_scale 与 scale_x/scale_y 互斥,添加时会校验并抛出 CoreValidationError。
2.1.9 旁白同步 (narration_sync)
from aivideo.document.narration_sync import (
split_by_punctuation,
split_bilingual,
generate_narrated_subtitles,
)
segments = split_by_punctuation("这是一段中文文本。包含多个句子。")
bilingual = split_bilingual("This is English. 这是中文。")
subtitles = generate_narrated_subtitles(text, audio_duration=30.0)
2.1.10 同义词搜索 (synonym_search)
from aivideo.document.synonym_search import resolve_enum_with_synonyms, EFFECT_SYNONYMS
key = resolve_enum_with_synonyms("模糊渐显", EFFECT_SYNONYMS)
2.1.11 元数据枚举 (metadata/)
metadata/ 子目录包含16个元数据枚举文件,定义了剪映草稿中所有标准化的类型枚举:
| 文件 |
枚举类 |
说明 |
effect_meta.py |
EffectMeta |
特效元数据 |
font_meta.py |
FontType |
字体类型枚举 |
mask_meta.py |
MaskMeta, MaskType |
遮罩类型 |
filter_meta.py |
FilterType |
滤镜类型枚举 |
transition_meta.py |
TransitionMeta, TransitionType |
转场类型 |
text_intro.py |
TextIntro |
文字入场动画 |
text_outro.py |
TextOutro |
文字出场动画 |
text_loop.py |
TextLoopAnim |
文字循环动画 |
video_intro.py |
IntroType |
视频入场 |
video_outro.py |
OutroType |
视频出场 |
video_group_animation.py |
GroupAnimationType |
组合动画 |
video_scene_effect.py |
VideoSceneEffectType |
视频场景特效 |
video_character_effect.py |
VideoCharacterEffectType |
视频人物特效 |
audio_scene_effect.py |
AudioSceneEffectType |
音频场景效果 |
tone_effect.py |
— |
音调效果 |
speech_to_song.py |
— |
语音转歌曲 |
2.1.12 模板模式 (template_mode)
from aivideo.document.template_mode import (
ShrinkMode, ExtendMode,
ImportedSegment, ImportedMediaSegment,
ImportedTrack, EditableTrack,
ImportedTextTrack, ImportedMediaTrack,
import_track,
)
2.1.13 通用工具 (util)
from aivideo.document.util import (
provide_ctor_defaults,
assign_attr_with_json,
export_attr_to_json,
merge_timeranges,
clamp,
)
2.2 剪映技能层 (skills/jianying_editor/)
2.2.1 JyProject — 项目基类
JyProject 是剪映项目的高级封装,提供完整的生命周期管理。
from aivideo.skills.jianying_editor import JyProject
project = JyProject("我的项目", width=1920, height=1080, fps=30)
project.add_video("clip.mp4", track=0)
project.add_text_simple("标题", start_time=0, duration=5.0)
project.save()
project.open_in_jianying()
生命周期方法:
| 方法 |
说明 |
save() |
保存脚本内容到文件 |
build() |
构建草稿目录 |
open_in_jianying() |
在剪映中打开 |
轨道管理:
| 方法 |
说明 |
get_total_duration() |
获取总时长 |
list_tracks() |
列出所有轨道 |
remove_track(name) |
移除轨道 |
素材替换:
| 方法 |
说明 |
replace_material_by_name() |
按名称替换素材 |
replace_material_by_seg() |
按片段替换素材 |
replace_text() |
替换文本内容 |
模板管理:
| 方法 |
说明 |
import_track() |
导入轨道 |
import_template() |
导入模板 |
export_template() |
导出模板 |
2.2.2 媒体操作 (media_ops)
project.add_video("clip.mp4", track=0)
project.add_audio("bgm.mp3", track=0)
project.add_media_safe("maybe_missing.mp4") # 安全添加,缺失时返回None
project.add_audio_effect(segment, effect_type="fade_in")
project.add_audio_fade(segment, fade_in=1.0, fade_out=0.5)
project.add_audio_keyframe(segment, property="volume", time=1.0, value=0.8)
2.2.3 文本操作 (text_ops)
project.add_styled_text("标题", style=preset_style)
project.add_text_from_template(template_name="subtitle")
project.add_text_bubble("气泡文字", bubble_type="round")
project.add_text_effect("特效文字", effect_name="typewriter")
project.import_srt("subtitle.srt")
2.2.4 特效操作 (vfx_ops)
project.add_filter_simple("净透", track=0)
project.add_video_animation("模糊渐显", segment=seg)
project.add_video_effect("老电影", segment=seg)
project.add_video_mask(mask_type="rectangle", segment=seg)
project.add_video_fade(fade_in=1.0, fade_out=0.5, segment=seg)
project.add_video_background("blur", segment=seg)
project.add_sticker_at(sticker_id="xxx", position=(0.5, 0.5))
2.3 引擎层 (engines/)
2.3.1 DraftBuilderCore — 草稿构建核心
from aivideo.engines.draft_builder_core import DraftBuilderCore
builder = DraftBuilderCore(
title="项目标题",
width=1920, height=1080, fps=30
)
builder.add_image_track(images, durations, motion="dramatic_reveal")
builder.add_voiceover(text, speaker="zh-CN-YunxiNeural")
builder.add_bgm("bgm.mp3")
draft_path = builder.build(output_dir)
核心方法:
| 方法 |
说明 |
init_script() |
初始化脚本 |
add_video_track() |
添加视频轨道 |
add_text_tracks() |
添加文本轨道 |
add_audio_tracks() |
添加音频轨道 |
add_effects() |
添加特效 |
finalize() |
最终化 |
build() |
完整构建 |
2.3.2 DraftBuilderEngine — 草稿构建引擎(门面)
from aivideo.engines.draft_builder_engine import DraftBuilderEngine
engine = DraftBuilderEngine()
engine.build(config)
engine.import_video(video_path)
engine.render_draft(draft_path)
engine.check_ready()
DraftBuilderEngine 是 DraftBuilderCore 的薄门面层,通过 @register_engine('draft_builder') 注册到 EngineFactory。
2.3.3 EngineFactory — 引擎工厂
from aivideo.engines.engine_factory import EngineFactory
EngineFactory.register("draft_builder", DraftBuilderEngine)
engine = EngineFactory.create("draft_builder")
engine = EngineFactory.auto_select(requirements=[EngineCapability.DRAFT_BUILD])
engines = EngineFactory.list_engines()
2.3.4 ExportEngine — 导出引擎
from aivideo.engines.export_engine import ExportEngine
engine = ExportEngine()
engine.export_mp4(draft_path, output_path, strategy="ffmpeg_direct")
三种导出策略:
| 策略 |
说明 |
适用场景 |
jianying_auto |
剪映自动导出 |
有剪映安装 |
ffmpeg_direct |
FFmpeg直出 |
无剪映,快速导出 |
moviepy |
MoviePy渲染 |
灵活控制 |
2.3.5 TTS引擎
四个后端:
| 后端 |
说明 |
适用场景 |
| Edge-TTS |
微软云端TTS,SSML支持好 |
开发测试 |
| Kokoro |
82M本地模型,速度极快 |
生产离线 |
| Piper |
轻量本地TTS |
低资源环境 |
| Chatterbox |
高品质TTS,需GPU |
极致音质 |
自动降级机制: Kokoro → Edge-TTS → Piper,按可用性自动切换。
from aivideo.engines.tts_engine import TTSEngine, TTSEngineType
engine = TTSEngine(backend=TTSEngineType.EDGE_TTS)
path = engine.synthesize_sync(text="Hello", speaker="zh-CN-YunxiNeural", output_path="out.mp3")
voices = engine.list_voices(language="zh")
lang = detect_language(text)
2.3.6 ASREngine — 语音识别引擎
from aivideo.engines.asr_engine import ASREngine
engine = ASREngine()
result = engine.recognize(audio_path)
aligned = engine.align_subtitles(audio_path, text_segments)
2.3.7 ASRSyncEngine — ASR同步引擎
from aivideo.engines.asr_sync import ASRSyncEngine
engine = ASRSyncEngine()
segments = engine.align(audio_path, reference_text)
数据模型: ASRSegment
2.3.8 AIContentEngine — AI内容生成引擎
from aivideo.engines.ai_content_engine import AIContentEngine
engine = AIContentEngine()
essay = engine.generate_essay(topic="八仙过海", style="cinematic")
vocab = engine.extract_vocabulary(essay)
prompts = engine.generate_image_prompt(scenes)
translated = engine.translate(text, target_lang="en")
scene = engine.image_to_scene(image_path)
prompts = engine.generate_scene_prompts(topic, num_scenes=8)
2.3.9 ImageEngine — 图片处理引擎
from aivideo.engines.image_engine import ImageEngine
engine = ImageEngine()
engine.remove_watermark(image_path, output_path)
engine.resize(image_path, width=1920, height=1080)
engine.convert_format(image_path, format="png")
2.3.10 逆向引擎 (reverse_engine)
from aivideo.engines.reverse_engine import VideoReverseEngine, VideoProbe
engine = VideoReverseEngine()
result = engine.reverse_to_draft(video_path, output_dir)
scenes = engine.detect_scenes(video_path)
keyframes = engine.extract_keyframes(video_path)
probe = VideoProbe()
info = probe.probe(video_path)
2.3.11 双风格引擎 (dual_style_engine)
from aivideo.engines.dual_style_engine import DualStyleEngine
engine = DualStyleEngine()
result = engine.generate_all(
topic="牛郎织女",
styles=["epic_cinematic", "ink_wash"],
images=image_pool,
output_dir="output"
)
重要: _import_to_jianying() 方法必须调用 update_content_paths() 进行路径替换(参见5.3节)。
2.3.12 渲染引擎 (IVideoEngine实现)
from aivideo.engines.base_video_engine import IVideoEngine, EngineCapability
from aivideo.engines.moviepy_engine import MoviePyEngine
from aivideo.engines.ffmpeg_engine import FFmpegEngine
IVideoEngine接口:
| 方法 |
说明 |
initialize() |
初始化 |
set_canvas() |
设置画布 |
add_background() |
添加背景 |
add_audio() |
添加音频 |
add_subtitle_sequence() |
添加字幕序列 |
render() |
渲染 |
cleanup() |
清理 |
2.3.13 HardwareDetector — 硬件检测
from aivideo.engines.hardware_detector import HardwareDetector
detector = HardwareDetector()
platform = detector.detect()
level = detector.get_acceleration_level()
数据模型: HardwarePlatform, AccelerationLevel
2.3.14 JianyingController — 剪映UI自动化
from aivideo.engines.jianying_controller import JianyingController
controller = JianyingController()
controller.open_draft(draft_path)
controller.export_video(resolution=ExportResolution.R_1080P, framerate=ExportFramerate.FPS_30)
数据模型: ExportResolution, ExportFramerate, ControlFinder
2.3.15 VideoImporter — 视频导入器
from aivideo.engines.video_importer import VideoImporter
importer = VideoImporter()
info = importer.probe(video_path)
draft_path = importer.import_video(video_path, output_dir)
数据模型: VideoInfo
2.3.16 DraftTemplateManager — 模板管理
from aivideo.engines.draft_template import DraftTemplateManager, DraftQualityChecker, BatchDraftGenerator
manager = DraftTemplateManager()
template = manager.load(template_name)
checker = DraftQualityChecker()
report = checker.check(draft_path)
generator = BatchDraftGenerator()
results = generator.generate_batch(template, variations=5)
数据模型: DraftQualityReport, TEMPLATES
2.3.17 TrackBuilder — 轨道构建器
from aivideo.engines.track_builder import TrackBuilder, create_track_builder
builder = create_track_builder()
builder.add_motion(motion="dramatic_reveal")
builder.add_transition(transition="cross_dissolve")
track = builder.build()
2.3.18 DraftRenderer — 草稿渲染器
from aivideo.engines.draft_renderer import DraftRenderer
renderer = DraftRenderer()
renderer.render(draft_path, output_path)
2.3.19 DraftRemixerEngine — 草稿混剪引擎
from aivideo.engines.draft_remixer_engine import DraftRemixerEngine
engine = DraftRemixerEngine()
result = engine.remix(draft_path, style="energetic")
2.3.20 AdaptiveEncoder — 自适应编码器
from aivideo.engines.adaptive_encoder import AdaptiveEncoder
encoder = AdaptiveEncoder()
encoder.encode(input_path, output_path, target_size_mb=50)
2.3.21 渲染增强 (render_enhancements)
from aivideo.engines.render_enhancements import CRFAdaptive, AudioNormalizer, KenBurnsEffect
crf = CRFAdaptive(profile=CRFProfile.BALANCED)
normalizer = AudioNormalizer()
kb = KenBurnsEffect()
数据模型: CRFProfile
2.4 核心基础设施层 (core/)
2.4.1 统一异常体系
from aivideo.core.exceptions import UniVideoError, CoreValidationError
异常分类体系 (25+异常类):
| 分类 |
异常类 |
说明 |
| 核心 |
UniVideoError |
统一异常基类 |
| 核心 |
CoreValidationError |
核心校验错误 |
| 媒体 |
MediaNotFoundError |
媒体未找到 |
| 媒体 |
FormatConversionError |
格式转换失败 |
| 媒体 |
ImageProcessingError |
图片处理失败 |
| 路径 |
PathSecurityError |
路径安全错误 |
| 草稿 |
DraftLockError |
草稿锁定 |
| 草稿 |
SegmentOverlapError |
片段重叠 |
| TTS |
TTSBackendError |
TTS后端错误 |
| 导出 |
ExportTimeoutError |
导出超时 |
| 导出 |
ExportStrategyError |
导出策略错误 |
| 配置 |
ConfigValidationError |
配置校验失败 |
| 配置 |
ConfigVersionError |
配置版本不兼容 |
| AI |
AIServiceError |
AI服务错误 |
| AI |
AIGenerationError |
AI生成失败 |
| 引擎 |
EngineError |
引擎错误 |
| 引擎 |
EngineUnavailableError |
引擎不可用 |
| 集成 |
IntegrationError |
集成错误 |
| 质量 |
QualityGateError |
质量门控失败 |
| 工作流 |
WorkflowTimeoutError |
工作流超时 |
| 工作流 |
WorkflowDeadlockError |
工作流死锁 |
| 工作流 |
WorkflowNodeError |
工作流节点错误 |
| ASR |
ASRError |
ASR错误 |
错误码体系 (ERROR_CODES): AV-0100 ~ AV-1302
2.4.2 VideoService — DI门面
from aivideo.core.video_service import VideoService
service = VideoService()
register_engine("draft_builder")
register_tool("ffmpeg", "FFmpeg视频处理")
register_workflow_node("tts", config)
2.4.3 EventBus — 事件总线
from aivideo.core.event_bus import EventBus, EventType, get_event_bus
bus = get_event_bus()
bus.emit(EventType.DRAFT_CREATED, data={"path": draft_path})
bus.on(EventType.DRAFT_CREATED, handler)
30+事件类型: DRAFT_CREATED, DRAFT_SAVED, BUILD_STARTED, BUILD_COMPLETED, EXPORT_STARTED, TTS_SYNTHESIZED, ERROR_OCCURRED 等
2.4.4 BuildStateMachine — 构建状态机
from aivideo.core.state_machine import BuildStateMachine, BuildState
sm = BuildStateMachine()
sm.transition(BuildState.INITIALIZING)
current = sm.current_state
11个状态: IDLE, INITIALIZING, GENERATING_CONTENT, PROCESSING_MEDIA, SYNTHESIZING_AUDIO, BUILDING_DRAFT, RENDERING, EXPORTING, IMPORTING, COMPLETED, FAILED
标准构建路径: STANDARD_BUILD_PATH 定义了合法的状态转换序列。
2.4.5 BuildErrorHandler — 构建错误处理
from aivideo.core.error_handler import BuildErrorHandler, VideoBuildError
handler = BuildErrorHandler()
result = handler.handle(error, context)
数据模型: ErrorSeverity, ErrorCategory, HandledError
2.4.6 ArtifactStore — 产物版本化存储
from aivideo.core.artifact_store import ArtifactStore
store = ArtifactStore(base_dir="artifacts")
store.save_draft(project_name, draft_path)
store.load_draft(project_name, version="latest")
versions = store.list_versions(project_name)
store.save_audio(project_name, audio_path)
store.save_subtitle(project_name, subtitle_path)
2.4.7 QualityGate — 质量门控
from aivideo.core.quality_gate import QualityGate
gate = QualityGate()
result = gate.check(draft_path)
内置检查器: SubtitleQualityChecker, ExportQualityGate
数据模型: QualityCheckResult
2.4.8 Project — 项目工程管理
from aivideo.core.project import Project
project = Project(name="我的项目", config=config)
project.save_draft_version(draft_path)
draft = project.load_draft_version(version="latest")
versions = project.list_versions()
info = project.get_info()
2.4.9 Result[T] — 统一返回类型
from aivideo.core.result import Result
result = Result.ok(value=draft_path)
result = Result.fail(error="构建失败", code="AV-0201")
if result.is_ok:
path = result.value
else:
error = result.error
2.4.10 DraftValidator — 草稿校验器
from aivideo.core.draft_validator import DraftValidator
validator = DraftValidator()
report = validator.validate(draft_path)
数据模型: ValidationReport
2.4.11 TimelineManager — 时间线管理器
from aivideo.core.timeline_manager import TimelineManager, TimelineConfig
manager = TimelineManager(config=TimelineConfig(total_duration=60.0))
slot = manager.allocate(segment_type=SegmentType.VIDEO, duration=5.0)
数据模型: TimelineConfig, TimeSlot, SegmentType
2.4.12 SubtitleTimingCalculator — 字幕时间计算
from aivideo.core.subtitle_timing import SubtitleTimingCalculator
calc = create_subtitle_calculator()
segments = calc.calculate(word_timestamps, max_duration=3.0)
数据模型: SubtitleSegment, WordTimestamp
2.4.13 AudioSyncService — 音频同步服务
from aivideo.core.audio_sync_service import AudioSyncService
sync = create_audio_sync_service()
result = sync.align(audio_path, text_segments)
数据模型: AudioSyncResult, SyncConfig
2.4.14 TemplateFactory — 模板工厂
from aivideo.core.template_engine import TemplateFactory, DraftAssembler, TemplateManifest
factory = TemplateFactory()
manifest = TemplateManifest(name="subtitle", slots=[...])
assembler = DraftAssembler(factory, manifest)
数据模型: SlotType, SlotDefinition
2.4.15 MotionLibrary — 运动库
from aivideo.core.motion_library import MotionLibrary, CameraMotion, CameraMotionType
MotionLibrary.register("my_zoom", CameraMotion(
type=CameraMotionType.KEN_BURNS,
scale_start=1.0, scale_end=1.25,
pan_x_end=0.15,
easing=EasingFunction.EASE_IN_OUT
))
motion = MotionLibrary.get("dramatic_reveal")
10种预设镜头: dramatic_reveal, subtle_zoom, ken_burns_left, ken_burns_right, slow_push_in, slow_pull_out, pan_left, pan_right, tilt_up, tilt_down
数据模型: CameraMotion, CameraMotionType, EasingFunction, MotionPreset, MotionGenerator
2.4.16 RhythmLibrary — 节奏库
from aivideo.core.rhythm_library import RhythmLibrary
rhythm = RhythmLibrary.get("cinematic")
segments = rhythm.generate(total_duration=60.0)
3种节奏: cinematic, energetic, contemplative
数据模型: RhythmPattern, RhythmSegment
2.4.17 TransitionLibrary — 转场库
from aivideo.core.transition_library import TransitionLibrary, TransitionPreset
transition = TransitionLibrary.get("cross_dissolve")
5种转场: cross_dissolve, dip_to_black, wipe_right, fade_through_white, smooth_cut
数据模型: TransitionPreset, TransitionType
2.4.18 VisualHierarchyBuilder — 视觉层级构建器
from aivideo.core.visual_hierarchy import VisualHierarchyBuilder
builder = VisualHierarchyBuilder()
builder.add_layer(LayerType.BACKGROUND, LayerConfig(opacity=1.0))
builder.add_layer(LayerType.MAIN_CONTENT, LayerConfig(opacity=1.0))
builder.add_layer(LayerType.OVERLAY, LayerConfig(opacity=0.5))
数据模型: LayerType, LayerConfig
2.4.19 AudioMixer — 音频混合器
from aivideo.core.audio_mixer import AudioMixer
mixer = AudioMixer()
mixer.add_track(AudioTrackConfig(path="voiceover.mp3", volume=1.0))
mixer.add_track(AudioTrackConfig(path="bgm.mp3", volume=0.3, ducking=DuckingConfig(enabled=True)))
result = mixer.mix(output_path)
数据模型: AudioTrackConfig, DuckingConfig
2.4.20 StoryboardPlanner — 分镜规划器
from aivideo.core.storyboard import StoryboardPlanner
planner = StoryboardPlanner(strategy=StoryboardStrategy.CHRONOLOGICAL)
segments = planner.plan(scenes, total_duration=60.0)
数据模型: StoryboardStrategy, StoryboardSegment
神话场景策略 (storyboard_strategies.py): MythologyStoryboard, MythologyScene, SceneRatio
分镜混剪 (storyboard_remixer.py): StoryboardRemixer, RemixScene
2.4.21 StylePresets — 风格预设库
from aivideo.core.style_presets import StylePresetLibrary
preset = StylePresetLibrary.get("cinematic")
数据模型: StylePresetType, StylePreset
2.4.22 VisionProvider — 图片分析
from aivideo.core.vision_provider import create_vision_provider
provider = create_vision_provider()
result = provider.analyze(image_path)
数据模型: VisionResult, ImageCategory, MoodType
2.4.23 BgmSearchService — BGM搜索
from aivideo.core.bgm_search import create_bgm_search_service
service = create_bgm_search_service()
results = service.search(mood=BgmMood.INSPIRATIONAL, genre=BgmMood.ORCHESTRAL)
数据模型: BgmMood, BgmGenre, BgmTrack, BgmSearchResult
2.4.24 草稿操作工具 (draft_ops)
from aivideo.core.draft_ops import (
update_meta_paths, # 更新 draft_meta_info.json
update_content_paths, # 更新 draft_content.json 素材路径
load_draft_content, # 加载草稿内容
save_draft_content, # 保存草稿内容
find_jianying_draft_dir, # 查找剪映草稿目录
append_segment, # 追加片段
merge_draft_content, # 合并草稿内容
copy_material_files, # 复制素材文件
copy_file_to_materials, # 复制文件到素材目录
search_material_file, # 搜索素材文件
repair_material_paths, # 修复素材路径
compute_file_hash, # 计算文件哈希
)
update_content_paths(draft_dir, old_dir=source_dir)
2.4.25 媒体归一化 (MediaNormalizer)
from aivideo.core.media_normalizer import MediaNormalizer, MediaInfo
normalizer = MediaNormalizer()
info = normalizer.probe("input.avi")
normalizer.convert("input.avi", "output.mp4")
2.4.26 ID生成器 (id_generator)
from aivideo.core.id_generator import generate_id, generate_id_upper
id_hex = generate_id() # 32位无横线小写: "a1b2c3d4e5f6..."
id_upper = generate_id_upper() # 36位含横线大写: "A1B2C3D4-E5F6-..."
规范: 统一使用 generate_id() 生成与pycapcut兼容的32位无横线小写UUID。
2.4.27 其他核心模块
| 模块 |
关键类/函数 |
说明 |
safe_path.py |
SafePathHandler |
路径安全处理 |
rule_engine.py |
RuleEngine |
规则引擎 |
base_service.py |
BaseService |
服务基类(ABC) |
workflow_context.py |
WorkflowContext |
工作流上下文 |
constants.py |
CANVAS_WIDTH, CANVAS_HEIGHT, FPS, SEC |
全局常量 |
media_probe.py |
probe_video_info(), extract_audio_from_video() |
媒体探测 |
import_helper.py |
ImportHelper |
导入辅助 |
subprocess_utils.py |
run_subprocess() |
安全子进程封装 |
2.5 服务层 (services/)
2.5.1 DraftSyncService / DraftWatcher
双向同步与自动监控服务。
2.5.2 VideoDraftService
一键逆向/导出/生成服务。
2.5.3 AutoImportService
自动导入剪映服务,导入后调用 update_content_paths() 更新路径。
2.5.4 VideoDraftService — 统一视频草稿服务
VideoDraftService 是视频草稿操作的统一入口,整合了导出、逆向、增强、导入等核心功能。
from aivideo.services.video_draft_service import VideoDraftService
service = VideoDraftService()
service.export_mp4(draft_path, output_path, strategy="ffmpeg_direct")
service.reverse_to_draft(video_path, output_dir)
service.draft_from_video(video_path, output_dir)
service.import_to_jianying(draft_path)
service.probe_video(video_path)
service.analyze_draft(draft_path)
service.generate_english_teaching(topic, images, output_dir)
核心方法:
| 方法 |
说明 |
export_mp4() |
导出MP4视频 |
reverse_to_draft() |
视频逆向为剪映草稿 |
draft_from_video() |
从视频创建草稿 |
reverse_full() |
完整逆向流程 |
import_to_jianying() |
导入剪映 |
probe_video() |
视频信息探测 |
analyze_draft() |
草稿分析 |
generate_english_teaching() |
英语教学视频生成 |
2.5.5 DraftSyncService — 双向同步服务
from aivideo.services.draft_sync_service import DraftSyncService
sync = DraftSyncService()
diff = sync.detect_changes(draft_path)
result = sync.sync_to_jianying(draft_path)
result = sync.sync_from_jianying(draft_path)
数据模型: DraftDiff, MaterialDiff, TrackDiff, SyncResult, SyncDirection
2.5.6 DraftWatcher — 自动监控服务
from aivideo.services.draft_watcher import DraftWatcher
watcher = DraftWatcher()
watcher.watch(draft_path)
watcher.start()
watcher.stop()
数据模型: FileChangeEvent, ChangeType, MaterialCategory, DraftSnapshot
2.5.7 CloudManager — 云端素材管理
from aivideo.services.cloud_manager import CloudManager
cm = CloudManager()
cm.register(category, provider)
results = cm.search(category, query)
path = cm.download(category, resource_id)
material = cm.get(category, resource_id)
2.5.8 素材提供者 (asset_providers)
from aivideo.services.asset_providers import (
LocalImageProvider,
SolidColorImageProvider,
LocalBGMProvider,
LocalCoverProvider,
)
2.6 流水线层 (pipeline/)
2.6.1 Pipeline — 统一流水线入口
Pipeline 是框架的最高层编排器,将6大引擎串联为18步完整流程。
from aivideo.pipeline.pipeline import Pipeline
pipeline = Pipeline()
result = pipeline.run(
topic="八仙过海",
images=image_list,
style_override=STYLE_CINEMATIC,
output_dir="output"
)
result = pipeline.run_style_driven(
topic="牛郎织女",
styles=["epic_cinematic", "ink_wash"],
images=image_pool
)
18步标准流程:
| 步骤 |
说明 |
涉及引擎 |
| 1-3 |
内容生成(文案/词汇/提示词) |
AIContentEngine |
| 4-5 |
图片生成/处理 |
ImageEngine |
| 6-7 |
TTS语音合成 |
TTSEngine |
| 8-9 |
ASR字幕对齐 |
ASREngine |
| 10-12 |
草稿构建(轨道/片段/特效) |
DraftBuilderCore |
| 13-14 |
质量检查+修正 |
QualityGate |
| 15-16 |
渲染导出 |
ExportEngine |
| 17-18 |
导入剪映+验证 |
JianyingController |
2.6.2 EssayData — 内容数据模型
from aivideo.pipeline.models import EssayData, Sentence, VocabularyItem, StyleProfile
essay = EssayData(
title="八仙过海",
sentences=[Sentence(text="...", start=0, end=5.0)],
vocabulary=[VocabularyItem(word="ocean", definition="海洋")],
style=StyleProfile(
tts_speaker="zh-CN-YunxiNeural",
motion_preset="dramatic_reveal",
color_grade="cinematic"
)
)
核心数据模型:
| 模型 |
说明 |
EssayData |
内容数据包(标题/句子/词汇/风格) |
Sentence |
句子(文本/起止时间) |
VocabularyItem |
词汇项(单词/定义/翻译) |
StyleProfile |
风格配置(TTS/运动/色彩) |
BuildResult |
构建结果 |
ExportResult |
导出结果 |
TTSResult |
TTS结果 |
DualStyleBuildContext |
双风格构建上下文 |
2.6.3 BatchPipelineExecutor — 批量执行器
from aivideo.pipeline.batch import BatchPipelineExecutor, BatchTask
executor = BatchPipelineExecutor()
tasks = [
BatchTask(topic="主题1", images=imgs1, style=style1),
BatchTask(topic="主题2", images=imgs2, style=style2),
]
summary = executor.execute(tasks)
数据模型: BatchTask, BatchResult, BatchSummary
2.6.4 PipelineState — 断点续传
from aivideo.pipeline.state import PipelineState
state = PipelineState(work_dir="output")
state.mark_step("tts_synthesis", result=data)
if not state.is_step_completed("tts_synthesis"):
...
artifact = state.get_artifact("tts_audio_path")
20步定义: STEPS 列表定义了流水线的所有步骤名称。
2.6.5 PipelineScheduler — DAG调度
from aivideo.pipeline.nodes import PipelineNode, PipelineScheduler
class MyNode(PipelineNode):
def execute(self, context):
...
return NodeResult(status=NodeStatus.SUCCESS, outputs={...})
scheduler = PipelineScheduler()
scheduler.add_node(my_node)
result = scheduler.run()
2.7 配置中心 (config/)
2.7.1 AivideoConfig — 全框架唯一配置来源
from aivideo.config.defaults import AivideoConfig, get_config
config = AivideoConfig.from_env()
config = AivideoConfig.from_dict({"tts": {"backend": "edge"}})
config = AivideoConfig.from_yaml("config.yaml")
config = AivideoConfig.from_json("config.json")
9个子配置:
| 子配置 |
说明 |
关键字段 |
MediaConfig |
媒体处理 |
默认编码、分辨率、帧率 |
ExportConfig |
导出设置 |
策略、CRF、预设 |
TTSConfig |
TTS设置 |
后端、音色、语速、SSML |
AIConfig |
AI服务 |
API密钥、模型、温度 |
PathConfig |
路径配置 |
输出目录、剪映目录、缓存目录 |
JianyingConfig |
剪映配置 |
草稿根目录、自动导出 |
AppConfig |
应用配置 |
日志级别、并发数 |
HardwareConfig |
硬件配置 |
GPU、加速级别 |
HooksConfig |
钩子配置 |
启用/禁用钩子列表 |
方法: from_env(), from_dict(), from_json(), from_yaml(), to_dict(), save(), migrate()
2.7.2 ConfigManager — 多环境分层合并
from aivideo.config.config_manager import ConfigManager
manager = ConfigManager()
manager.load("config_default.yaml")
manager.load("config_production.yaml", priority=10)
config = manager.to_aivideo_config()
2.7.3 SceneTemplate — 场景模板
from aivideo.config.templates import SceneTemplate, get_template, list_templates, register_template
template = get_template("douyin_commerce")
templates = list_templates()
register_template("my_template", SceneTemplate(...))
预置模板: DOUYIN_COMMERCE, YOUTUBE_TECH
2.8 API层 (api/)
2.8.1 DirectorAPI — AI Agent接口
DirectorAPI 是面向AI Agent的高层语义接口,通过自然语言指令控制视频生成。
from aivideo.api.director_api import DirectorAPI
director = DirectorAPI()
director.create_project(name="我的视频", width=1920, height=1080)
director.add_video(path="clip.mp4")
director.add_audio(path="bgm.mp3")
director.add_text(content="标题", start_time=0, duration=5.0)
director.add_effect(name="模糊渐显", segment=seg)
director.add_transition(type="fade", duration=1.0)
director.save()
director.export(output_path="output.mp4")
director.import_to_jianying()
2.8.2 VideoCommandAPI — 视频命令API
from aivideo.api.command_api import VideoCommandAPI
api = VideoCommandAPI()
api.reverse_video(video_path, output_dir)
api.export_video(draft_path, output_path)
api.draft_from_video(video_path, output_dir)
api.add_subtitles(draft_path, srt_path)
api.enhance_images(image_dir)
2.8.3 MediaAPI / TextAPI / VFXAPI / ExportAPI
from aivideo.api.media_api import MediaAPI
from aivideo.api.text_api import TextAPI
from aivideo.api.vfx_api import VFXAPI
from aivideo.api.export_api import ExportAPI
media = MediaAPI()
media.add_video(path="clip.mp4")
media.add_image(path="img.png")
media.add_audio(path="bgm.mp3")
media.probe(path="clip.mp4")
text = TextAPI()
text.add_text(content="标题")
text.add_subtitle(text="字幕行", start=0, end=3.0)
vfx = VFXAPI()
vfx.add_animation(name="模糊渐显")
vfx.add_text_animation(name="打字机")
vfx.add_mask(type="rectangle")
export = ExportAPI()
export.export_mp4(draft_path, output_path)
2.8.4 MCPRpcHandler — JSON-RPC 2.0 服务
from aivideo.api.mcp_server import start_mcp_server, MCPRpcHandler
start_mcp_server(host="0.0.0.0", port=8080)
支持的RPC方法:
| 方法 |
说明 |
ping |
心跳检测 |
engines/list |
列出可用引擎 |
engines/call |
调用引擎 |
tools/list |
列出工具 |
tools/call |
调用工具 |
workflow/run |
运行工作流 |
draft/versions |
草稿版本列表 |
draft/save |
保存草稿 |
draft/load |
加载草稿 |
quality/check |
质量检查 |
project/info |
项目信息 |
generate/video |
生成视频 |
2.9 钩子系统 (hooks/)
2.9.1 HookPoint — 12个触发点
from aivideo.hooks.base import HookPoint
| HookPoint |
触发时机 |
典型用途 |
| PRE_PROCESS |
内容处理前 |
图片超分(RealESRGAN) |
| POST_PROCESS |
内容处理后 |
高光提取(ClipsAI)、超剪(Videogrep) |
| PRE_BUILD |
草稿构建前 |
— |
| POST_BUILD |
草稿构建后 |
水印添加 |
| PRE_RENDER |
渲染前 |
— |
| POST_RENDER |
渲染后 |
视频插帧(RIFE) |
| PRE_EXPORT |
导出前 |
— |
| POST_EXPORT |
导出后 |
— |
| PRE_IMPORT |
导入剪映前 |
— |
| POST_IMPORT |
导入剪映后 |
— |
| ON_ERROR |
错误发生时 |
错误通知 |
| ON_COMPLETE |
流程完成时 |
结果推送 |
2.9.2 HookManager — 钩子管理器
from aivideo.hooks.base import HookManager
manager = HookManager()
manager.add_hook(my_hook, priority=10)
manager.run_hooks_sync(HookPoint.POST_BUILD, context)
await manager.run_hooks_async(HookPoint.POST_BUILD, context)
2.9.3 内置钩子实现
| 钩子 |
触发点 |
说明 |
依赖 |
WhisperHook |
PRE_PROCESS |
字幕生成 |
whisper |
RealESRGANHook |
PRE_PROCESS |
图片超分辨率 |
realesrgan |
ClipsAIHook |
POST_PROCESS |
高光提取 |
clipsai |
VideogrepHook |
POST_PROCESS |
超剪 |
videogrep |
RIFEHook |
POST_RENDER |
视频插帧 |
rife |
KenBurnsHook |
POST_PROCESS |
Ken Burns运动效果 |
— |
QualityGateHook |
POST_PROCESS |
质量门控 |
— |
2.9.4 HookContext — 钩子上下文
from aivideo.hooks.context import HookContext
ctx = HookContext(
project_name="我的项目",
draft_dir="/path/to/draft",
essay_data=essay,
images=image_list,
audio_paths=audio_list,
subtitles=sub_list,
)
ctx.set_result("whisper", subtitle_data)
sub = ctx.get_result("whisper")
2.10 外部集成层 (integrations/)
2.10.1 PluginManager — 插件管理器
from aivideo.integrations.plugin_manager import PluginManager
pm = PluginManager.create_default()
pm.register_llm("openai", OpenAILLM)
pm.register_tts("custom", CustomTTS)
pm.register_image_gen("dalle", DalleGenerator)
llm = pm.get_llm()
tts = pm.get_tts()
img_gen = pm.get_image_gen()
plugins = pm.list_plugins()
2.10.2 LLMProvider — 大语言模型接口
from aivideo.integrations.llm.base import LLMProvider
class MyLLM(LLMProvider):
def generate(self, prompt: str) -> str:
...
def generate_json(self, prompt: str) -> dict:
...
@property
def available(self) -> bool:
...
2.10.3 TTSBackend — TTS后端接口
from aivideo.integrations.tts.base import TTSBackend
from aivideo.integrations.tts.edge_tts import EdgeTTSBackend
class MyTTS(TTSBackend):
def synthesize(self, text: str, output_path: str, **kwargs) -> str:
...
@property
def available(self) -> bool:
...
2.10.4 ASRBackend — 语音识别接口
from aivideo.integrations.asr.base import ASRBackend
from aivideo.integrations.asr.whisper_asr import WhisperASRBackend
class MyASR(ASRBackend):
def recognize(self, audio_path: str) -> list:
...
@property
def available(self) -> bool:
...
2.10.5 ImageGenerator — 图片生成接口
from aivideo.integrations.image_gen.base import ImageGenerator
from aivideo.integrations.image_gen.openai_image_gen import OpenAIImageGenerator
2.10.6 CapCutMateClient — CapCut Mate API
from aivideo.integrations.capcut_mate import CapCutMateClient
client = CapCutMateClient()
if client.is_available:
client.import_draft(draft_path)
client.export_video(draft_path, output_path)
client.apply_template(draft_path, template_id)
2.11 适配器层 (adapters/)
2.11.1 DraftAdapter — 草稿适配器基类
from aivideo.adapters.base_adapter import DraftAdapter
class MyAdapter(DraftAdapter):
def load(self, path: str) -> dict:
...
def save(self, path: str, data: dict) -> None:
...
def is_available(self) -> bool:
...
2.11.2 JianyingV5Adapter — 剪映V5适配
from aivideo.adapters.jianying_v5_adapter import JianyingV5Adapter
adapter = JianyingV5Adapter()
data = adapter.load(draft_path)
adapter.save(draft_path, data)
2.11.3 CapCutAPIAdapter — CapCut API适配
from aivideo.adapters.capcut_api_adapter import CapCutAPIAdapter
adapter = CapCutAPIAdapter()
if adapter.is_available():
data = adapter.load(draft_path)
2.12 工作流引擎 (workflow/)
2.12.1 WorkflowEngine — DAG工作流引擎
from aivideo.workflow.engine import WorkflowEngine
engine = WorkflowEngine()
engine.add_node("script_gen", ScriptGenerationNode())
engine.add_node("tts", TTSSynthesizeNode())
engine.add_node("draft_build", DraftBuildNode())
engine.add_node("export", ExportVideoNode())
result = engine.run()
engine2 = WorkflowEngine.from_yaml("workflow.yaml")
2.12.2 标准节点 (7个)
| 节点 |
说明 |
ScriptGenerationNode |
脚本生成 |
ImageProcessNode |
图片处理 |
TTSSynthesizeNode |
TTS合成 |
ASRRecognizeNode |
ASR识别 |
DraftBuildNode |
草稿构建 |
ExportVideoNode |
视频导出 |
QualityCheckNode |
质量检查 |
2.12.3 高级节点 (8个)
| 节点 |
说明 |
ConditionalNode |
条件分支 |
ParallelNode |
并行执行 |
LoopNode |
循环执行 |
HumanReviewNode |
人工审核 |
MergeContextsNode |
上下文合并 |
LogMessageNode |
日志消息 |
ValidateInputNode |
输入校验 |
RetryOnFailureNode |
失败重试 |
2.13 创新功能模块 (features/)
2.13.1 SmartCutScheduler — 智能剪辑调度
from aivideo.features.smart_cut_scheduler import SmartCutScheduler
scheduler = SmartCutScheduler()
schedule = scheduler.schedule(clips, target_duration=60.0)
数据模型: CutPoint, CutSchedule
2.13.2 AudioMaster — 音频母带处理
from aivideo.features.audio_master import AudioMaster
master = AudioMaster(config=AudioMasterConfig())
result = master.process(audio_path, output_path)
数据模型: AudioMasterConfig, AudioMasterResult
2.13.3 AIVideoGenerator — AI视频生成器
from aivideo.features.ai_video_generator import AIVideoGenerator
generator = AIVideoGenerator()
result = generator.generate(prompt="...", output_dir="output")
2.13.4 MultiPlatformExporter — 多平台导出
from aivideo.features.multi_platform_exporter import MultiPlatformExporter
exporter = MultiPlatformExporter()
exporter.export(draft_path, platforms=["douyin", "youtube", "bilibili"])
预置平台规格 (PLATFORM_SPECS):
| 平台 |
分辨率 |
帧率 |
时长限制 |
| douyin |
1080x1920 |
30fps |
15min |
| youtube |
1920x1080 |
30fps |
无 |
| bilibili |
1920x1080 |
30fps |
无 |
数据模型: PlatformSpec, ExportTask
2.13.5 VideoAnalytics — 视频分析
from aivideo.features.video_analytics import VideoAnalytics
analytics = VideoAnalytics()
metrics = analytics.analyze(draft_path)
summary = analytics.summarize(metrics_list)
数据模型: BuildMetrics, AnalyticsSummary
2.14 模板系统 (templates/)
from aivideo.templates.export_configs import ExportConfigTemplate
from aivideo.templates.scene_templates import SceneTemplate
from aivideo.templates.tts_configs import TTSConfigTemplate
2.15 CLI命令行工具
python -m aivideo <command> [options]
20+子命令:
| 命令 |
说明 |
run |
运行完整流水线 |
generate |
生成视频 |
export |
导出MP4 |
reverse |
视频逆向 |
draft-from-video |
从视频创建草稿 |
enhance |
增强视频 |
batch |
批量处理 |
validate |
校验草稿 |
config |
配置管理 |
launch |
启动服务 |
workflow |
运行工作流 |
draft |
草稿操作 |
template |
模板管理 |
shell |
交互式Shell |
error |
错误码查询 |
tts |
TTS合成 |
translate |
翻译 |
probe |
媒体探测 |
analyze |
分析草稿 |
serve |
启动MCP服务器 |
check |
环境检查 |
第三章 剪映草稿规范
3.1 草稿目录结构
{剪映草稿目录}/
├── draft_content.json # 草稿内容(轨道、片段、素材)
├── draft_meta_info.json # 草稿元信息(素材注册、draft_id)
├── draft_virtual_store.json # 虚拟存储(父子关系映射)
├── draft_cover.jpg # 封面图
├── draft_local_cover.jpg # 本地缩略图(必需)
└── Resources/ # 素材文件目录
├── img1.png
├── img2.png
└── voiceover.mp3
注意: 剪映草稿目录中不应存在 materials/ 目录,剪映只使用 Resources/。
3.2 JSON文件规范
3.2.1 draft_content.json
顶层结构:
{
"id": "草稿UUID",
"version": 360000,
"new_version": "110.0.0",
"render_index_track_mode_on": true,
"canvas_config": { ... },
"tracks": [ ... ],
"materials": {
"videos": [],
"audios": [],
"texts": [],
"effects": [],
"filters": [],
"speeds": [],
"animations": [],
"stickers": [],
"loudnesses": [],
"sound_channel_mappings": [],
"vocal_separations": [],
"beats": []
},
"composition": { ... }
}
关键字段说明:
| 字段 |
值 |
说明 |
| version |
360000 |
版本号 |
| new_version |
“110.0.0” |
新版本标识 |
| render_index_track_mode_on |
true |
顶层字段 |
3.2.2 draft_meta_info.json
{
"draft_id": "UUID",
"draft_name": "项目名称",
"draft_fold_path": "草稿目录绝对路径",
"draft_materials": [
{
"id": "素材local_material_id",
"type": 0,
"value": "",
"file_Path": "绝对路径",
"metetype": "video"
}
]
}
素材类型注册规则:
| type |
含义 |
说明 |
| 0 |
视频素材/非音乐音频 |
file_Path 使用绝对路径 |
| 1 |
虚拟存储关系 |
draft_virtual_store.json |
| 2 |
附加信息 |
必须为空数组 [] |
| 8 |
在线音乐 |
仅在线音乐使用 |
3.2.3 draft_virtual_store.json
{
"draft_virtual_store": [
{
"1": [
{
"child_id": "素材ID",
"parent_id": ""
}
]
}
]
}
3.3 素材路径规范
3.3.1 路径格式方案
最终方案:绝对路径
根据多轮修复验证,剪映Pro使用绝对路径方案,而非占位符方案:
| 文件 |
字段 |
正确格式 |
示例 |
| draft_content.json |
videos.path |
绝对路径 |
D:/AngentAI/JianyingPro Drafts/项目名/Resources/img1.png |
| draft_content.json |
audios.path (原声) |
绝对路径 |
D:/AngentAI/JianyingPro Drafts/项目名/Resources/voiceover.mp3 |
| draft_content.json |
audios.path (音乐) |
绝对路径(指向缓存) |
C:/Users/.../Cache/music/xxx.mp3 |
| draft_meta_info.json |
file_Path |
绝对路径 |
D:/AngentAI/JianyingPro Drafts/项目名/Resources/img1.png |
3.3.2 占位符方案为何不可行
| 问题 |
说明 |
| draft_id 不一致 |
剪映打开草稿时会重新生成 draft_meta_info.json 的 draft_id,导致占位符路径中的旧ID失效 |
| 路径解析失败 |
新的 draft_id 与占位符路径中的旧 draft_id 不匹配,剪映无法解析 |
3.3.3 音频注册规则
| 音频类型 |
draft_content.json 路径 |
meta type=0 |
meta type=2 |
| 语音原声 (video_original_sound) |
绝对路径 |
注册, metetype=video |
不注册 |
| 提取音乐 (extract_music) |
materials/xxx |
不注册 |
不注册 |
| 在线音乐 (music) |
绝对路径(缓存) |
不注册 |
不注册(使用type=8) |
3.4 素材引用完整性
3.4.1 引用完整性原则
剪映草稿中每个 segment 必须满足:
segment.material_id → materials.{videos|audios|texts}[id] 必须存在
segment.extra_material_refs[*] → materials.{speeds|effects|...}[id] 必须存在
任何断裂都会导致"媒体未找到"。
3.4.2 引用链示例
VideoSegment
├── material_id → materials.videos[id]
└── extra_material_refs → [
materials.speeds[id],
]
AudioSegment
├── material_id → materials.audios[id]
└── extra_material_refs → [
materials.speeds[id],
materials.beats[id],
materials.sound_channel_mappings[id],
materials.vocal_separations[id],
materials.loudnesses[id], # 必须存在
]
TextSegment
├── material_id → materials.texts[id] # 必须存在
└── extra_material_refs → [
materials.speeds[id],
materials.animations[id], # 如有动画
materials.filters[id], # 如有气泡/效果
]
3.4.3 fix_material_ids() 规范
fix_material_ids() 函数用于清理孤立的 material_id 引用。必须收集所有素材类型的ID:
valid_ids = set()
for v in mats.get("videos", []):
valid_ids.add(v.get("id", ""))
for a in mats.get("audios", []):
valid_ids.add(a.get("id", ""))
for t in mats.get("texts", []): # ✅ 必须包含 texts
mid = t.get("id", "")
if mid:
valid_ids.add(mid)
# ... 其他素材类型
禁止: 对 text segment 的 material_id 执行 del seg["material_id"] 操作。
3.5 composition 结构规范
{
"composition": {
"id": "UUID",
"type": "composition",
"render_index_track_mode_on": false,
"drafts": [
{
"id": "与cover_draft_id一致",
"type": "composition_draft",
...
}
]
}
}
关键约束:
| 字段 |
正确值 |
错误值 |
说明 |
| render_index_track_mode_on |
false |
true |
必须为false |
| is_drop_frame_timecode |
不存在 |
存在 |
参考案例中无此字段 |
| common_masks |
不存在 |
存在 |
参考案例中无此字段 |
| placeholder_infos |
不存在 |
存在 |
参考案例中无此字段 |
3.6 封面文件规范
| 文件 |
说明 |
生成方式 |
| draft_cover.jpg |
封面图 |
DraftFolder.generate_cover_image() |
| draft_local_cover.jpg |
本地缩略图(必需) |
DraftFolder._generate_local_cover() |
注意: draft_local_cover.jpg 是剪映必需文件,缺失可能导致草稿显示异常。
第四章 三方框架兼容性
4.1 框架对照关系
| 三方框架 |
aivideo 对应模块 |
集成状态 |
| pyCapCut/pycapcut/ |
aivideo/document/ |
核心兼容,5项不兼容 |
| jianying-skill/scripts/vendor/pyJianYingDraft/ |
aivideo/document/ |
核心兼容,同上 |
| jianying-skill/scripts/core/ |
aivideo/skills/jianying_editor/core/ |
功能增强,3项缺失 |
| jianying-skill/scripts/utils/ |
aivideo/skills/jianying_editor/utils/ + aivideo/core/ |
分散集成,1项降级 |
| jianying-skill/scripts/ (独立脚本) |
aivideo/skills/jianying_editor/scripts/ |
部分缺失 |
| jianying-skill/data/ |
aivideo/skills/jianying_editor/data/ |
文件列表一致 |
| jianying-skill/examples/ |
aivideo/examples/ |
完全不同,10个示例缺失 |
| jianying-skill/rules/ |
无对应 |
未集成规则文件 |
4.2 集成完成度评分
| 维度 |
完成度 |
说明 |
| 文档模型层 (document/) |
90% |
核心API兼容,5项不兼容需修复 |
| 剪映技能层 (skills/) |
88% |
功能增强显著,3项功能缺失 |
| 引擎层 (engines/) |
75% |
TTS缺少SAMI后端,逆向/渲染完整 |
| 数据资产层 (data/) |
95% |
文件列表一致,内容待验证 |
| 工具脚本层 (scripts/) |
80% |
核心脚本已集成,同义词搜索降级 |
| 示例层 (examples/) |
30% |
aivideo自有示例完整,但缺失10个剪映操作示例 |
| 规则层 (rules/) |
0% |
未集成Agent规则文件 |
4.3 严重不兼容项(P0)
4.3.1 Text_animation 类名变更
| 项目 |
值 |
| 源 |
Text_animation(下划线命名) |
| 目标 |
TextAnimationClip(驼峰命名) |
| 影响 |
依赖 Text_animation 类名的代码抛 NameError |
| 修复 |
添加兼容别名: Text_animation = TextAnimationClip |
4.3.2 异常继承体系不同
| 项目 |
值 |
| 源 |
TrackNotFound(NameError), AmbiguousTrack(ValueError) 等 |
| 目标 |
所有异常继承 UniVideoError |
| 影响 |
isinstance(e, ValueError) / isinstance(e, NameError) 失败 |
| 修复 |
双继承: class TrackNotFound(UniVideoError, NameError): ... |
4.3.3 tim() 对 float 输入的语义不同
| 项目 |
值 |
| 源 |
tim(1.5) → 2(float视为微秒,直接取整) |
| 目标 |
tim(1.5) → 1500000(float视为秒,乘以SEC) |
| 影响 |
所有使用 tim(float_value) 的代码行为不一致 |
| 修复 |
统一为pycapcut语义(float视为微秒),添加 tim_seconds() |
4.3.4 source_timerange + speed 联动逻辑缺失
| 项目 |
值 |
| 源 |
自动计算 target_timerange.duration = source_timerange.duration / speed |
| 目标 |
缺少此逻辑 |
| 影响 |
变速片段的时间范围计算错误 |
| 修复 |
在 VideoSegment.__init__ 和 AudioSegment.__init__ 中添加联动逻辑 |
4.3.5 UUID 格式差异
| 项目 |
值 |
| 源 |
uuid.uuid4().hex → 32位无横线小写 |
| 目标 |
str(uuid.uuid4()).upper() → 36位含横线大写 |
| 影响 |
ID格式不同可能影响去重、引用和剪映兼容性 |
| 修复 |
统一使用 generate_id() (32位无横线小写) |
4.4 功能缺失项(P1)
| # |
缺失项 |
严重程度 |
修复方案 |
| 1 |
SAMI TTS后端 |
高 |
添加 _SamiTTSBackend 类,实现WebSocket协议 |
| 2 |
视频文件AI分析能力 |
高 |
扩展 LLMProvider 支持多模态输入 |
| 3 |
同义词枚举映射降级 |
中 |
恢复SYNONYMS字典匹配逻辑 |
| 4 |
素材时长越界检查 |
中 |
添加 source_timerange.end > material.duration 校验 |
| 5 |
uniform_scale互斥校验 |
中 |
添加 uniform_scale 与 scale_x/scale_y 互斥检查 |
| 6 |
GIF文件特殊解析 |
低 |
添加imageio解析GIF帧数和时长 |
| 7 |
TextBorder/TextSegment导出字段缺失 |
中 |
补充alpha/bold/italic/underline字段 |
4.5 行为差异项(P2)
| # |
差异项 |
源行为 |
目标行为 |
修复方案 |
| 1 |
add_track()返回值 |
返回self |
返回Track |
添加add_track_chain() |
| 2 |
add_segment()返回值 |
返回self |
返回BaseSegment |
添加add_segment_chain() |
| 3 |
TrackType.text render_index |
15000 |
14000 |
修正为15000 |
| 4 |
Track.export_json is_default_name |
len(name)==0 |
始终True |
修正逻辑 |
| 5 |
EffectSegment参数名 |
effect_type |
effect |
添加别名 |
| 6 |
FilterSegment参数名 |
meta |
filter_meta |
添加别名 |
| 7 |
load_template()实现 |
provide_ctor_defaults |
直接构造 |
路径检查 |
| 8 |
draft_meta_info.json损坏检测 |
有 |
缺失 |
添加检查 |
| 9 |
pre_export状态处理 |
支持Esc键 |
不支持 |
添加处理 |
| 10 |
add_media_safe错误提示 |
打印缺失路径 |
静默返回None |
添加logger.warning |
| 11 |
DataError异常类 |
有 |
缺失 |
添加 |
| 12 |
ScriptFile.load_template路径检查 |
有 |
无 |
添加 |
4.6 兼容层模块
创建 aivideo/document/compat.py 提供pycapcut风格的兼容别名和适配器:
from aivideo.document.animation import TextAnimationClip as Text_animation
from aivideo.document.time_util import tim, tim_seconds, Timerange, trange, SEC
from aivideo.document.exceptions import (
TrackNotFound, AmbiguousTrack,
SegmentOverlapError as SegmentOverlap,
MaterialNotFound, ExtensionFailed,
AutomationError, ExportTimeoutError as ExportTimeout,
)
def generate_id() -> str:
from aivideo.core.id_generator import generate_id
return generate_id()
第五章 常见问题排查与修复
5.1 草稿构建问题
5.1.1 Bug: fix_material_ids() 删除 text segment 的 material_id
现象: 剪映打开后所有文本显示"媒体未找到"
根因: fix_material_ids() 中 valid_ids 只收集了 videos 和 audios 的 ID,text segment 的 material_id 引用 materials.texts 中的 ID,不在 valid_ids 中,被当作"孤立引用"删除。
修复: 收集 texts 的 ID 到 valid_ids:
for t in mats.get("texts", []):
mid = t.get("id", "")
if mid:
valid_ids.add(mid)
文件: aivideo/tests/job1/main.py
5.1.2 Bug: add_segment() 中重复的 elif TextSegment 死代码
现象: materials.texts 列表为空(有 text segment 但无 text material)
根因: add_segment() 中有两个 elif isinstance(segment, TextSegment): 分支,Python 只执行第一个匹配的分支,第二个分支(注册 text material)永远不会执行。
修复: 合并为一个完整的 TextSegment 处理块:
elif isinstance(segment, TextSegment):
if segment.animations_instance is not None:
self.script_materials.animations.append(segment.animations_instance)
if segment.bubble is not None:
self.script_materials.filters.append(segment.bubble)
if segment.effect is not None:
self.script_materials.filters.append(segment.effect)
speed_id = segment.speed.global_id
if speed_id not in [s.global_id for s in self.script_materials.speeds]:
self.script_materials.speeds.append(segment.speed)
text_id = segment.material_id
if text_id and text_id not in [t.get("id") for t in self.script_materials.texts]:
self.script_materials.texts.append(segment.export_material())
文件: aivideo/document/script_file.py
5.1.3 Bug: 缺少 Loudness 类
现象: loudnesses: 0,工作模板 loudnesses: 3
根因: 框架完全没有实现 Loudness 材质类。
修复: 五步修复(参见2.1.1节素材注册机制中的AudioSegment部分)
文件: aivideo/document/audio_segment.py, aivideo/document/script_file.py
5.1.4 Bug: TextSegment.export_material() 顶层字段未填充
现象: text material 中 font_path="", border_width=0.0, border_color=""
根因: 这些字段被硬编码为空值,未从内部属性动态填充。
修复: 动态填充顶层字段:
"border_alpha": self.border.alpha if self.border else 1.0,
"border_color": self._color_to_hex(self.border.color) if self.border else "",
"border_width": self.border.width if self.border else 0.0,
"font_path": self._resolve_font_path() if self.font else "",
"text_color": self._color_to_hex(s.color),
"shadow_color": self._color_to_hex(self.shadow.color) if self.shadow else "",
文件: aivideo/document/text_segment.py
5.1.5 Bug: draft_folder.py 的 _update_path 使用未定义变量
现象: 运行时报错 NameError: name 'placeholder_prefix' is not defined
根因: _update_path() 嵌套函数引用了外部作用域不存在的变量。
修复: 确保变量定义存在,或改用绝对路径构建。
文件: aivideo/document/draft_folder.py
5.2 素材路径问题
5.2.1 路径格式不符合剪映标准
现象: 部分素材能正常显示,部分素材仍丢失
根因: 素材路径格式不符合剪映Pro标准
六大路径BUG:
| # |
BUG |
文件 |
修复 |
| 1 |
_update_path 使用绝对路径而非占位符格式 |
draft_folder.py |
使用placeholder_prefix |
| 2 |
update_content_paths 将占位符路径转换为绝对路径 |
draft_ops.py |
占位符路径保持不变 |
| 3 |
import_draft 复制了多余的 materials/ 目录 |
draft_folder.py |
排除materials/ |
| 4 |
update_meta_materials 中 video 的 file_Path 使用绝对路径 |
draft_folder.py |
使用 ./Resources/ |
| 5 |
update_meta_materials 中 audio 的 file_Path 使用绝对路径 |
draft_folder.py |
使用 ./Resources/ |
| 6 |
_add_bgm_placeholder 中 BGM 素材使用绝对路径 |
draft_folder.py |
使用 materials/ 相对路径 |
注意: 以上为占位符方案下的修复。最终方案为绝对路径方案(参见3.3节),部分修复逻辑已调整。
5.2.2 placeholder_prefix 变量被linter删除
现象: _update_path 引用 placeholder_prefix 时报 NameError
根因: IDE的linter/自动格式化工具删除了变量定义行
修复: 确保以下行存在:
placeholder_prefix = f"##_draftpath_placeholder_{draft_id}_##" if draft_id else ""
应对策略: 使用 Python 脚本(如 fix_and_run.py)在运行前强制修改代码。
5.3 素材链接问题
5.3.1 根因:代码执行路径错误
现象: 多轮修复后素材仍丢失
根因: 修复作用于错误的代码路径
用户预期修复路径:
DraftFolder.import_draft() → update_content_paths() → 路径替换
实际执行的代码路径:
DualStyleEngine._import_to_jianying() → 直接 copytree → 无路径替换
系统中两套导入逻辑:
| 入口 |
方法 |
是否正确 |
| DraftFolder.import_draft() |
draft_folder.py |
正确 |
| DualStyleEngine._import_to_jianying() |
dual_style_engine.py |
需修复 |
修复: 在 _import_to_jianying 中添加 update_content_paths 调用:
shutil.copytree(ctx.draft_folder_path, dest)
from aivideo.core.draft_ops import update_meta_paths, update_content_paths
update_meta_paths(dest, jy_dir)
update_content_paths(dest, old_dir=ctx.draft_folder_path)
文件: aivideo/engines/dual_style_engine.py
5.3.2 占位符路径解析失败
根因: 剪映打开草稿时重新生成 draft_id,导致占位符路径中的旧ID失效
最终方案: 使用绝对路径替代占位符
VideoMaterial/AudioMaterial 修复:
def _get_placeholder_path(self) -> str:
return os.path.abspath(self._original_path).replace("\\", "/")
文件: aivideo/document/local_materials.py
5.3.3 composition 结构错误
修复: 修正 composition 内部 draft 字段:
| 字段 |
修正前 |
修正后 |
| render_index_track_mode_on |
True |
False |
| is_drop_frame_timecode |
存在 |
删除 |
| common_masks |
存在 |
删除 |
| placeholder_infos |
存在 |
删除 |
文件: aivideo/document/draft_folder.py
5.3.4 save/finalize 顺序错误
根因: finalize_draft() 的修改被 save() 覆盖
修复: 正确顺序 — 先 save,再 finalize:
self._script.save() # 1. 保存脚本内容到文件
self._folder.finalize_draft(self._draft_dir) # 2. 从文件加载、修改、保存
文件: aivideo/engines/draft_remixer_engine.py
5.4 动画与滤镜问题
5.4.1 动画下载失败
现象: 剪映无法识别动画类型,提示下载失败
根因: Animation.export_json() 缺少 category_id、category_name、request_id、path 字段
修复: 添加缺失字段(参见2.1.6节)
文件: aivideo/document/animation.py
5.4.2 滤镜导出到错误字段
现象: 滤镜显示异常
根因: ScriptMaterial.export_json() 将 Filter 对象导出为 "effects" 键,但剪映标准格式中:
effects = 文字气泡、文字形状等效果(type=text_shape)
filters = 滤镜效果(type=filter)
修复:
"effects": [],
"filters": [f.export_json() for f in self.filters],
文件: aivideo/document/script_file.py
5.5 排查方法论
5.5.1 反向对比法
当有确定可工作的参照物时,从输出差异推导代码缺陷:
- 确认参照物(工作的输出)
- 编写对比脚本,逐字段对比
- 按严重程度排序差异
- 对每个差异,从输出反推代码
- 加调试日志精确定位
- 编写最小化测试验证
- 修复并清除缓存
- 端到端验证
5.5.2 调试日志法
在关键函数前后加日志,精确定位问题发生的时刻:
logger.info(f"DEBUG: BEFORE fix_material_ids: text segments={total}, with material_id={count}")
fix_material_ids(result.draft_folder_path)
logger.info(f"DEBUG: AFTER fix_material_ids: text segments with material_id={count2}")
5.5.3 最小化测试法
当完整流程太复杂时,编写最小化测试脚本隔离问题:
script = ScriptFile(1129, 1920, 30.0)
tseg = TextSegment("Hello", Timerange(0, 10000000), style=style)
script.add_segment(tseg, "TextTrack0")
output = script.dumps()
data = json.loads(output)
# 检查 data["materials"]["texts"] 是否有内容
5.5.4 缓存陷阱
Python 的 __pycache__ 会导致修改后的代码不生效:
- 每次修改后清除
__pycache__
- 使用
python -B 禁用字节码缓存
- 用
importlib.reload() 或重启进程确保加载最新代码
5.5.5 代码执行路径验证
在修复Bug前,先确认代码的实际执行路径:
- 使用日志和调试工具验证修复是否生效
- 检查是否存在绕过修复逻辑的替代路径
- 注意IDE工具(linter)可能自动回退代码修改
第六章 开发规范与最佳实践
6.1 素材路径管理
- 永远使用
DraftFolder.finalize_draft() 收尾,它会自动打包素材并生成路径
- 导入剪映后必须调用
update_content_paths(),将工作区路径替换为剪映目录路径
- 统一使用绝对路径方案,避免占位符路径的 draft_id 不一致问题
- 排除 materials/ 目录,剪映草稿目录中只保留 Resources/
6.2 时长与内容平衡
- 词汇展示段容易重叠,建议总视频时长 ≥ 词汇数 × 6秒
- 使用
JyProject 手动布局复杂场景
DraftValidator.validate() 检查片段重叠
6.3 TTS后端选择策略
| 场景 |
推荐后端 |
说明 |
| 开发测试 |
Edge-TTS |
免费云端,SSML支持好 |
| 生产离线 |
Kokoro |
82M模型,速度极快 |
| 极致音质 |
Chatterbox |
需GPU |
| 低资源 |
Piper |
轻量本地TTS |
6.4 钩子执行顺序
通过 HookManager 的 priority 参数控制执行顺序:
先超分(RealESRGANHook) → 再插帧(RIFEHook) → 最后渲染
6.5 草稿验证
生成后务必调用 DraftValidator.validate(),检查:
- 片段重叠
- 素材缺失
- 引用完整性
- 路径有效性
6.6 代码审查要点
- if-elif 链中的重复分支: Python 只执行第一个匹配的分支,后续同名分支是死代码
- 集合操作的完整性: 收集 ID 时必须覆盖所有素材类型,不能遗漏
- 删除操作的危险性:
del seg["material_id"] 这种破坏性操作必须有充分的条件保护
- 嵌套函数的作用域: 内部函数引用外部变量时,确保变量在正确的作用域中定义
- 导入逻辑一致性: 系统中存在多套导入逻辑时,确保所有路径都执行了必要的步骤
6.7 Linter 自动回退防范
- 使用 Python 脚本在运行前强制修改代码
- 修改后立即运行生成命令,不给linter回退的机会
- 在
.editorconfig 或 linter 配置中排除关键文件
第七章 扩展开发指南
7.1 添加自定义运动预设
from aivideo.core.motion_library import MotionLibrary, CameraMotion, CameraMotionType
MotionLibrary.register("my_signature_zoom", CameraMotion(
type=CameraMotionType.KEN_BURNS,
scale_start=1.0, scale_end=1.25,
pan_x_end=0.15,
easing=EasingFunction.EASE_IN_OUT
))
7.2 开发业务专用钩子
from aivideo.hooks.base import BaseHook, HookPoint, HookContext
class WatermarkHook(BaseHook):
hook_point = HookPoint.POST_BUILD
def run(self, context: HookContext) -> HookContext:
draft_path = context.metadata["draft_path"]
project = JyProject.load(draft_path)
project.add_text_simple("YourBrand", start_time="0s", duration="999s",
transform_y=0.45, opacity=0.3)
project.save()
return context
7.3 集成自定义TTS引擎
实现 integrations/tts/base.py 中的 BaseTTS 接口,注册到 TTSEngine 后端列表,即可享受自动降级和缓存机制。
7.4 构建企业级视频中台
将 AivideoConfig 与配置中心(如Nacos)打通,ArtifactStore 对接S3/OSS,Pipeline 结果通过 EventBus 推送到消息队列,形成Serverless视频生产流水线。
7.5 AI Agent集成
# 启动MCP服务器
# python -m aivideo serve
# 在Agent中调用DirectorAPI
# create_project → add_video → add_text → export
7.6 高级组合技
| 组合 |
效果 |
适用场景 |
| 逆向 + 正向叠加 |
逆向提取画面,正向生成全新配音和字幕 |
视频翻译、多语言版本 |
| 模板引擎 + 钩子 |
预制模板 + 自动运镜 + 插帧 |
老照片修复视频 |
| 时间线管理器 + ASR同步 |
词级时间戳 + 动态分配片段时长 |
卡拉OK字幕 |
| 视觉层级 + 音频混合 |
5层叠加 + 自动闪避 |
新闻播报、教学演示 |
附录
附录A: 修改文件索引
A.1 三方框架集成相关
| 文件 |
修改内容 |
aivideo/document/animation.py |
添加 Text_animation 别名;export_json() 添加 category_id/category_name/request_id/path |
aivideo/document/exceptions.py |
异常双继承 UniVideoError + 标准异常 |
aivideo/document/time_util.py |
tim() float语义统一;添加 tim_seconds() |
aivideo/document/video_segment.py |
source_timerange+speed联动;素材时长越界检查 |
aivideo/document/audio_segment.py |
source_timerange+speed联动;Loudness类;素材时长越界检查 |
aivideo/document/segment.py |
uniform_scale互斥校验 |
aivideo/document/text_segment.py |
export_material()动态填充;_color_to_hex();_resolve_font_path() |
aivideo/document/script_file.py |
合并重复TextSegment分支;滤镜导出字段修正;loudnesses注册 |
aivideo/document/track.py |
render_index修正;export_json名称行为修正 |
aivideo/document/effect_segment.py |
参数名兼容别名 |
aivideo/document/local_materials.py |
_get_placeholder_path()返回绝对路径 |
aivideo/document/draft_folder.py |
_update_path路径格式;update_meta_materials路径格式;_add_bgm_placeholder路径;import_draft排除materials/;composition结构修正;_resolve_material_path();_generate_local_cover();finalize_draft添加version/new_version |
aivideo/core/id_generator.py |
新建:统一ID生成 |
aivideo/core/draft_ops.py |
update_content_paths()路径替换逻辑 |
aivideo/core/exceptions.py |
UniVideoError体系 |
aivideo/engines/tts_engine.py |
SAMI TTS后端(待集成) |
aivideo/engines/dual_style_engine.py |
_import_to_jianying添加update_content_paths调用 |
aivideo/engines/draft_remixer_engine.py |
save/finalize顺序修正 |
aivideo/engines/reverse_engine.py |
_update_draft_content()添加version/new_version |
aivideo/skills/jianying_editor/scripts/asset_search.py |
同义词枚举映射恢复 |
aivideo/skills/jianying_editor/utils/errors.py |
DataError异常类 |
aivideo/skills/jianying_editor/core/media_ops.py |
add_media_safe错误日志 |
aivideo/document/compat.py |
新建:兼容层模块 |
A.2 Bug修复相关
| 文件 |
Bug |
修复内容 |
aivideo/tests/job1/main.py |
fix_material_ids删除text material_id |
收集text IDs |
aivideo/document/script_file.py |
重复elif TextSegment死代码 |
合并分支 |
aivideo/document/audio_segment.py |
缺少Loudness类 |
新增Loudness |
aivideo/document/text_segment.py |
顶层字段未填充 |
动态填充 |
aivideo/document/draft_folder.py |
_update_path未定义变量 |
路径构建修正 |
aivideo/document/animation.py |
动画缺少必要字段 |
添加4个字段 |
aivideo/document/script_file.py |
滤镜导出到错误字段 |
effects→filters |
aivideo/engines/dual_style_engine.py |
绕过import_draft |
添加update_content_paths |
aivideo/document/local_materials.py |
placeholder路径解析失败 |
返回绝对路径 |
aivideo/engines/draft_remixer_engine.py |
save/finalize顺序错误 |
先save再finalize |
附录B: 重构执行计划
第1天: P0 修复
| 时间 |
任务 |
文件 |
| 上午 |
source_timerange+speed联动 |
video_segment.py, audio_segment.py |
| 上午 |
异常继承体系兼容 |
exceptions.py |
| 下午 |
Text_animation别名 |
animation.py, init.py |
| 下午 |
tim()语义统一 |
time_util.py |
| 下午 |
UUID格式统一 |
id_generator.py + 多个文件 |
第2天: P1 修复
| 时间 |
任务 |
文件 |
| 上午 |
SAMI TTS后端 |
tts_engine.py |
| 上午 |
素材时长越界检查 |
video_segment.py, audio_segment.py |
| 下午 |
uniform_scale互斥校验 |
segment.py |
| 下午 |
TextBorder/TextSegment字段补全 |
text_segment.py |
| 下午 |
同义词枚举映射恢复 |
asset_search.py |
第3天: P2 修复 + 兼容层
| 时间 |
任务 |
文件 |
| 上午 |
3.1-3.5 行为差异修复 |
track.py, project_base.py, errors.py, media_ops.py, script_file.py |
| 下午 |
3.6-3.9 行为差异修复 |
track.py, effect_segment.py, script_file.py |
| 下午 |
创建兼容层模块 |
compat.py |
附录C: 验证方案
C.1 单元测试
def test_text_animation_alias():
from aivideo.document.animation import Text_animation, TextAnimationClip
assert Text_animation is TextAnimationClip
def test_exception_compatibility():
from aivideo.document.exceptions import TrackNotFound
e = TrackNotFound("test")
assert isinstance(e, NameError)
assert isinstance(e, UniVideoError)
def test_source_timerange_speed_linkage():
seg = VideoSegment(
material=mat,
target_timerange=Timerange(0, 10000000),
source_timerange=Timerange(0, 5000000),
speed=2.0
)
assert seg.target_timerange.duration == 2500000
def test_tim_float_semantic():
assert tim(1.5) == 2
assert tim_seconds(1.5) == 1500000
def test_uuid_format():
from aivideo.core.id_generator import generate_id
id_val = generate_id()
assert len(id_val) == 32
assert '-' not in id_val
C.2 集成测试
使用 jianying-editor-skill 的示例脚本验证兼容性:
simple_clip_demo.py — 基础剪辑
cloud_video_music_tts_demo.py — 云端素材+TTS
all_elements_regen.py — 全功能测试
C.3 回归测试
- 运行
aivideo/examples/ 下的所有示例
- 运行
aivideo/tests/ 下的所有测试
- 验证已有输出草稿的完整性
C.4 草稿验证清单
1. 检查 draft_content.json
→ videos 路径为绝对路径
→ audios 路径为绝对路径
→ 所有 material_id 在 materials 中有对应项
→ 所有 extra_material_refs 在 materials 中有对应项
→ version = 360000
→ new_version = "110.0.0"
2. 检查 draft_meta_info.json
→ file_Path 为绝对路径
→ type=2 为空数组
3. 检查 Resources/ 目录
→ 所有引用的文件存在
4. 检查 materials/ 目录不存在
5. 检查封面文件
→ draft_cover.jpg 存在
→ draft_local_cover.jpg 存在
6. 检查 composition
→ render_index_track_mode_on = false
→ 不含 is_drop_frame_timecode/common_masks/placeholder_infos
附录D: 风险评估
| 风险 |
概率 |
影响 |
缓解措施 |
| tim()语义变更导致现有代码出错 |
高 |
高 |
先搜索所有调用点,逐一确认 |
| UUID格式变更导致草稿不兼容 |
中 |
高 |
保留双格式支持,渐进迁移 |
| 异常双继承导致MRO冲突 |
低 |
中 |
测试所有异常的isinstance行为 |
| SAMI TTS WebSocket协议变更 |
中 |
中 |
添加版本检测和降级逻辑 |
| TrackType.text render_index变更影响现有草稿 |
中 |
中 |
添加草稿版本标记 |
| Linter自动回退修复 |
高 |
中 |
使用fix脚本强制修改 |
附录E: 完成标准
- 所有 P0 不兼容项修复完成
- 所有 P1 功能缺失项补全
- 所有 P2 行为差异项修正
- 兼容层模块创建完成
- 单元测试全部通过
- 集成测试(jianying-skill示例)全部通过
- 回归测试(aivideo现有功能)全部通过
- 审查报告中的所有项目状态更新为通过。