多语种AI数字人播报视频制作:从0到1全栈指南
1. 技术全景与平台对比
1.1 数字人平台矩阵分析
| 平台名称 |
核心功能 |
语言支持 |
价格 |
质量等级 |
适合场景 |
| HeyGen |
语音克隆、口型同步 |
40+种 |
$24-720/月 |
⭐⭐⭐⭐⭐ |
企业培训、营销视频 |
| Synthesia |
120+数字人、模板库 |
120+种 |
$30-500/月 |
⭐⭐⭐⭐⭐ |
企业培训、教育内容 |
| D-ID |
照片动画、实时对话 |
100+种 |
$5.9-299/月 |
⭐⭐⭐⭐ |
客服、个性化视频 |
| Colossyan |
多角色对话、场景模板 |
70+种 |
$19-499/月 |
⭐⭐⭐⭐ |
团队协作、模拟面试 |
| Pictory |
文字转视频、AI配音 |
20+种 |
$19-99/月 |
⭐⭐⭐ |
营销、社交媒体 |
| Elai.io |
定制数字人、PPT转视频 |
65+种 |
$23-499/月 |
⭐⭐⭐⭐ |
电商、产品演示 |
| 本地方案 |
开源模型、完全定制 |
无限 |
硬件成本 |
⭐⭐-⭐⭐⭐⭐ |
隐私敏感、高定制 |
1.2 技术架构概览
graph TB
A[多语种数字人系统] --> B[输入层]
A --> C[处理层]
A --> D[输出层]
B --> B1[文本脚本]
B --> B2[语音输入]
B --> B3[形象选择]
B --> B4[背景模板]
C --> C1[文本翻译]
C --> C2[语音合成]
C --> C3[口型同步]
C --> C4[表情动画]
D --> D1[视频渲染]
D --> D2[字幕生成]
D --> D3[音轨混合]
D --> D4[格式导出]
2. 入门篇:5分钟制作第一个多语种数字人视频
2.1 HeyGen快速入门
"""
HeyGen API快速入门:制作多语种数字人视频
"""
import requests
import json
import time
import os
from pathlib import Path
from dotenv import load_dotenv
from typing import Dict, List, Optional
class HeyGenMultilingualCreator:
"""HeyGen多语种视频创建器"""
def __init__(self, api_key=None):
load_dotenv()
self.api_key = api_key or os.getenv('HEYGEN_API_KEY')
if not self.api_key:
raise ValueError("请设置HEYGEN_API_KEY环境变量")
self.base_url = "https://api.heygen.com"
self.headers = {
"X-Api-Key": self.api_key,
"Content-Type": "application/json"
}
self.output_dir = Path("multilingual_videos")
self.output_dir.mkdir(exist_ok=True)
self.language_map = {
"中文": "zh-CN",
"英文": "en-US",
"日文": "ja-JP",
"韩文": "ko-KR",
"法文": "fr-FR",
"德文": "de-DE",
"西班牙文": "es-ES",
"俄文": "ru-RU",
"阿拉伯文": "ar-SA",
"葡萄牙文": "pt-BR",
"意大利文": "it-IT",
"印地文": "hi-IN",
"泰文": "th-TH",
"越南文": "vi-VN"
}
self.avatars = {
"male_business": {
"id": "Adam_v2",
"name": "亚当(商务男)",
"styles": ["business", "casual"]
},
"female_business": {
"id": "Alice_v2",
"name": "爱丽丝(商务女)",
"styles": ["business", "professional"]
},
"male_casual": {
"id": "Charlie_v2",
"name": "查理(休闲男)",
"styles": ["casual", "friendly"]
},
"female_casual": {
"id": "Diana_v2",
"name": "戴安娜(休闲女)",
"styles": ["casual", "enthusiastic"]
}
}
print("✅ HeyGen多语种视频创建器初始化完成")
def create_video(self, script: str, language: str = "中文",
avatar: str = "male_business", **kwargs) -> Optional[Path]:
"""创建单个语言视频"""
if language not in self.language_map:
print(f"❌ 不支持的语言: {language}")
print(f"可用语言: {', '.join(self.language_map.keys())}")
return None
if avatar not in self.avatars:
print(f"❌ 无效的数字人: {avatar}")
print(f"可用数字人: {', '.join(self.avatars.keys())}")
return None
print(f"🎬 开始创建 {language} 视频...")
print(f"📝 脚本长度: {len(script)} 字符")
print(f"🤖 数字人: {self.avatars[avatar]['name']}")
data = {
"video_inputs": [{
"character": {
"type": "avatar",
"avatar_id": self.avatars[avatar]["id"],
"avatar_style": "normal"
},
"voice": {
"type": "text",
"input_text": script,
"voice_id": self._get_voice_id(language)
},
"background": {
"type": "color",
"value": kwargs.get("bg_color", "#1a1a1a")
}
}],
"dimension": {
"width": kwargs.get("width", 1920),
"height": kwargs.get("height", 1080)
},
"test": kwargs.get("test", False)
}
if kwargs.get("subtitles", True):
data["video_inputs"][0]["subtitles"] = {
"enabled": True,
"font_color": "#ffffff",
"background_color": "#00000080",
"font_size": 24
}
try:
response = requests.post(
f"{self.base_url}/v1/video/generate",
headers=self.headers,
json=data,
timeout=30
)
if response.status_code == 200:
result = response.json()
video_id = result["data"]["video_id"]
print(f"📤 视频生成任务已提交,ID: {video_id}")
video_url = self._poll_video_status(video_id)
if video_url:
video_path = self._download_video(video_url, language, avatar)
return video_path
else:
print("❌ 视频生成失败")
return None
else:
print(f"❌ API请求失败: {response.status_code}")
print(f"响应: {response.text}")
return None
except Exception as e:
print(f"❌ 请求过程中出错: {str(e)}")
return None
def create_multilingual_video(self, scripts: Dict[str, str],
avatar: str = "male_business",
output_name: str = "multilingual") -> List[Dict]:
"""创建多语种视频系列"""
results = []
print(f"\n{'='*60}")
print(f"🚀 开始创建多语种视频系列")
print(f"📊 语言数量: {len(scripts)}")
print(f"{'='*60}\n")
for i, (language, script) in enumerate(scripts.items(), 1):
print(f"\n▶️ 处理语言 {i}/{len(scripts)}: {language}")
video_path = self.create_video(
script=script,
language=language,
avatar=avatar,
subtitles=True
)
results.append({
"language": language,
"script": script[:100] + "..." if len(script) > 100 else script,
"video_path": video_path,
"success": video_path is not None
})
if i < len(scripts):
print("⏸️ 等待15秒继续下一个语言...")
time.sleep(15)
self._generate_multilingual_report(results, output_name)
return results
def create_bilingual_comparison(self, script_en: str, script_zh: str,
avatar_en: str = "male_business",
avatar_zh: str = "female_business") -> Optional[Path]:
"""创建双语对比视频"""
print("🎬 创建双语对比视频...")
print("📝 生成英文版本...")
video_en = self.create_video(script_en, "英文", avatar_en)
if not video_en:
return None
time.sleep(10)
print("📝 生成中文版本...")
video_zh = self.create_video(script_zh, "中文", avatar_zh)
if not video_zh:
return None
try:
output_path = self._merge_videos_side_by_side(video_en, video_zh)
return output_path
except Exception as e:
print(f"❌ 视频合并失败: {str(e)}")
return None
def _get_voice_id(self, language: str) -> str:
"""获取语音ID"""
voice_mapping = {
"中文": "zh-CN-YunxiNeural",
"英文": "en-US-AriaNeural",
"日文": "ja-JP-NanamiNeural",
"韩文": "ko-KR-SunHiNeural",
"法文": "fr-FR-DeniseNeural",
"德文": "de-DE-KatjaNeural",
"西班牙文": "es-ES-ElviraNeural",
"俄文": "ru-RU-SvetlanaNeural"
}
return voice_mapping.get(language, "en-US-AriaNeural")
def _poll_video_status(self, video_id: str, max_attempts: int = 60) -> Optional[str]:
"""轮询视频生成状态"""
print("⏳ 等待视频生成...", end="", flush=True)
for attempt in range(max_attempts):
time.sleep(10)
try:
status_response = requests.get(
f"{self.base_url}/v1/video/{video_id}",
headers=self.headers,
timeout=10
)
if status_response.status_code == 200:
status_data = status_response.json()
status = status_data["data"]["status"]
print(".", end="", flush=True)
if status == "completed":
print("\n✅ 视频生成完成!")
return status_data["data"]["video_url"]
elif status == "failed":
print(f"\n❌ 生成失败: {status_data.get('error', '未知错误')}")
return None
else:
print(f"\n⚠️ 状态查询失败: {status_response.status_code}")
except Exception as e:
print(f"\n⚠️ 状态查询异常: {str(e)}")
print(f"\n❌ 生成超时({max_attempts * 10}秒)")
return None
def _download_video(self, video_url: str, language: str, avatar: str) -> Path:
"""下载视频文件"""
try:
timestamp = time.strftime("%Y%m%d_%H%M%S")
lang_code = self.language_map.get(language, "unknown")
avatar_name = avatar.replace("_", "-")
filename = f"{timestamp}_{lang_code}_{avatar_name}.mp4"
filepath = self.output_dir / filename
print(f"⬇️ 下载视频到: {filepath}")
response = requests.get(video_url, stream=True, timeout=30)
if response.status_code == 200:
total_size = int(response.headers.get('content-length', 0))
downloaded = 0
with open(filepath, 'wb') as f:
for chunk in response.iter_content(chunk_size=8192):
f.write(chunk)
downloaded += len(chunk)
if total_size > 0:
percent = downloaded / total_size * 100
print(f"\r下载进度: {percent:.1f}%", end="", flush=True)
print(f"\n✅ 下载完成!大小: {filepath.stat().st_size / (1024*1024):.1f} MB")
return filepath
else:
print(f"❌ 下载失败: {response.status_code}")
return None
except Exception as e:
print(f"❌ 下载过程中出错: {str(e)}")
return None
def _merge_videos_side_by_side(self, video1: Path, video2: Path) -> Optional[Path]:
"""使用ffmpeg合并两个视频为分屏显示"""
try:
import subprocess
output_filename = f"comparison_{time.strftime('%Y%m%d_%H%M%S')}.mp4"
output_path = self.output_dir / output_filename
cmd = [
'ffmpeg',
'-i', str(video1),
'-i', str(video2),
'-filter_complex',
'[0:v]scale=960:1080,setpts=PTS-STARTPTS[left];'
'[1:v]scale=960:1080,setpts=PTS-STARTPTS[right];'
'[left][right]hstack=inputs=2',
'-c:v', 'libx264',
'-preset', 'fast',
'-crf', '23',
'-c:a', 'aac',
'-b:a', '128k',
'-y',
str(output_path)
]
print("🔄 正在合并视频...")
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode == 0:
print(f"✅ 视频合并成功: {output_path}")
return output_path
else:
print(f"❌ 视频合并失败: {result.stderr}")
return None
except Exception as e:
print(f"❌ 视频合并异常: {str(e)}")
return None
def _generate_multilingual_report(self, results: List[Dict], output_name: str):
"""生成多语种报告"""
report_path = self.output_dir / f"{output_name}_report.md"
with open(report_path, 'w', encoding='utf-8') as f:
f.write(f"# 多语种数字人视频生成报告\n\n")
f.write(f"生成时间: {time.strftime('%Y-%m-%d %H:%M:%S')}\n\n")
success_count = sum(1 for r in results if r['success'])
total_count = len(results)
f.write("## 📊 统计信息\n")
f.write(f"- 总语言数: {total_count}\n")
f.write(f"- 成功数: {success_count}\n")
f.write(f"- 失败数: {total_count - success_count}\n")
f.write(f"- 成功率: {success_count/total_count*100:.1f}%\n\n")
f.write("## 📝 详细结果\n\n")
for result in results:
status_icon = "✅" if result['success'] else "❌"
f.write(f"### {status_icon} {result['language']}\n")
f.write(f"**脚本摘要**: {result['script']}\n\n")
if result['success']:
f.write(f"**视频文件**: `{result['video_path'].name}`\n")
f.write(f"**文件大小**: {result['video_path'].stat().st_size / (1024*1024):.1f} MB\n")
else:
f.write("**状态**: 生成失败\n")
f.write("\n---\n\n")
f.write("## 💡 使用建议\n\n")
f.write("1. **文件管理**: 建议按项目分类存放视频文件\n")
f.write("2. **质量检查**: 生成后检查口型同步是否准确\n")
f.write("3. **批量处理**: 建议每次最多处理5个语言,避免API限流\n")
f.write("4. **字幕校对**: 自动生成的字幕可能需要人工校对\n")
print(f"📊 生成报告: {report_path}")
if __name__ == "__main__":
creator = HeyGenMultilingualCreator()
print("示例1: 创建中文数字人视频")
chinese_script = """
大家好,欢迎来到AI数字人教学视频。
今天我们将学习如何使用人工智能技术创建多语种播报视频。
这项技术可以帮助企业快速制作全球化内容,节省大量时间和成本。
让我们开始吧!
"""
video_path = creator.create_video(
script=chinese_script,
language="中文",
avatar="female_business",
subtitles=True,
bg_color="#2c3e50"
)
if video_path:
print(f"🎉 视频创建成功: {video_path}")
print("\n示例2: 创建多语种系列视频")
multilingual_scripts = {
"英文": "Welcome to our AI digital human tutorial. Today we'll learn how to create multilingual videos using artificial intelligence.",
"中文": "欢迎来到AI数字人教程。今天我们将学习如何使用人工智能创建多语种视频。",
"日文": "AIデジタルヒューマンチュートリアルへようこそ。本日は人工知能を使った多言語動画の作成方法を学びます。",
"韩文": "AI 디지털 휴먼 튜토리얼에 오신 것을 환영합니다. 오늘은 인공지능을 사용하여 다국어 동영상을 만드는 방법을 배웁니다."
}
results = creator.create_multilingual_video(
scripts=multilingual_scripts,
avatar="male_business",
output_name="tutorial_intro"
)
print("\n示例3: 创建双语对比视频")
en_script = "AI technology is revolutionizing video production. It enables fast, cost-effective multilingual content creation."
zh_script = "AI技术正在革命性地改变视频制作。它使得快速、低成本的多语种内容创作成为可能。"
comparison_path = creator.create_bilingual_comparison(
script_en=en_script,
script_zh=zh_script,
avatar_en="male_business",
avatar_zh="female_business"
)
if comparison_path:
print(f"🎉 双语对比视频创建成功: {comparison_path}")
2.2 环境配置与API获取
# 多语种数字人视频制作环境配置
## 第一步:获取API密钥
### 1. HeyGen API
1. 访问 https://www.heygen.com
2. 注册账号并登录
3. 进入Dashboard → API Settings
4. 点击"Generate API Key"
5. 复制API密钥(以`sk-`开头)
### 2. 备用方案:Synthesia API
1. 访问 https://www.synthesia.io/api
2. 申请API访问权限
3. 获取API密钥
## 第二步:本地环境配置
```bash
# 1. 检查Python版本(需要3.8+)
python --version
# 2. 创建虚拟环境
python -m venv digital-human-env
# 3. 激活虚拟环境
# Windows:
digital-human-env\Scripts\activate
# Mac/Linux:
source digital-human-env/bin/activate
# 4. 安装依赖包
pip install requests python-dotenv pillow moviepy opencv-python numpy
# 5. 安装FFmpeg(视频处理必需)
# Ubuntu/Debian:
sudo apt-get install ffmpeg
# Mac:
brew install ffmpeg
# Windows: 从 https://ffmpeg.org/download.html 下载
# 6. 创建环境变量文件
cat > .env << EOF
HEYGEN_API_KEY=your_heygen_api_key_here
SYNTHESIA_API_KEY=your_synthesia_api_key_here
OPENAI_API_KEY=your_openai_key_for_translation
DEFAULT_LANGUAGE=zh-CN
EOF
# 7. 创建项目结构
mkdir -p multilingual_videos/{raw,processed,exports}
mkdir -p scripts/{translations,templates}
mkdir -p assets/{backgrounds,logos,music}
mkdir -p outputs/{single,bilingual,multilingual}
第三步:验证环境
import os
import sys
from pathlib import Path
def test_environment():
print("🔍 数字人视频制作环境测试")
print("="*50)
py_version = sys.version_info
print(f"Python版本: {py_version.major}.{py_version.minor}.{py_version.micro}")
if py_version.major == 3 and py_version.minor >= 8:
print("✅ Python版本符合要求")
else:
print("❌ 需要Python 3.8+")
from dotenv import load_dotenv
load_dotenv()
required_envs = ['HEYGEN_API_KEY']
for env in required_envs:
value = os.getenv(env)
if value and len(value) > 10:
print(f"✅ {env}: 已设置")
else:
print(f"❌ {env}: 未设置或无效")
required_dirs = [
'multilingual_videos',
'scripts',
'assets',
'outputs'
]
for dir_name in required_dirs:
if Path(dir_name).exists():
print(f"✅ 目录 '{dir_name}': 存在")
else:
print(f"⚠️ 目录 '{dir_name}': 不存在")
try:
import subprocess
result = subprocess.run(['ffmpeg', '-version'],
capture_output=True, text=True)
if result.returncode == 0:
print("✅ FFmpeg: 已安装")
else:
print("❌ FFmpeg: 未正确安装")
except:
print("❌ FFmpeg: 未安装")
print("="*50)
print("环境测试完成")
if __name__ == "__main__":
test_environment()
第四步:快速测试
运行快速开始脚本:
python heygen_quickstart.py
如果一切正常,你应该能在multilingual_videos目录下看到生成的视频文件。
## 3. 进阶篇:自动化工作流与批量处理
### 3.1 全自动多语种视频生成系统
```python
# multilingual_workflow.py
"""
全自动多语种数字人视频生成工作流
支持:翻译 -> 脚本优化 -> 视频生成 -> 后期处理
"""
import os
import json
import time
from datetime import datetime
from typing import Dict, List, Optional, Tuple
from dataclasses import dataclass
from pathlib import Path
import pandas as pd
# 假设已安装的库
import openai
from dotenv import load_dotenv
@dataclass
class VideoProject:
"""视频项目配置"""
project_id: str
base_language: str = "中文"
target_languages: List[str] = None
template_id: str = "business_presentation"
avatar_config: Dict = None
output_format: Dict = None
def __post_init__(self):
if self.target_languages is None:
self.target_languages = ["英文", "日文", "韩文"]
if self.avatar_config is None:
self.avatar_config = {
"中文": "female_business",
"英文": "male_business",
"日文": "female_business",
"韩文": "male_business"
}
if self.output_format is None:
self.output_format = {
"resolution": "1080p",
"aspect_ratio": "16:9",
"with_subtitles": True,
"with_intro": True,
"with_outro": True
}
class MultilingualWorkflow:
"""多语种工作流引擎"""
def __init__(self, heygen_api_key: str, openai_api_key: str = None):
load_dotenv()
self.heygen_key = heygen_api_key or os.getenv('HEYGEN_API_KEY')
self.openai_key = openai_api_key or os.getenv('OPENAI_API_KEY')
if self.openai_key:
openai.api_key = self.openai_key
# 初始化组件
self.translator = TranslationEngine(self.openai_key)
self.script_optimizer = ScriptOptimizer()
self.video_generator = VideoGenerator(self.heygen_key)
self.post_processor = PostProcessor()
# 项目跟踪
self.projects = {}
print("🚀 多语种视频工作流引擎初始化完成")
def create_project(self, project_name: str, base_script: str, **kwargs) -> str:
"""创建新项目"""
project_id = f"proj_{datetime.now().strftime('%Y%m%d_%H%M%S')}"
project = VideoProject(
project_id=project_id,
**kwargs
)
# 保存项目配置
project_config = {
"project_id": project_id,
"project_name": project_name,
"created_at": datetime.now().isoformat(),
"base_script": base_script,
"config": project.__dict__
}
# 创建项目目录
project_dir = Path(f"projects/{project_id}")
project_dir.mkdir(parents=True, exist_ok=True)
# 保存配置
config_path = project_dir / "config.json"
with open(config_path, 'w', encoding='utf-8') as f:
json.dump(project_config, f, ensure_ascii=False, indent=2)
self.projects[project_id] = project_config
print(f"📁 项目创建成功: {project_name} (ID: {project_id})")
return project_id
def execute_workflow(self, project_id: str) -> Dict:
"""执行完整工作流"""
if project_id not in self.projects:
print(f"❌ 项目不存在: {project_id}")
return None
project_config = self.projects[project_id]
project = VideoProject(**project_config["config"])
print(f"\n{'='*60}")
print(f"🚀 开始执行工作流: {project_config['project_name']}")
print(f"📊 目标语言: {', '.join(project.target_languages)}")
print(f"{'='*60}\n")
results = {
"project_id": project_id,
"project_name": project_config["project_name"],
"workflow_start": datetime.now().isoformat(),
"languages": {}
}
# 1. 脚本翻译
print("📝 步骤1: 脚本翻译")
translations = self._translate_script(
project_config["base_script"],
project.base_language,
project.target_languages
)
# 2. 脚本优化
print("\n✨ 步骤2: 脚本优化")
optimized_scripts = {}
for lang, script in translations.items():
print(f" 优化 {lang} 脚本...")
optimized = self.script_optimizer.optimize_for_video(
script,
lang,
project.template_id
)
optimized_scripts[lang] = optimized
# 3. 视频生成
print("\n🎬 步骤3: 视频生成")
video_results = {}
for lang, script in optimized_scripts.items():
print(f" 生成 {lang} 视频...")
avatar = project.avatar_config.get(lang, "male_business")
video_path = self.video_generator.generate(
script=script,
language=lang,
avatar=avatar,
project_id=project_id
)
video_results[lang] = {
"script": script,
"video_path": video_path,
"avatar": avatar,
"success": video_path is not None
}
# 避免限流
if lang != list(optimized_scripts.keys())[-1]:
print(" 等待20秒继续...")
time.sleep(20)
# 4. 后期处理
print("\n🎨 步骤4: 后期处理")
processed_videos = {}
successful_videos = {
lang: data for lang, data in video_results.items()
if data["success"]
}
if successful_videos:
processed = self.post_processor.add_branding(
successful_videos,
project_id,
project.output_format
)
for lang, video_path in processed.items():
if video_path:
processed_videos[lang] = video_path
# 保存结果
results["languages"] = {
lang: {
"original_translation": translations.get(lang),
"optimized_script": optimized_scripts.get(lang),
"raw_video": video_results[lang]["video_path"],
"processed_video": processed_videos.get(lang),
"success": video_results[lang]["success"]
}
for lang in project.target_languages
}
results["workflow_end"] = datetime.now().isoformat()
results["success_count"] = sum(
1 for lang_data in results["languages"].values()
if lang_data["success"]
)
# 生成报告
self._generate_workflow_report(results, project_id)
return results
def _translate_script(self, base_script: str, base_lang: str,
target_langs: List[str]) -> Dict[str, str]:
"""翻译脚本到目标语言"""
translations = {}
for target_lang in target_langs:
if target_lang == base_lang:
translations[target_lang] = base_script
continue
print(f" 翻译到 {target_lang}...")
try:
# 使用OpenAI翻译
response = openai.ChatCompletion.create(
model="gpt-4",
messages=[
{"role": "system", "content": f"你是一个专业的视频脚本翻译员。将以下{base_lang}脚本翻译成{target_lang},保持口语化和视频播报的节奏。"},
{"role": "user", "content": base_script}
],
temperature=0.3,
max_tokens=2000
)
translation = response.choices[0].message.content
translations[target_lang] = translation
print(f" ✅ 翻译完成 ({len(translation)} 字符)")
except Exception as e:
print(f" ❌ 翻译失败: {str(e)}")
translations[target_lang] = None
return translations
def _generate_workflow_report(self, results: Dict, project_id: str):
"""生成工作流报告"""
project_dir = Path(f"projects/{project_id}")
report_path = project_dir / "workflow_report.md"
with open(report_path, 'w', encoding='utf-8') as f:
f.write(f"# 多语种视频工作流执行报告\n\n")
f.write(f"## 项目信息\n")
f.write(f"- **项目ID**: {results['project_id']}\n")
f.write(f"- **项目名称**: {results['project_name']}\n")
f.write(f"- **开始时间**: {results['workflow_start']}\n")
f.write(f"- **结束时间**: {results['workflow_end']}\n")
f.write(f"- **成功率**: {results['success_count']}/{len(results['languages'])}\n\n")
f.write("## 语言详情\n\n")
for lang, data in results["languages"].items():
status = "✅ 成功" if data["success"] else "❌ 失败"
f.write(f"### {lang} - {status}\n\n")
if data["optimized_script"]:
f.write("**优化后脚本**:\n")
f.write(f"> {data['optimized_script'][:200]}...\n\n")
if data["raw_video"]:
f.write(f"**原始视频**: `{data['raw_video']}`\n")
if data.get("processed_video"):
f.write(f"**处理后视频**: `{data['processed_video']}`\n")
f.write("\n---\n\n")
# 总结和建议
f.write("## 📊 统计总结\n\n")
# 计算成功率
success_rate = results["success_count"] / len(results["languages"]) * 100
f.write(f"- **总语言数**: {len(results['languages'])}\n")
f.write(f"- **成功数**: {results['success_count']}\n")
f.write(f"- **成功率**: {success_rate:.1f}%\n")
f.write(f"- **总耗时**: 约{(len(results['languages']) * 30) // 60}分钟\n\n")
f.write("## 💡 改进建议\n\n")
if success_rate < 80:
f.write("1. **检查API配额**: 部分失败可能是API限制导致\n")
f.write("2. **优化脚本**: 过长的脚本可能导致生成失败\n")
f.write("3. **分批处理**: 建议每次处理不超过5个语言\n")
else:
f.write("✅ 工作流执行良好,继续保持!\n")
print(f"📊 工作流报告已生成: {report_path}")
class TranslationEngine:
"""翻译引擎"""
def __init__(self, api_key: str = None):
self.api_key = api_key
self.supported_languages = [
"中文", "英文", "日文", "韩文", "法文", "德文",
"西班牙文", "俄文", "葡萄牙文", "意大利文"
]
def translate(self, text: str, source_lang: str, target_lang: str) -> Optional[str]:
"""翻译文本"""
if not self.api_key:
print("⚠️ Open