| name | clip-export |
| description | Video project push tool. Programmatically creates editing projects via Python scripts, with one-click push to JianyingPro or CapCut.
Direct mode creates project files directly in the local JianyingPro/CapCut draft directory — open the app and start editing.
Built on pyJianYingDraft (PyPI).
Trigger words include: JianyingPro, CapCut, push, push to JianyingPro, capcut, export to JianyingPro.
|
Clip Export — Video Project Push Tool
You are a video editing AI assistant. You programmatically create video project drafts via Python scripts, supporting one-click push to JianyingPro or CapCut:
- Direct mode (
direct=True): Creates project files directly in the JianyingPro/CapCut draft directory — open the app to preview and edit
Supported Targets
| Target | Details |
|---|
| JianyingPro (Chinese edition) | app_source: "lv", app_id: 3704 |
| CapCut (International edition) | app_source: "cc", app_id: 359289 |
Prerequisites
- Python 3.8+
pip3 install pyJianYingDraft (v0.2.6 installed)
- JianyingPro or CapCut must be installed locally
Output Mode
Direct Mode (Recommended for JianyingPro/CapCut)
CRITICAL — Distinguish between JianyingPro Chinese edition and CapCut International edition:
| User says | App version | Draft directory |
|---|
| "Push to JianyingPro" | JianyingPro (Chinese) | ~/Movies/JianyingPro/User Data/Projects/com.lveditor.draft/ |
| "CapCut" / "capcut" | CapCut (International) | ~/Movies/CapCut/User Data/Projects/com.lveditor.draft/ |
Rules:
- User says "Push to JianyingPro" → Use JianyingPro Chinese edition path (
JianyingPro)
- User says "CapCut" / "capcut" → Use international edition path (
CapCut)
- If not specified → must ask the user: Push to JianyingPro (Chinese) or CapCut (International)?
When the user wants to open in their local JianyingPro/CapCut, use direct=True. The draft is created directly in the app's draft directory — no manual import needed.
project = JyProject("My Video", direct=True, overwrite=True)
project.save()
- Auto-detects JianyingPro/CapCut draft directory (macOS / Windows)
- Auto-adapts format and platform fields for JianyingPro or CapCut
Core API
All operations are performed through the JyProject class. Script path: .claude/skills/clip-export/scripts/jy_wrapper.py
Create Project
import sys, os
sys.path.insert(0, os.path.join(os.getcwd(), ".claude/skills/clip-export/scripts"))
from jy_wrapper import JyProject
project = JyProject("My Video", direct=True, overwrite=True)
project = JyProject("Portrait Video", width=1080, height=1920, direct=True, overwrite=True)
project = JyProject("Distribution Video", overwrite=True)
Add Video
project.add_video("/absolute/path/video.mp4", start_time=0, duration="5s")
project.add_video("/path/video.mp4", start_time="5s", duration="5s", source_start="10s")
from jy_wrapper import ClipSettings
pip_seg = project.add_video(
"/path/video.mp4",
start_time="1s", duration="4s",
track_name="PiP_Layer",
clip_settings=ClipSettings(scale_x=0.3, scale_y=0.3),
)
Add Audio
project.add_audio("/path/bgm.mp3", start_time=0, volume=0.6, track_name="BGM")
project.add_audio("/path/voice.wav", start_time="2s", duration="10s", track_name="Narration")
Add Text
project.add_text(
"Big Title",
start_time="1s", duration="3s",
font_size=15.0,
color_rgb=(1.0, 0.8, 0.0),
transform_y=0.4,
bold=True,
)
project.add_subtitle("This is a subtitle", start_time="0s", duration="3s")
project.import_srt("/path/to/subtitles.srt", track_name="Subtitle Track")
Filters
project.add_filter("VHS_III", start_time=0, duration="10s")
project.add_filter("Retro Film", start_time=0, duration="10s", intensity=80.0)
Scene Effects
project.add_effect("CCD Flash", start_time="2s", duration="3s")
project.add_effect("Shake", start_time="5s", duration="2s")
Keyframe Animation
from jy_wrapper import KeyframeProperty
seg = project.add_video("/path/video.mp4", start_time=0, duration="4s")
JyProject.add_keyframe(seg, "uniform_scale", "0s", 1.0)
JyProject.add_keyframe(seg, "uniform_scale", "4s", 1.5)
JyProject.add_keyframe(seg, "position_x", "0s", -0.5)
JyProject.add_keyframe(seg, "position_x", "4s", 0.5)
JyProject.add_keyframe(seg, "rotation", "0s", 0.0)
JyProject.add_keyframe(seg, "rotation", "4s", 360.0)
JyProject.add_keyframe(seg, "alpha", "0s", 0.0)
JyProject.add_keyframe(seg, "alpha", "1s", 1.0)
Available properties: position_x, position_y, rotation, scale_x, scale_y, uniform_scale, alpha, saturation, contrast, brightness, volume
Save & Export
project.save()
Direct mode outputs to the draft directory — refresh the app to open it.
Time Formats
All time parameters support multiple formats:
| Format | Example | Description |
|---|
| Seconds (float) | 2.5 | 2.5 seconds |
| Microseconds (int) | 2500000 | 2.5 seconds |
| String with unit | "3s", "500ms", "1m30s" | Auto-parsed |
| Colon format | "01:30", "00:01:30" | min:sec or hr:min:sec |
CLI Tools
Asset Search
python3 .claude/skills/clip-export/scripts/asset_search.py "retro"
python3 .claude/skills/clip-export/scripts/asset_search.py "fade" -c transitions
python3 .claude/skills/clip-export/scripts/asset_search.py --list
Asset Library
| Category | Count | Data File |
|---|
| Filters | 1052 | data/filters.csv |
| Transitions | 453 | data/transitions.csv |
| Scene Effects | 1097 | data/effects.csv |
| Text Intro Animations | 155 | data/text_animations.csv |
| Text Outro Animations | 124 | data/text_animations.csv |
| Keyframe Properties | 11 | data/keyframe_properties.csv |
Important Rules
- File paths must use absolute paths
- Scripts must call
project.save() at the end
- Resolution must match: Landscape 1920x1080 (default), portrait requires explicit
width=1080, height=1920
- Do not guess asset names: Use
asset_search.py to search and confirm first
- Keyframe times are offsets relative to the segment start, not absolute timeline times
- Always add
overwrite=True in direct mode: CapCut encrypts the JSON after opening a draft — regenerating requires overwrite
- User wants to open in JianyingPro/CapCut → use direct mode (
direct=True), other software → package mode. Distinguish versions: says "push to JianyingPro" → Chinese edition; says "CapCut" → International edition
CapCut Test Verification Record
The following use cases have been tested and verified on CapCut 8.4 (macOS):
| Test | Content | Result |
|---|
| Minimal text | add_text() text only, no media | ✅ Opens normally |
| Single video | add_video() one 15s mp4 | ✅ Displays normally, no missing media |
| Complex mashup | 7 video/image clips + BGM + title + subtitles, 33s | ✅ Opens normally, all assets intact |
Key fixes (compared to earlier versions):
_copy_media_into_draft() copies all external assets into the Resources/ directory, resolving "missing media" caused by CapCut's sandbox
_patch_for_capcut78() auto-detects CapCut path and injects correct platform.app_source="cc" + app_id=359289
_create_capcut_scaffold() creates all auxiliary files required by CapCut (draft_agency_config / draft_biz_config / timeline_layout etc.)
Pitfall Notes
1. Duration cannot exceed actual asset length
add_video()'s source_start + duration cannot exceed the source file's duration, otherwise it throws ValueError: The extracted material time range exceeds the material duration.
p.add_video("001.mp4", duration="3s")
p.add_video("001.mp4", duration="1.5s")
Best practice: Use ffprobe to confirm asset duration first; leave a tiny margin for duration (e.g., int(dur * 1_000_000) microsecond precision), or omit duration to let the wrapper auto-detect.
2. ffprobe Duration Precision Pitfall
ffprobe's reported duration (e.g., 35.875011s) and pyJianYingDraft's internally calculated duration (35875000μs) may differ by microseconds. When source_start + duration exactly equals the ffprobe duration, rounding can cause overflow.
p.add_audio("long.mp4", duration=35.875011)
p.add_audio("long.mp4", duration="35.8s")
3. Images Can Be Used as Video
PNG/JPG files can be added via add_video() with arbitrary duration (not limited by source file length). Great for product close-ups and static frame transitions.
p.add_video("product.png", start_time="5s", duration="4s")
4. Video Files as Audio Source
When using a video file for BGM/sound effects, the wrapper automatically calls ffmpeg to extract audio to .m4a. In direct mode, extracted audio goes to the draft's audio/ subdirectory, which CapCut recognizes directly.
p.add_audio("video_with_music.mp4", volume=0.4, track_name="BGM")
5. CapCut 7.8 Draft Encryption
After CapCut opens a draft, it encrypts draft_info.json, causing:
- Manual editing of the draft JSON becomes impossible
- Regenerating a same-named draft requires
overwrite=True
During iterative debugging: Use a new draft name each time or overwrite=True to avoid operating on encrypted JSON.
6. Reusing the Same Asset
When the same file appears multiple times on the timeline, just call add_video() multiple times with different source_start values — the wrapper automatically reuses the material:
p.add_video("example.mp4", start_time="0s", duration="6s", source_start="0s")
p.add_video("example.mp4", start_time="11.5s", duration="7s", source_start="20s")
7. Best Pattern for Mashup Projects
Recommended template for product mashups / ad creative editing:
p = JyProject("Project Name", width=1080, height=1920, direct=True, overwrite=True)
p.add_video(...)
p.add_video(...)
p.add_video(...)
p.add_video(...)
p.add_filter("VHS_III", start_time=0, duration="total_duration")
p.add_effect("CCD Flash", start_time="transition_time", duration="1.5s")
p.add_text("Title", ...)
p.add_subtitle("Subtitle 1", ...)
p.add_audio("bgm.mp3", volume=0.4, track_name="BGM")
p.save()
Typical Workflow
- User provides asset file paths (video/audio/images)
- Confirm resolution (landscape/portrait)
- Confirm target app:
- User says "push to JianyingPro" → Direct mode + JianyingPro Chinese edition path (
JianyingPro)
- User says "CapCut" / "capcut" → Direct mode + International edition path (
CapCut)
- Not specified → must ask the user: Push to JianyingPro (Chinese) or CapCut (International)?
- Write Python script to create the draft
- Run the script
- User reviews in the corresponding app
- Iterate based on feedback
Import Notes
JianyingPro / CapCut (Direct Mode)
Direct mode auto-detects paths. Target is determined by the app name the user mentions:
- "Push to JianyingPro" → JianyingPro Chinese edition path (
JianyingPro)
- "CapCut" → International edition path (
CapCut)
- Not specified → must ask the user: Push to JianyingPro (Chinese) or CapCut (International)?
macOS Draft Directories:
- JianyingPro:
~/Movies/JianyingPro/User Data/Projects/com.lveditor.draft/
- CapCut:
~/Movies/CapCut/User Data/Projects/com.lveditor.draft/
Windows Draft Directories:
- JianyingPro:
%LOCALAPPDATA%/JianyingPro/User Data/Projects/com.lveditor.draft/
- CapCut:
%LOCALAPPDATA%/CapCut/User Data/Projects/com.lveditor.draft/
Full Example
See references/full_feature_showcase.py
Limitations
- Cannot modify existing drafts (JianyingPro/CapCut encrypts draft_info.json after opening)
- Cannot access GPU effects (smart cutout, beauty filters, etc.)
- Direct mode requires locally installed JianyingPro or CapCut (macOS / Windows)
- CapCut encrypts after opening a draft — regeneration requires
overwrite=True