Install
openclaw skills install @unique-memory/article-to-videoConverts articles (docx/pdf/txt/md) to narrated videos with AI-generated visuals and TTS voiceover. Invoke when user asks to convert article/document to video, mentions 文章转视频, or needs text-to-video with narration.
openclaw skills install @unique-memory/article-to-videoConvert articles in Word (.docx), PDF (.pdf), Text (.txt), or Markdown (.md) format into narrated videos with AI-generated visuals, TTS voiceover, subtitles, background music, and scene transitions.
The pipeline has 5 stages, each handled by a dedicated Python script:
[Document] → ① parse_doc.py → scenes.json
↓
② generate_tts.py → audio + timing.json
↓
③ create_slides.py (or GenerateImage) → images
↓
④ assemble_video.py → final MP4 + SRT
↓
⑤ Output: video.mp4 + subtitle.srt
scripts/parse_doc.py)Parses the input document into a structured JSON of scenes.
Supported formats:
.docx → python-docx (paragraphs with heading levels).pdf → pdfplumber (page-by-page text extraction, table detection).txt → direct read, split by blank lines.md → markdown library, preserve heading hierarchyOutput format (scenes.json):
{
"title": "Article Title",
"scenes": [
{
"index": 0,
"heading": "Section Title",
"level": 1,
"narration": "Clean text suitable for TTS reading...",
"slide_text": "Key points for visual display...",
"image_prompt": "Description for AI image generation...",
"char_count": 250
}
],
"total_chars": 5000,
"estimated_duration_sec": 1000
}
Usage:
python scripts/parse_doc.py --input article.docx --output scenes.json
Key logic:
Content type auto-detection:
The parser automatically detects the document's content type using keyword analysis, and stores it in scenes.json as content_type. This drives visual style and BGM selection in later stages.
| Content Type | Description | Auto Theme | Ken Burns |
|---|---|---|---|
finance | 金融/投资报告 | ocean (deep blue + gold) | slow |
business | 商业/管理 | default (purple) | normal |
technology | 科技/IT | dark (black + cyan) | fast |
science | 科学/研究 | ocean (deep blue) | slow |
education | 教育/教程 | warm (dark + orange) | normal |
news | 新闻/资讯 | light (white + red) | fast |
lifestyle | 生活/随笔 | warm (dark + orange) | normal |
default | 通用 | default | normal |
Override with --content-type technology.
scripts/generate_tts.py)Converts narration text to speech with retry and fallback.
Primary engine: edge-tts (free, high quality, multi-voice Chinese support)
Fallback chain: edge-tts → gTTS → pyttsx3 (offline)
Key features:
ffprobe/ffmpeg -i after generationscene_NN.mp3 + timing.json (with actual measured durations)Voice Profiles (new):
Use --profile to apply a preset combination of voice + rate + pitch + volume:
python scripts/generate_tts.py --scenes scenes.json --outdir ./audio --profile professional
| Profile | Voice | Rate | Pitch | Best For |
|---|---|---|---|---|
professional | Yunyang (男声播音) | +0% | +0Hz | 商务报告、金融分析 |
casual | Xiaoxiao (女声亲切) | +10% | +2Hz | 博客文章、生活分享 |
energetic | Yunxi (男声活力) | +15% | +5Hz | 科技资讯、产品发布 |
documentary | Yunjian (男声解说) | -5% | -2Hz | 历史人文、深度报道 |
warm | Xiaoyi (女声温柔) | -5% | +0Hz | 教育课程、情感故事 |
Available voices (Chinese):
zh-CN-XiaoxiaoNeural - 女声,亲切自然 (default)zh-CN-YunxiNeural - 男声,年轻活力zh-CN-YunyangNeural - 男声,专业播音zh-CN-XiaoyiNeural - 女声,温柔甜美zh-CN-YunjianNeural - 男声,体育解说scripts/create_slides.py)Two modes for generating scene visuals:
Mode A - Template slides (default, fast):
Renders HTML templates to PNG images using the built-in slide.html template.
--theme override)Mode B - AI image generation (optional, higher quality):
Uses the GenerateImage tool or Seedream plugin to create custom illustrations.
image_prompt is automatically adapted based on the detected content type (e.g. finance → financial infographic style, technology → futuristic cyberpunk aesthetic)ai_image_requests.json — a manifest of all image generation requests with prompts, output paths, and dimensionsAI Image Style Mapping:
| Content Type | Artistic Style | Color Mood |
|---|---|---|
finance | Financial infographic, corporate | Deep blue + gold |
business | Corporate illustration, minimalist | Purple + white |
technology | Futuristic tech, digital cyberpunk | Dark + neon cyan/purple |
science | Scientific illustration, precise | Deep blue + teal |
education | Warm educational, friendly | Orange + soft blue |
news | Editorial news, impactful | White + red/blue |
lifestyle | Lifestyle photography, natural | Soft warm tones |
Usage (template mode):
python scripts/create_slides.py --scenes scenes.json --outdir ./slides --mode template
Usage (AI mode): The skill instructions below describe how to use GenerateImage for this stage.
scripts/assemble_video.py)Combines images + audio into final video using FFmpeg.
Pipeline:
Key features:
zoompan filter with zoom + pan for cinematic camera movement. Pan direction (right/left/down/up) is deterministically selected per scene via filename hash, ensuring varied but reproducible movement. Pan range is configurable per speed preset (slow: 60px, normal: 80px, fast: 100px).xfade filter (fade, dissolve, slideleft)assets/bgm/<style>/ based on content type--bgm-style to force a specific BGM style (e.g. --bgm-style cinematic)amix with automatic duckingsubtitles filter with Chinese font (FontSize=12, no background box, 20px from bottom)fast preset and CRF 24 for subtitle burning and concatenationUsage:
# BGM auto-selected based on content type (with style-specific volume)
python scripts/assemble_video.py \
--slides ./slides \
--audio ./audio \
--timing ./audio/timing.json \
--output final_video.mp4 \
--resolution 1920x1080 \
--transition fade
# Override BGM style (ignores content type mapping)
python scripts/assemble_video.py \
--slides ./slides \
--audio ./audio \
--timing ./audio/timing.json \
--output final_video.mp4 \
--bgm-style cinematic \
--resolution 1920x1080
# Or specify BGM file manually
python scripts/assemble_video.py \
--slides ./slides \
--audio ./audio \
--timing ./audio/timing.json \
--output final_video.mp4 \
--bgm ./assets/bgm/corporate/track01.mp3 \
--resolution 1920x1080
scripts/bgm_manager.py)Manage background music files in the assets/bgm/<style>/ directory structure.
BGM Styles:
| Style | Directory | Volume | Best For |
|---|---|---|---|
corporate | corporate/ | -18dB | 商务、金融、新闻 |
acoustic | acoustic/ | -15dB | 生活、随笔 |
electronic | electronic/ | -20dB | 科技、产品发布 |
cinematic | cinematic/ | -12dB | 科学、纪录片 |
soft | soft/ | -16dB | 教育、儿童 |
Commands:
# List all BGM files
python scripts/bgm_manager.py list
# List files in a specific style
python scripts/bgm_manager.py list --style corporate
# Upload (copy) audio file to a style directory
python scripts/bgm_manager.py upload --file music.mp3 --style corporate
python scripts/bgm_manager.py upload --file music.mp3 --style corporate --name track01
# Remove a BGM file
python scripts/bgm_manager.py remove --style corporate --file track01.mp3
# Validate an audio file before uploading
python scripts/bgm_manager.py validate --file music.mp3
# Show BGM configuration summary
python scripts/bgm_manager.py info
Upload validation:
.mp3, .m4a, .wavFinal deliverables:
final_video.mp4 - The complete narrated videosubtitle.srt - Subtitle file (also burned into video)thumbnail.jpg - Video thumbnail (first scene frame)# Step 1: Parse document (auto-detects content type)
python scripts/parse_doc.py --input article.docx --output scenes.json
# Or manually specify: --content-type technology
# Step 2: Generate TTS audio (use voice profile or individual settings)
python scripts/generate_tts.py --scenes scenes.json --outdir ./audio --profile professional
# Or: --voice zh-CN-XiaoxiaoNeural --rate +0% --pitch +0Hz
# Step 3: Generate slide images (auto-selects theme from content type)
python scripts/create_slides.py --scenes scenes.json --outdir ./slides --mode template
# Or override: --theme dark
# Step 4: Assemble final video (auto-selects BGM from content type)
python scripts/assemble_video.py \
--slides ./slides \
--audio ./audio \
--timing ./audio/timing.json \
--output final_video.mp4 \
--resolution 1920x1080
All defaults are in scripts/config.py. Key options:
| Option | Default | Description |
|---|---|---|
voice | zh-CN-XiaoxiaoNeural | TTS voice |
--profile | (none) | Voice profile preset (professional/casual/energetic/documentary/warm) |
--content-type | auto | Override content type detection (finance/business/technology/...) |
--bgm-style | auto | Override BGM style (corporate/acoustic/electronic/cinematic/soft) |
resolution | 1920x1080 | Output video resolution |
transition | fade | Scene transition type |
bgm_volume | style-specific | Background music volume (per-style: corporate -18dB, cinematic -12dB, etc.) |
narration_volume | -3dB | Narration volume |
ken_burns | True | Enable Ken Burns zoom + pan effect |
ken_burns_speed | auto | Ken Burns speed (slow/normal/fast) — auto from content type |
ken_burns_pan_range | 60/80/100 | Pan range in pixels per speed (slow/normal/fast) |
bgm_auto_select | True | Auto-select BGM from content type |
bgm_random | True | Randomly select from multiple BGM files in style directory |
ai_image_size | landscape_16_9 | AI image generation size preset |
subtitle | True | Burn subtitles into video |
subtitle_font | Microsoft YaHei | Subtitle font family |
subtitle_font_size | 12 | Subtitle font size (ASS FontSize) |
subtitle_border_style | 1 | ASS BorderStyle (1=outline only, 3=background box) |
subtitle_margin_v | 20 | Subtitle vertical margin from bottom (pixels) |
tts_delay | 2.0 | Seconds between TTS calls (anti-throttle) |
tts_max_retries | 3 | Max retry on 429 errors |
| Platform | Resolution | Aspect |
|---|---|---|
| YouTube/B站 | 1920x1080 | 16:9 |
| 抖音/TikTok | 1080x1920 | 9:16 |
| 小红书 | 1080x1440 | 3:4 |
imageio-ffmpeg which bundles a full FFmpeg binary with all codecs (PNG decode, H.264 encode, AAC/MP3 audio). No separate system FFmpeg installation required. The config auto-detects the bundled binary.progress.json. Re-running skips completed scenes