Automates music- and curve-driven video edits: librosa beat-sync, MoviePy 2.x time_transform ramps, FFmpeg zoompan easing, camera shake, and word-highlight .ass. Use when beats, easing math, or time-remap drive the cut. Not for plain trim/concat (ffmpeg-video-editing), format conversion (ffmpeg-format-conversion), or audio loudness (ffmpeg-audio-processing).
Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Une commande directe contourne le prompt de vérification. Examinez la source avant de l'exécuter.
Automates music- and curve-driven video edits: librosa beat-sync, MoviePy 2.x time_transform ramps, FFmpeg zoompan easing, camera shake, and word-highlight .ass. Use when beats, easing math, or time-remap drive the cut. Not for plain trim/concat (ffmpeg-video-editing), format conversion (ffmpeg-format-conversion), or audio loudness (ffmpeg-audio-processing).
category
media-automation
risk
safe
source
openrouter-deepsearch
date_added
2026-06-20T00:00:00.000Z
last_updated
2026-07-01T00:00:00.000Z
trigger
User asks to cut or transition video on music beats or onsets, build a speed ramp (fast -> slow-mo -> fast), animate smooth zoom/pan with easing curves, add bass-impact camera shake, or generate karaoke-style word-highlight subtitles.
action
Run the matching bundled script (beat_sync.py, speed_ramp.py, subtitles_styled.py) or compose the documented MoviePy 2.x / FFmpeg recipe; apply the easing and time-remap formulas; enforce even output dimensions and close every clip handle.
exception
Outputting odd-dimension video; leaving MoviePy clip handles open on Windows; applying atempo outside 0.5-2.0 without chaining; calling time_transform without restoring the clip duration.
not-triggered
Format conversion, simple trims or concatenation, static image editing or graphic design, generative AI video creation, CapCut or other NLE project-file manipulation.
Multimedia Production Mastery
Automation recipes, mathematical formulations, and Python/FFmpeg templates for edits that are driven by a signal or a curve: audio beats, easing functions, and time-remap profiles. The unit of work here is a computed timeline, not a manual cut.
When to Use
Use this skill when one or more of the following are true:
Beat synchronization — cutting or transitioning clips to align with the tempo, beats, or onsets of an audio track (librosa analysis feeding MoviePy/FFmpeg cuts).
Speed ramping — smooth, non-linear acceleration/deceleration profiles (fast → slow-mo → fast) via time remapping.
Zoom & pan curves — Ken Burns motion using sinusoidal or exponential ease-in/ease-out instead of robotic linear interpolation.
Camera shake — procedural handheld or bass-impact shake generated from noise or onset strength.
Styled dynamic subtitles — .ass files with word-by-word highlight colors, custom fonts, borders, and margins.
Load references/effects-landscape.md when the user asks about available AI-enhanced or classical video effects, their parameters, tooling, or underlying math — it is a catalog you can search for effect names and implementation details.
where t is current time, d the ease duration. To keep pixel (x_f, y_f) centered on a W x H frame while zooming by z(t):
x(t) = x_f - W / (2 * z(t))
y(t) = y_f - H / (2 * z(t))
Time remapping (speed ramps)
Define S(t) = source time at output time t; the derivative S'(t) is the instantaneous speed multiplier. Build S(t) by integrating a speed profile.
MoviePy 2.x:clip.time_transform(time_func) — the 1.x fl_time is gone. HARD RULE:time_transform() leaves the clip's duration undefined. Call .with_duration(target) immediately after, or output is truncated.
FFmpeg: dynamic speed requires splitting into segments and applying setpts (video) + atempo (audio) per segment. HARD RULE:atempo only accepts [0.5, 2.0]; chain filters for anything outside (e.g. atempo=2.0,atempo=2.0 for 4x, atempo=2.0,atempo=1.5 for 3x).
ASS color formats
Two different hex conventions inside one file:
Context
Format
Example
Style definitions ([V4+ Styles])
&HAABBGGRR — 8 digits, no trailing &
&H0000FFFF = opaque yellow
Inline override tags
\c&HBBGGRR& — 6 digits, trailing &, no alpha
{\c&H00FFFF&} = yellow from here on
HARD RULE: Alpha is inverted relative to RGBA: 00 = fully opaque, FF = fully transparent. Invisible text usually means FF (transparent) where 00 (opaque) was intended.
Step 4 — FFmpeg recipes
Recipe 1: Jitter-free FFmpeg zoompan (Ken Burns)
zoompan evaluates positions in integer pixels, causing visible jitter at low zoom speeds. Pre-upscale to 4K first so the truncation error becomes sub-pixel:
Swap the source path back to the 4K original for the final render only.
Step 5 — Onset fallback for difficult tracks
Standard beat tracking misses beats in sparse or heavily syncopated material. Fall back to onsets in custom code:
onset_frames = librosa.onset.onset_detect(y=y, sr=sr, backtrack=True)
times = librosa.frames_to_time(onset_frames, sr=sr)
(beat_sync.py --onset does this automatically.)
Pitfalls
MoviePy duration reset — time_transform() leaves the clip's duration undefined. Call .with_duration(target) immediately after, or output is truncated.
ASS inverted alpha — invisible text usually means FF (transparent) where 00 (opaque) was intended. Alpha is inverted relative to RGBA.
atempo range — multipliers outside [0.5, 2.0] silently fail unless chained (atempo=2.0,atempo=1.5 for 3x, atempo=2.0,atempo=2.0 for 4x).
librosa tempo type — beat_track() returns a NumPy array for tempo in librosa 0.11+; cast with float() before formatting.
Beat tracking on ambient/vocal tracks — standard beat tracking misses beats in sparse or heavily syncopated material. Use --onset flag or librosa.onset.onset_detect with backtrack=True.
Windows file locks — unclosed VideoFileClip/AudioFileClip handles keep files locked and crash subsequent runs. HARD RULE: Always .close() every clip before the script exits, including in error paths.
Odd output dimensions — yuv420p and most encoders fail on odd width/height. Always force even dimensions after any crop or scale operation.
MoviePy 1.x vs 2.x API — only use 2.x methods: time_transform / with_duration / subclipped / with_audio. The 1.x fl_time / set_duration / subclip methods do not exist in 2.x and will raise AttributeError.
zoompan integer jitter — zoompan evaluates positions in integer pixels. Without pre-upscaling to 4K, low zoom speeds produce visible jitter. Always pre-scale to a high resolution before zoompan.
Verification
Run through this checklist before considering the task complete:
Environment check:librosa, moviepy (2.x), numpy, and scipy import successfully:
Output must show moviepy version starting with 2..
MoviePy 2.x API only: Only these methods are used: time_transform / with_duration / subclipped / with_audio. No 1.x fl_time / set_duration / subclip appears anywhere in the code.
Even dimensions: Every scale/crop expression forces even output dimensions. Verify with:
ASS color formats: Inline ASS tags use 6-digit hex with trailing & (\c&HBBGGRR&); style lines use 8-digit &HAABBGGRR; alpha semantics are inverted (00 = opaque, FF = transparent).
Clip handles closed: All VideoFileClip/AudioFileClip handles are .close()d before the script exits. On Windows, verify no file locks remain by attempting to delete or rename the input file after the script finishes.
atempo within range: Any atempo filter values are within [0.5, 2.0] or properly chained. Verify by inspecting the FFmpeg filtergraph string.