| name | cmm-video-production |
| description | Use this CMM skill to plan video production for content packages, including short-video plans, scripts, storyboards, captions, asset specs, render packages, AI-video generation plans, FFmpeg post-processing plans, and title/cover/hook checks. It directly creates video_plan and video_package contracts with CMM video structure and quality gates, while treating legacy video skills only as optional approved execution backends. This new CMM layer does not modify legacy video skills and does not silently render or call paid APIs. |
| version | 0.1.0 |
CMM Video Production
cmm-video-production is the video routing layer in the CMM content factory.
It consumes a content_package, decides whether video is needed, creates a
video_plan, and produces script structure, storyboard, captions, asset needs,
backend route options, and quality gates. After user confirmation, an approved
backend can render, generate, or edit media. Its final artifact is a
video_package.
Boundary
Use this skill for:
- Planning short-video or long-video production from a content package.
- Turning content into video plan, script direction, storyboard, caption plan,
asset needs, and quality checks.
- Producing CMM-native script, storyboard, caption, asset, and quality specs.
- Selecting the bundled render engine, optional AI-video API,
ffmpeg, or TTS
providers only as approved execution steps.
- Producing a structured
video_package for publishing workflows.
Do not use this skill to:
- Draft final articles or social posts.
- Generate or render video without confirmation.
- Call any paid API (AI video, network TTS) by default.
- Publish videos to external platforms.
Render Boundary
This skill plans and produces a video_plan / video_package. Deterministic
rendering is performed by the bundled cmm-remotion-video engine after
explicit user confirmation. AI-video generation (optional, configured API) and
live publishing are opt-in. All planning, scripting, storyboard, captions,
post-processing, and quality methods are internalized in
references/video-method.md — no external skill is required.
When to route here vs straight to cmm-remotion-video
These two skills are sibling top-level skills with split responsibilities;
neither is nested in the other:
cmm-video-production = decide & spec. Use it when the format/engine is
not a foregone conclusion: choosing between talking-head / cards-and-captions /
AI-video, picking the render engine vs an AI-video API vs raw ffmpeg, or when
you need a reviewed video_package before any rendering. Its job is to own the
format/engine decision and emit the video_package spec.
cmm-remotion-video = render. For a straightforward vertical
card/typography/explainer social video on the Remotion engine, the agent may
call cmm-remotion-video directly — it is designed to run standalone and
derives its own script/storyboard when no upstream spec exists.
So: don't force the extra hop through this layer for an obvious Remotion job.
Route here when there is a real decision to make. When this layer does run, it
hands cmm-remotion-video a video_package to consume (so the engine does
not re-derive the script) — see that skill's "Parse the input" step.
Input
Preferred input is a content_package:
content_package:
plan_id: ""
platform: ""
format: ""
title: ""
body_markdown: ""
summary: ""
variants: []
sources_used: []
visual_needs: []
video_needs: []
publish_notes: ""
fact_check_status: pending
status: draft
If video_needs is empty or false, ask whether video is required only when the
platform or format strongly implies video. Otherwise mark the video path skipped.
Read references/video-package-contract.md for exact fields. Read
references/video-method.md for script, storyboard, caption, backend, TTS, and
quality rules. Read references/douyin-text-card-video-template.md when
creating local vertical text-card explainer videos.
Before building a video_plan, resolve the upstream
content_plan.style_selection: load the visual template from
cmm-content-factory/references/styles/visual/<id>.yaml and apply its
palette, fonts, cover ratio, and generation_avoid list as mandatory
constraints for thumbnails, on-screen text, and generated footage. Run a
style_consistency check in the quality gate. (A dedicated video-style
template library may be added later under styles/video/.)
Workflow
- Validate the
content_package.
- Decide whether video is needed.
- If not needed, return a skipped video state.
- If needed, create a
video_plan:
- platform
- format
- target duration
- script direction
- storyboard direction
- caption plan
- asset needs
- render/generation route
- risks and confirmation gates
- Include script beats, storyboard beats, caption plan, asset specs, and quality gate.
- Run audio-first preflight before full rendering:
- estimate narration duration from script length and speech rate
- decide whether captions are summary captions or true sentence-level subtitles
- generate or simulate voiceover first
- measure the real voiceover duration with
ffprobe or the backend duration API
- allocate the video timeline from the measured voiceover duration
- render key preview frames only
- inspect text overflow, graphic overlap, and mobile readability
- Ask for confirmation before paid rendering, API generation, or long media
jobs. If the user explicitly requested local video generation in the current
turn, local preview/render work can proceed after recording the preflight.
- Route to an approved backend after confirmation or same-turn local render intent.
- Produce
video_package.
- Stop before publishing.
Routing
| Need | CMM output | Execution after approval |
|---|---|
| 2-3 video outline options, title and cover suggestions, structure discussion | video_outline | built-in (video-method.md · 视频大纲方法) |
| Full vertical short-video package with script, storyboard, captions, cover, render plan | short_video | bundled cmm-remotion-video render engine |
| Local vertical text-card explainer for Douyin or Reels-style platforms | douyin_text_card_video | CMM local renderer + ffmpeg |
| Text-to-video or image-to-video generation plan | ai_generated_clip | optional configured AI-video API |
| Convert, compress, trim, merge, subtitle, extract audio, or edit media files | edited_clip | built-in ffmpeg post-processing (video-method.md) |
| Voiceover generation for narration | voiceover_asset | macOS say, Edge TTS, SiliconFlow TTS, Volcengine OpenSpeech TTS, or approved third-party TTS API |
| Pre-publish title, cover, hook, CTR, and retention check | quality_check | built-in 封标承接质检 (video-method.md) |
Routing rules:
- Use CMM outline first before expensive production when the structure is
unclear.
- Use the bundled
cmm-remotion-video render engine for deterministic vertical social video packages.
- Use the optional configured AI-video API only when the user explicitly wants AI
video generation and the required API key/cost is acceptable.
- Use local TTS such as macOS
say for zero-cost internal drafts when quality
is enough.
- Use Edge TTS as the default low-cost formal preview route when network access
is approved. For Chinese narration, default to
zh-CN-XiaoxiaoNeural
(小小) unless the user selects another voice.
- Use Volcengine OpenSpeech TTS only when network/API use is approved. Store
only
appid and credential references in artifacts. Access token and secret
key values must come from environment variables and must not be written to
skills, YAML, logs, or reports.
- Use SiliconFlow TTS only when network/API use is approved. Store only
base_url, model, voice_id, and api_key_ref in artifacts. The API key
value must come from an environment variable and must not be written to
skills, YAML, logs, or reports.
- Use a third-party TTS provider only when the required base url, API key,
voice id, and cost/rate limits are clear. Do not echo or write API keys into
output artifacts.
- Use built-in
ffmpeg post-processing only for media processing, not creative planning.
- Run the built-in 封标承接质检 before publishing or after script/cover draft exists.
video_plan
Before rendering or generation, output:
video_plan:
content_package_id: ""
platform: ""
format: short_video
target_duration_seconds: 90
script_direction: ""
storyboard_direction: []
script_beats:
- beat: ""
narration: ""
visual: ""
caption_plan: []
voiceover_plan:
text_ref: ""
provider: ""
provider_type: ""
voice_id: ""
voice_name: ""
voice_language: ""
voice_style: ""
model: ""
base_id_or_url: ""
voices_endpoint: ""
speech_endpoint: ""
api_key_ref: ""
voice_catalog_path: ""
response_audio_format: ""
appid: ""
access_token_ref: ""
secret_key_ref: ""
cluster: ""
speech_rate_wpm: 0
estimated_duration_seconds: 0
generated_duration_seconds: 0
timeline_source: measured_voiceover_duration
audio_video_max_delta_seconds: 0.75
duration_status: pending
preview_gate:
required: true
frames:
- timestamp: "00:00:02"
path: ""
status: pending
checks:
text_overflow: pending
graphic_overlap: pending
mobile_readability: pending
safe_zones: pending
subtitle_strategy: summary_caption
asset_needs:
- asset_type: ""
purpose: ""
source: ""
required: true
recommended_routes:
- route: ""
reason: ""
requires_confirmation: true
confirmation_required: true
cost_or_api_notes: []
risks: []
quality_gate:
hook_strength: ""
retention_structure: ""
caption_readability: ""
asset_readiness: ""
source_integrity: ""
preview_gate: ""
voiceover_duration: ""
status: pending_confirmation
video_package
After confirmed production, output:
video_package:
content_package_id: ""
platform: ""
format: short_video
script_path: ""
storyboard_path: ""
caption_paths: []
asset_paths: []
render_path: ""
cover_path: ""
publish_copy: ""
quality_notes: []
preview_paths: []
voiceover_path: ""
voiceover_provider: ""
voiceover_voice_id: ""
voiceover_voice_name: ""
voice_catalog_path: ""
bgm_path: ""
bgm_source: ""
mixed_audio_path: ""
subtitle_paths: []
quality_gate:
hook_strength: ""
retention_structure: ""
caption_readability: ""
asset_readiness: ""
source_integrity: ""
preview_gate: ""
voiceover_duration: ""
status: draft
Quality Gate
| Gate | Requirement |
|---|
hook_strength | First 3 seconds clearly state conflict, value, or question. |
retention_structure | Beats create progression, not a flat summary. |
caption_readability | Captions fit mobile screens and match narration language. |
asset_readiness | Required images, clips, screenshots, voiceover, and cover are available or marked missing. |
source_integrity | Claims and visual facts are supported or marked for review. |
preview_gate | Key frames pass before full render, especially first, middle, and final scenes. |
voiceover_duration | Generated voiceover is measured first and drives the video timeline; final audio/video duration delta must stay within the configured threshold. |
bgm_mix | Voiceover is the master timeline. BGM is looped then trimmed when shorter, trimmed when longer, faded, lowered, mixed, and re-measured before video timing. |
Preflight Gates
Before full rendering:
- Estimate voiceover duration from narration length and speech rate.
- Generate or simulate voiceover before rendering the full video.
- Measure the actual voiceover duration.
- Prepare background music if needed:
- local asset first
- generated BGM second
- no BGM last
- if BGM is shorter than voiceover, loop then trim
- if BGM is longer than voiceover, trim
- apply fade-in/fade-out and lower volume before mixing
- Mix voiceover and BGM, then measure the mixed audio duration.
- Allocate scene durations, captions, and motion timing from the measured audio
duration. Do not use a fixed video timeline after voiceover exists.
- Render key preview frames only, usually first hook frame, middle dense frame,
and final frame.
- Check text overflow, graphic overlap, mobile readability, and platform safe zones.
- Render the full MP4 and mux mixed audio.
- Validate final audio/video duration delta. A local preview should fail if
the audio stream and final video duration differ beyond the configured
threshold, even when both streams exist.
BGM Policy
Default priority:
bgm_source_priority:
- local_asset
- generated
- none
Default local asset directories (generic placeholders; the user profile at
~/.cmm/profile/ may define actual local_assets.bgm_paths, which take
precedence):
bgm_local_asset_paths:
- <project>/assets/cmm-content-factory/bgm/default
- <project>/assets/cmm-content-factory/bgm/knowledge
- <project>/assets/cmm-content-factory/bgm/tech
- <project>/assets/cmm-content-factory/bgm/business
Format policy:
accepted_inputs: [wav, mp3, m4a, aac, mp4, mov]
preferred_input: wav
acceptable_common_input: mp3
internal_mix_format: wav
final_video_audio_codec: aac
default_volume_ratio: 0.12
fade_in_seconds: 0.5
fade_out_seconds: 1.0
If any gate fails, revise the script, timing, or layout before full render.
Confirmation Rules
- Default behavior is plan first, render/generate second.
- Do not call the render engine, AI-video API, TTS, or
ffmpeg until the user
confirms the video_plan.
- For the render engine, prefer a first-frame or preview check before full
rendering when possible.
- For the optional AI-video API, require its API key reference and explicit user
approval before any API call.
Stop Conditions
Stop and ask before:
- Paid video generation.
- Full video rendering.
- Uploading or publishing video.
- Replacing existing media files.
- Running long media processing commands.