Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
242 commits
Select commit Hold shift + click to select a range
949c02a
Add OpenSSF Scorecard and MCP registry manifests
cursoragent Oct 29, 2026
2c1dc56
Add join.py --copy (stream-copy join of matching clips) and cut.py --…
claude Oct 31, 2026
bd139c1
Add output_identity, check.py --expect-identity and check.py --compare
claude Oct 31, 2026
c6ae342
Add export.py --max-mb: a two-pass x264 encode that fits a size, meas…
claude Oct 31, 2026
ae26d28
Add export.py --preset copy --repair: remux a damaged file and count …
claude Oct 31, 2026
3284ceb
export.py --repair: judge the remux on timestamp warnings
claude Oct 31, 2026
762f1bc
Label the join copy, identity, compare, max-mb and repair additions 2.24
claude Oct 31, 2026
00e44c2
Merge remote-tracking branch 'origin/main' into claude/ffmpeg-skill-r…
claude Oct 31, 2026
6884481
Merge remote-tracking branch 'origin/main' into claude/ffmpeg-skill-r…
claude Oct 31, 2026
7c2560e
Address review: cover art, timeline times, copy-join guards, --remove…
claude Oct 31, 2026
921799e
Add a cut.py --remove demo; damage only video payload in the repair test
claude Oct 31, 2026
8f6d53c
join.py --copy: refuse a different stream layout and a start offset; …
claude Oct 31, 2026
41da3c6
check.py --expect-identity: grade an existing file under --dry-run too
claude Oct 31, 2026
387f8ed
join.py --copy checks starts without stream lengths; --expect-identit…
claude Oct 31, 2026
c89fac0
check.py: read the identity after --compare; note a mid-check change …
claude Oct 31, 2026
aefb438
Route the 2.24 features from SKILL.md; make the repair test open on e…
claude Oct 31, 2026
b483306
Repair test: fall back to MPEG-PS where ffprobe cannot read MPEG-TS
claude Oct 31, 2026
300f12e
Repair test: give the MPEG-PS fallback damage every ffmpeg reports
claude Oct 31, 2026
c6daf4d
Docs: multicam energy switch is a loudness proxy; why 啊 is not a defa…
claude Oct 31, 2026
34dfbc7
Drop color.py --tonemap bt2390 (never worked); bring README in line w…
claude Oct 31, 2026
ce1820a
Merge remote-tracking branch 'origin/main' into claude/ffmpeg-skill-r…
claude Oct 31, 2026
845f7e0
check.py --compare: pair only frames both files have; RGB and rotated…
claude Oct 31, 2026
d71ca47
join.py --copy: measure stream spans from packets; VP9; --codec; drop…
claude Oct 31, 2026
c0d546a
Merge remote-tracking branch 'origin/main' into claude/ffmpeg-skill-r…
claude Oct 31, 2026
de4d2f0
export.py --max-mb with gif / huge limits; --repair damage counting; …
claude Oct 31, 2026
a8c13a1
join.py --copy: refuse when a stream span cannot be measured; refuse …
claude Oct 31, 2026
b8a3428
join.py --copy: read packet spans as JSON with a dts fallback; rotati…
claude Oct 31, 2026
598947d
join.py --copy: read a long clip's packet span at its head and tail o…
claude Oct 31, 2026
af082e3
join.py --copy: seek a long clip's tail from its own start time
claude Oct 31, 2026
51d34e9
Merge remote-tracking branch 'origin/main' into claude/ffmpeg-skill-r…
claude Oct 31, 2026
cba64d4
Restore CHANGELOG.md to main after the 2.24.1 release bump
claude Oct 31, 2026
0bfedfb
3.0.0: require FFmpeg 6.1+ and Python 3.10+; apply the cut.py default…
claude Oct 31, 2026
dca4431
3.0.0 docs: work in progress
claude Oct 31, 2026
e82d25d
3.0.0 docs: work in progress
claude Oct 31, 2026
53e5b2c
3.0.0 docs: work in progress
claude Oct 31, 2026
463aa85
v3.0: tests for the new cut defaults, sampled guard on seeked TS wind…
claude Oct 31, 2026
bd27dc9
design-decisions: point stale test names at their 3.0 successors
claude Oct 31, 2026
1a17c9e
probe: report the source's start timecode (video stream, tmcd, then f…
claude Oct 31, 2026
ac19577
test_asr: pick the engine call out of the fake's calls (the 6.1 floor…
claude Oct 31, 2026
ac53771
Review: timecode minutes/seconds 00-59; ffprobe floor in doctor; git …
claude Oct 31, 2026
e8f31a0
Review: doctor marks every tool unusable below the floor; an old ffpr…
claude Oct 31, 2026
b7b1f41
Merge main (v3.0.0)
claude Oct 31, 2026
a3dae9a
ci: spread the suite over three machines per platform (run_parallel.p…
claude Oct 31, 2026
a441122
run_parallel --part: bound N by the work items; test that every shard…
claude Oct 31, 2026
2938c61
Merge main (#388)
claude Oct 31, 2026
01657c7
Failures say why: ffmpeg error reasons and hints, no orphan ffmpeg af…
claude Oct 31, 2026
ae1d114
Review: one encoder_missing entry, asr_engine_missing under error.rea…
claude Oct 31, 2026
4b4844e
Merge main (v3.1.0)
claude Oct 31, 2026
7c96aa4
Merge main (#390)
claude Oct 31, 2026
ef3372b
docs: a talking-head reframe demo from AI-generated footage, on the l…
claude Oct 31, 2026
1821226
silence --filler --transcribe: prime Whisper with the filler list; fi…
claude Oct 31, 2026
756c970
Pages: the two AI-footage demos as MP4 with sound, built with grid/gr…
claude Oct 31, 2026
f4eeca4
demos: the gallery intro names the two AI-footage demos
claude Oct 31, 2026
682b8be
docs/demos.md: keep render_project's --export-timeline line (a partia…
claude Oct 31, 2026
8039999
Pages: the reframe label and aria-label give the source's real size; …
claude Oct 31, 2026
d25d38f
Merge origin/main
claude Oct 31, 2026
9c54126
docs: SKILL.md restructured, no behavior change
claude Oct 31, 2026
865771f
docs: restore three SKILL.md rules the restructure cut; fix moved-tex…
claude Oct 31, 2026
6086d46
docs: step 5 keeps --expect-identity; highlight row and --from wording
claude Oct 31, 2026
d6c9050
Merge origin/main
claude Oct 31, 2026
16e0160
Fix #393-#397: lean builds, tofu emoji, SRT as --text, dropped audio …
claude Nov 5, 2026
0833d83
Merge remote branch history (same tree as main)
claude Nov 5, 2026
51534e1
#395: an auto caption leaves undrawable emoji out with a warning; Cod…
claude Nov 5, 2026
9ff4fc6
docs: qualify the emoji none mode and the one-audio-track gotcha
claude Nov 5, 2026
0d7bca4
Merge origin/main
claude Nov 5, 2026
d04a721
Escape line breaks and control characters from arguments in messages …
claude Nov 5, 2026
fe93dec
Merge remote branch history
claude Nov 5, 2026
d2347ef
Report audio tracks every tool leaves out; grid/scenes sheets without…
claude Nov 5, 2026
94c8b1d
CodeRabbit on #405: escape --opt=value and notes; no track report acr…
claude Nov 5, 2026
e233757
Merge origin/main
claude Nov 5, 2026
90d8a01
docs: README and the Pages docs layout carry the v3 brand
claude Nov 5, 2026
6e602c7
CHANGELOG: drop the 3.1.3 entries the merge left under Unreleased
claude Nov 5, 2026
b9de0f7
Side files and paths get the output guards (#408)
claude Nov 5, 2026
b76d9cb
Merge origin/main
claude Nov 5, 2026
6fb532f
HDR10 static metadata reaches libx265 and SVT-AV1, and its loss is me…
claude Nov 5, 2026
07a8911
Merge HDR10 work (#401)
claude Nov 5, 2026
e8f6ad7
CodeRabbit on #412: zero luminance, per-part frame read, V:0, SVT pre…
claude Nov 5, 2026
e14608c
CodeRabbit on #412: a still is not a picture source; read the frame w…
claude Nov 5, 2026
3a9dd96
Fix the audit G colour paths (#410)
claude Nov 5, 2026
65c8b04
Square pixels everywhere that scales; wrap graphics titles and overla…
claude Nov 5, 2026
4f76844
Merge origin/main
claude Nov 5, 2026
b88e62c
CHANGELOG: match main after the 3.1.4 release
claude Nov 5, 2026
5fad4ef
fix(timing): keep picture and sound on one clock in silence, sync, mu…
claude Nov 5, 2026
b494f46
render pack guard only where the folder exists; pin the pack table re…
claude Nov 5, 2026
b92f176
Merge origin/main
claude Nov 5, 2026
dc20e49
Merge #408 work
claude Nov 5, 2026
fb04bb0
Merge origin/main
claude Nov 5, 2026
317d644
CHANGELOG for #410
claude Nov 5, 2026
71705c4
test: check the MP4 header instead of calling file(1), which the Debi…
claude Nov 5, 2026
c2f6cf7
CodeRabbit on #413: guard every input and output the side files can c…
claude Nov 5, 2026
af16a43
Refuse hard-linked side files and allow a report inside a new --out (…
claude Nov 5, 2026
4af0165
Protect caption's --brand file from its side-file writes (#408)
claude Nov 5, 2026
20effb9
Pass -pattern_type only to image2 stills; never reuse a leftover temp…
claude Nov 5, 2026
fba851b
Merge branch 'wip-g' into wip-ghf
claude Nov 5, 2026
cb8ffc6
Merge branch 'worktree-agent-a913154fab2b1902e' into wip-ghf
claude Nov 5, 2026
89edfeb
Merge remote-tracking branch 'origin/main' into claude/ffmpeg-skill-r…
claude Nov 5, 2026
3d8f149
Merge origin/main (v3.1.5) into the branch
claude Nov 5, 2026
024115d
Merge #411 (square pixels, text wrapping, geometry audit) into wip-ghf
claude Nov 5, 2026
13cfd74
Merge branch 'wip-ghf' into claude/ffmpeg-skill-repo-setup-cn8xm4
claude Nov 5, 2026
9e267bb
freeze, reverse: clone frames before setpts so the hold survives FFmp…
claude Nov 5, 2026
396d83f
Address CodeRabbit's review of #416
claude Nov 5, 2026
80586c3
broll: B's sound lasts the whole cutaway when --from falls between fr…
claude Nov 5, 2026
1ee422c
loop: refuse an output that is its input before the concat list
claude Nov 5, 2026
4c2e0ab
color --lut: keep a BT.601 source's matrix on the ProRes path
claude Nov 5, 2026
f12b1e4
Subtitles, transcription, timeline export, Windows fonts and contract…
claude Nov 5, 2026
000229e
Dry-run honesty, process handling, faststart and batch/render orchest…
claude Nov 5, 2026
0f3dd9a
loop.py --crossfade: seamless repeats, and every loop measures its se…
claude Nov 5, 2026
a2bea69
export.py: DNxHR editing-master presets, and masters read their codec…
claude Nov 5, 2026
1ff22d6
loudness.py --versions: one master, one measured file per loudness ta…
claude Nov 5, 2026
2b405f6
export.py: alpha masters that read their alpha back (#417)
claude Nov 5, 2026
b7b2c58
export.py --preset key-fill: a switcher's fill and key from one alpha…
claude Nov 5, 2026
10532b8
look.py --guides: broadcast safe-area outlines on the preview (#423)
claude Nov 5, 2026
1d84f6b
test: the filler keep range is the rendered one since #416 (#414)
claude Nov 5, 2026
210e129
Merge remote-tracking branch 'origin/main' into wip-i2
claude Nov 5, 2026
95815dc
docs: refresh the design-decisions contents list (#414)
claude Nov 5, 2026
cbe34a9
docs: the #414 decisions ship in 3.1.7
claude Nov 5, 2026
f9463ea
Merge remote-tracking branch 'origin/main' into claude/ffmpeg-skill-r…
claude Nov 5, 2026
e815e00
Merge origin/main (v3.1.6) into the branch; CHANGELOG from main
claude Nov 5, 2026
6061574
Merge branch 'wip-i2' into claude/ffmpeg-skill-repo-setup-cn8xm4
claude Nov 5, 2026
8f6de10
test: the fake whisper-cli fixture runs on Windows too (#414)
claude Nov 5, 2026
770b906
docs: the #415 decisions ship in 3.1.8
claude Nov 5, 2026
2f57e73
Address the #427 review: margin input, filler message, SRT grammar, m…
claude Nov 5, 2026
53e0b97
probe: skip a start timecode whose frames field the picture's rate ca…
claude Nov 5, 2026
1321b0a
probe: validate a timecode's frames field at avg_frame_rate first, as…
claude Nov 5, 2026
7ea082b
Merge remote-tracking branch 'origin/main' into wip-j2
claude Nov 5, 2026
0abe905
Merge remote-tracking branch 'origin/main' into claude/ffmpeg-skill-r…
claude Nov 5, 2026
3ad41b7
CHANGELOG from main (v3.1.7)
claude Nov 5, 2026
cfbc178
Merge branch 'wip-j2' into claude/ffmpeg-skill-repo-setup-cn8xm4
claude Nov 5, 2026
f9cbef2
Address the #428 review: stopped-child exit codes, batch delivery, co…
claude Nov 6, 2026
ab4e2a9
Address the #428 review: dry-run output check, signal exit codes, bat…
claude Nov 6, 2026
47830ac
Refuse a batch output_dir that is the input folder (#428 review)
claude Nov 6, 2026
2dd5feb
Contract: a render-project batch recipe always writes its artifact (#…
claude Nov 6, 2026
9817eff
Keep batch rows' output a string; mark a write-free recipe with writt…
claude Nov 6, 2026
bdcf960
batch: key the cache on the files a step names; fix the QC note (#428…
claude Nov 6, 2026
efa3368
Merge main (v3.1.8) into the working branch
claude Nov 6, 2026
8965367
Take main's CHANGELOG after the v3.1.8 release
claude Nov 6, 2026
96a8bf7
Merge main (v3.1.8) into the feature branch
claude Nov 6, 2026
2fc6682
test: an encoder capability name may contain a hyphen (libvpx-vp9)
claude Nov 6, 2026
fb58d2a
Merge the feature branch (#417 #418 #419 #421 #422 #423)
claude Nov 6, 2026
ea2b50f
loop.py --crossfade: restate the frame rate before xfade (FFmpeg 7.x)
claude Nov 6, 2026
f23b583
Address the #430 review: key-fill outputs, alpha checks, --versions e…
claude Nov 6, 2026
9fbb793
Address the #430 review: loudness, look, demos, loop, key-fill, alpha
claude Nov 6, 2026
aff8e3b
Fix the demo page test off Linux; address the #430 follow-up review
claude Nov 6, 2026
b8204a8
Merge remote-tracking branch 'origin/main' into claude/ffmpeg-skill-r…
claude Nov 6, 2026
da8d29b
Merge main (v3.2.0) into the working branch
claude Nov 6, 2026
4bb594a
Merge remote-tracking branch 'origin/main' into claude/ffmpeg-skill-r…
claude Nov 7, 2026
ad5cca8
Merge origin/main (v3.2.3) into claude/ffmpeg-skill-repo-setup-cn8xm4
claude Nov 7, 2026
f6ffb81
release: find a squash commit's PR by its SHA when the subject does n…
claude Nov 10, 2026
6038492
source_carry: every result says what the output lost from its source …
claude Nov 11, 2026
a6112fe
Fix caption.py --srt --position (#436) and odd-sized JPEGs through th…
claude Nov 11, 2026
61c750f
Merge the OpenSSF Scorecard workflow and MCP registry manifests (#369…
claude Nov 11, 2026
3b33b47
CHANGELOG: the mcp subcommand, the registry manifest and the Scorecar…
claude Nov 11, 2026
0450874
Review of #435: keep an odd frame's own size through the BT.709 conve…
claude Nov 11, 2026
b6dbf2c
Sweep a reported defect across the tools before fixing it: tests/swee…
claude Nov 11, 2026
9f524d9
Fix odd-sized clips in caption.py and stabilize.py (#438)
claude Nov 11, 2026
5c83110
Plugin installs in Codex and Gemini CLI find the skill: skills/ffmpeg…
claude Nov 11, 2026
9962e1a
Review of #435: bound each sweep child, refuse a failed probe, write …
claude Nov 11, 2026
06f6983
CONTRIBUTING: Smithery's publish commands no longer exist (its API an…
claude Nov 11, 2026
46dd9f0
Publish a plugin branch with only the runtime set on each release
claude Nov 11, 2026
bc430e3
sweep.py: --list needs no input; pin its probe and timeout handling; …
claude Nov 11, 2026
78971a4
Record the questions an outside reviewer kept asking, as a pre-push list
claude Nov 11, 2026
753b800
Plugin branch step: do not hold the npm publish back; tell a missing …
claude Nov 11, 2026
7f1e9e2
reviewer-findings: path guards hold in dry runs; side-file order depe…
claude Nov 11, 2026
7c0ba79
Merge main (v3.3.0) into the working branch
claude Nov 11, 2026
c955ecf
check.py --compare --expect-changed: fail on a picture change outside…
claude Nov 11, 2026
1ebf86c
change_scope: grade overlapping declarations independently; refuse a …
claude Nov 11, 2026
e955d68
Refuse nan and inf for every float flag of every tool, and for every …
claude Nov 11, 2026
c8be17d
test: --change-floor 254 is asserted by what the document reports, no…
claude Nov 11, 2026
e044d2f
Non-finite flag values: a failure document with --json, as the flags …
claude Nov 11, 2026
9f5d47f
change_scope: rectangles are in the displayed picture (non-square pix…
claude Nov 11, 2026
02f6490
change_scope: equal displayed sizes are compared whatever the stored …
claude Nov 11, 2026
8970861
change_scope: the stored-size note reads the file's own width and hei…
claude Nov 11, 2026
1ca5780
Merge remote-tracking branch 'origin/main' into claude/ffmpeg-skill-r…
claude Nov 11, 2026
896d9ad
Sync CHANGELOG with main after the 3.4.0 release
claude Nov 11, 2026
f2081fe
Marketplace entry names the plugin branch's ffmpeg-skill/ directory
claude Nov 11, 2026
8913c87
README: the plugin route's minimum Claude Code version for a git-subd…
claude Nov 11, 2026
987d94b
README: a table of the install routes that work today, and the direct…
claude Nov 11, 2026
d6d9750
Plugin tree: ship the listing icon, leave the npx installer out
claude Nov 11, 2026
434092f
README: the one-line plugin install needs 2.1.275; older versions use…
claude Nov 11, 2026
1671406
Plugin tree: a short README of its own; workflow.md says add --overwrite
claude Nov 11, 2026
d7b325d
Plugin README: transcription engines may download a model and use a l…
claude Nov 11, 2026
6d11c62
Merge remote-tracking branch 'origin/main' into claude/ffmpeg-skill-r…
claude Nov 11, 2026
8781cb5
Sync with main after the 3.4.1 release
claude Nov 11, 2026
9b6ac28
Plugin icon: picture chunks only, pixels recompressed; drop mcpName f…
claude Nov 11, 2026
0ef2378
Merge remote-tracking branch 'origin/main' into claude/ffmpeg-skill-r…
claude Nov 11, 2026
d1617dd
Sync with main after the 3.4.2 release
claude Nov 11, 2026
62bdf66
Plugin listing: displayName, documentation, support and privacy links…
claude Nov 11, 2026
f5d9299
Merge remote-tracking branch 'origin/main' into claude/ffmpeg-skill-r…
claude Nov 11, 2026
521fd46
Sync with main after the 3.4.3 release
claude Nov 11, 2026
6e2da95
release.yml: publish the MCP Registry entry after npm, by OIDC
claude Nov 11, 2026
ed5f9ea
release.yml: an npm that cannot be asked is not 'not on npm'
claude Nov 11, 2026
a3de19c
release.yml: a tagged version npm does not have fails the registry step
claude Nov 11, 2026
4e487b9
release.yml: report both publish failures; recovery text without a fl…
claude Nov 11, 2026
8caaf3f
release.yml: ask the MCP Registry for the exact name and version
claude Nov 11, 2026
649fe2e
Merge remote-tracking branch 'origin/main' into claude/ffmpeg-skill-r…
claude Nov 11, 2026
1f49479
README: the MCP Registry entry is live
claude Nov 11, 2026
3ee1125
README: the registry row says what the release workflow does when its…
claude Nov 11, 2026
381bbac
Merge remote-tracking branch 'origin/main' into claude/ffmpeg-skill-r…
claude Nov 11, 2026
ef44c0a
test: read the icon word list from the publish script and bound the P…
claude Nov 11, 2026
34824d0
test: keep the seven known icon words as a fixed minimum
claude Nov 11, 2026
f1e5f0e
Merge remote-tracking branch 'origin/main' into claude/ffmpeg-skill-r…
claude Nov 11, 2026
1ba8b6f
feat(silence): --margin-lead and --margin-tail keep different amounts…
claude Nov 12, 2026
2b65364
Merge remote-tracking branch 'origin/main' into claude/ffmpeg-skill-r…
claude Nov 12, 2026
c695bc3
feat(silence): --sentence-min-silence and --sentence-margin-tail for …
claude Nov 12, 2026
3e637ac
Merge remote-tracking branch 'origin/main' into claude/ffmpeg-skill-r…
claude Nov 12, 2026
8fe593a
docs(changelog): keep the sentence-flags entry under Unreleased after…
claude Nov 12, 2026
ea923be
fix(silence): tell the word before a pause by word midpoints, and tes…
claude Nov 12, 2026
3b83636
fix(silence): measure an open-ended silence, refuse unusable word tim…
claude Nov 12, 2026
718506b
fix(silence): a silence that runs to the end of the file ends at the …
claude Nov 12, 2026
79f4907
test(silence): the sentence test makes its own clip
claude Nov 12, 2026
47a962a
docs(silence): margins is present under --filler when a sentence flag…
claude Nov 12, 2026
31cce57
Merge remote-tracking branch 'origin/main' into claude/ffmpeg-skill-r…
claude Nov 12, 2026
200dc16
chore: sync the branch with main after #452 and the 3.6.0 release
claude Nov 12, 2026
31dfd4d
fix(security): refuse DASH/IMF manifests by content, subfile URLs and…
claude Nov 12, 2026
8998cc0
fix(security): export.py's fill temp and batch.py's delivery temp are…
claude Nov 12, 2026
8011011
fix(security): copy through the reserved descriptor, refuse the 3GPP …
claude Nov 12, 2026
a2cadfa
fix(security): guard the project file, resolve overlay fonts, fail cl…
claude Nov 12, 2026
a93e1ef
fix(security): verify the default audit log after opening it where O_…
claude Nov 12, 2026
e7d6cbe
fix(security): guard the brand's own logo and font, skip the output g…
claude Nov 12, 2026
e337c57
fix(security): refuse a hard-linked default audit log where O_NOFOLLO…
claude Nov 12, 2026
e13aa91
test: require the --stop-after preview to succeed, not only to avoid …
claude Nov 12, 2026
7505eea
Merge remote-tracking branch 'origin/main' into claude/ffmpeg-skill-r…
claude Nov 12, 2026
c5c19ad
chore: sync with main after #456
claude Nov 12, 2026
44f6cbd
fix(batch): project side files beside the project; --watch waits for …
claude Nov 12, 2026
9f061c1
fix(captions): keep text symbols, spaces at moved breaks and SRT markup
claude Nov 12, 2026
a1565fc
fix: speedramp frame durations, sync --trim-second copy, upper-case M…
claude Nov 12, 2026
b69e9c9
fix: downmix gain, HDR tone-map peak, PiP opacity colour and 10-bit o…
claude Nov 12, 2026
16c7b36
fix(mcp): truthful tool annotations; a structured value is never read…
claude Nov 12, 2026
a72cd3e
fix(silence): name the sentence-flag transcription path everywhere, a…
claude Nov 12, 2026
d0b054f
test: name the render.py paths the output guard reads in the rebase l…
claude Nov 12, 2026
0b96623
ci(security): pin every action to a commit, grant writes per job, fuz…
claude Nov 12, 2026
21fdcdf
docs: the Unreleased entries for the merged fixes; why ffmpeg's temps…
claude Nov 12, 2026
f6cd8a0
test: compare the landing page's asset hosts by hostname, not by subs…
claude Nov 12, 2026
c7aee96
docs(readme): why the Claude plugin directory listing is on hold
claude Nov 12, 2026
22efa5d
fix(overlay): label an untagged PiP beside a tagged main (FFmpeg 8.0 …
claude Nov 12, 2026
f4aa936
fix(fuzz): a negative time is a valid parse; say what the SRI and fuz…
claude Nov 12, 2026
ad77e3b
fix(caption, look): whitespace-only markup, a split cue's alignment, …
claude Nov 12, 2026
055dc4d
fix(timecode): count the start label at the delivered rate, from a la…
claude Nov 12, 2026
75c118a
fix(batch): a watch pass replaces only the files it delivered, checke…
claude Nov 12, 2026
93fa254
fix(timecode): round the start label once at the delivered rate; fit …
claude Nov 12, 2026
3660b06
test(sync): read the first frame count FFmpeg 8's ffprobe prints for …
claude Nov 12, 2026
cee3555
fix(batch): record each delivered file as it was when written, not wh…
claude Nov 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .clusterfuzzlite/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# ClusterFuzzLite build image. The base is pinned by digest (Scorecard Pinned-Dependencies) and
# already carries atheris and PyInstaller; nothing is installed from a package index here.
FROM gcr.io/oss-fuzz-base/base-builder-python@sha256:21f6fab17ace4dc76e1c56de91ee95d3d03da021df94b41056ba036f6c6f55e9
COPY . $SRC/ffmpeg-skill
WORKDIR $SRC/ffmpeg-skill
COPY .clusterfuzzlite/build.sh $SRC/
11 changes: 11 additions & 0 deletions .clusterfuzzlite/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/bash -eu
# Build every fuzz/*_fuzzer.py into a standalone fuzzer. scripts/ is added to the bundle's import
# path so `_common` resolves inside the PyInstaller build exactly as it does from the checkout.
for fuzzer in "$SRC"/ffmpeg-skill/fuzz/*_fuzzer.py; do
compile_python_fuzzer "$fuzzer" --paths "$SRC/ffmpeg-skill/scripts" --paths "$SRC/ffmpeg-skill/fuzz"
name=$(basename "$fuzzer" .py)
seeds="$SRC/ffmpeg-skill/fuzz/seeds/${name%_fuzzer}"
if [ -d "$seeds" ]; then
(cd "$seeds" && zip -q -r "$OUT/${name}_seed_corpus.zip" .)
fi
done
1 change: 1 addition & 0 deletions .clusterfuzzlite/project.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
language: python
3 changes: 2 additions & 1 deletion .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Keeps GitHub Actions pins (actions/checkout@v4, release-drafter@v6, etc.) and package.json's
# Keeps GitHub Actions pins (each `uses:` is a commit SHA with its tag in a comment; Dependabot
# updates both) and package.json's
# npm metadata current, opening a PR for each update instead of letting either go stale silently.
# There's no requirements.txt/pyproject.toml to watch here -- scripts/ is deliberately Python
# 3.10+ standard library only, no third-party runtime dependencies (see README).
Expand Down
2 changes: 1 addition & 1 deletion .github/scripts/publish_plugin_branch.sh
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ README, the changelog and the tests are in the repository: https://github.com/ka

Needs FFmpeg 6.1 or later and Python 3.10 or later. The tools themselves open no network
connection and read no API key. The one exception is transcription (`caption.py --transcribe`,
`silence.py --filler --transcribe`), which runs a speech engine you installed yourself
`silence.py --transcribe` with `--filler` or a sentence flag), which runs a speech engine you installed yourself
(whisper.cpp, faster-whisper, openai-whisper or parakeet): on its first run such an engine may
download its model, and a Hugging Face client uses a token you are logged in with.
PLUGIN_README
Expand Down
42 changes: 42 additions & 0 deletions .github/workflows/cflite.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# ClusterFuzzLite: build the fuzz/ targets and fuzz them for a few minutes on each pull request
# that touches Python, and longer once a week (Scorecard Fuzzing). Each target documents what it
# accepts as a refusal; anything else is a crash and fails the job.
# https://google.github.io/clusterfuzzlite/running-clusterfuzzlite/github-actions/
name: ClusterFuzzLite
on:
pull_request:
paths:
- "scripts/**.py"
- "fuzz/**"
- ".clusterfuzzlite/**"
- ".github/workflows/cflite.yml"
schedule:
- cron: '17 3 * * 2'
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

permissions:
contents: read

jobs:
fuzz:
runs-on: ubuntu-latest
steps:
- name: Build fuzzers
id: build
uses: google/clusterfuzzlite/actions/build_fuzzers@884713a6c30a92e5e8544c39945cd7cb630abcd1 # v1
with:
language: python
github-token: ${{ secrets.GITHUB_TOKEN }}
sanitizer: address
- name: Run fuzzers
uses: google/clusterfuzzlite/actions/run_fuzzers@884713a6c30a92e5e8544c39945cd7cb630abcd1 # v1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
fuzz-seconds: ${{ github.event_name == 'schedule' && 1800 || 300 }}
mode: ${{ github.event_name == 'pull_request' && 'code-change' || 'batch' }}
sanitizer: address
output-sarif: false
12 changes: 7 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,15 @@ jobs:
runs-on: ${{ matrix.python == '3.10' && startsWith(matrix.os, 'ubuntu') && 'ubuntu-24.04' || matrix.os }}
name: test (${{ matrix.os }}, py${{ matrix.python }}, ${{ matrix.part }}/3)
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
# Full history (not the default shallow depth-1 clone): test_contract.py's
# test_changelog_mentions_every_closed_issue_since_last_tag walks git log back to the
# latest tag to check CHANGELOG.md against "Closes #N" in commit bodies -- a shallow
# clone would make that check silently a no-op (no tag reachable to diff against).
fetch-depth: 0
- uses: actions/setup-python@v7
- uses: actions/setup-python@6d4fd22b20465ccc0f7354476588e8df7c9ca0e0 # v7.1.0
with:
python-version: ${{ matrix.python }}
- name: Install ffmpeg (Linux)
Expand Down Expand Up @@ -106,7 +107,7 @@ jobs:
# that is reported, not hidden, but the listings must still be uploaded
python scripts/_contract.py doctor --json > listings/doctor.json || echo "doctor exit $?"
cat listings/doctor.json
- uses: actions/upload-artifact@v7
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
if: always()
with:
name: ffmpeg-listings-${{ matrix.os }}-py${{ matrix.python }}-${{ matrix.part }}
Expand Down Expand Up @@ -139,8 +140,9 @@ jobs:
apt-get update -qq
DEBIAN_FRONTEND=noninteractive apt-get install -y -qq ffmpeg python3 fonts-dejavu-core git nodejs ca-certificates
git config --global --add safe.directory "$GITHUB_WORKSPACE"
- uses: actions/checkout@v7
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
fetch-depth: 0
- name: ffmpeg version, listings and doctor
run: |
Expand All @@ -152,7 +154,7 @@ jobs:
ffmpeg -hide_banner -bsfs > listings/ffmpeg_bsfs.txt
python3 scripts/_contract.py doctor --json > listings/doctor.json || echo "doctor exit $?"
cat listings/doctor.json
- uses: actions/upload-artifact@v7
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
if: always()
with:
name: ffmpeg-listings-debian-trixie-ffmpeg7-${{ matrix.part }}
Expand Down
14 changes: 10 additions & 4 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,30 @@ concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

# Read-only at the top; the one write the analysis needs is granted to its job (Scorecard
# Token-Permissions).
permissions:
contents: read
security-events: write

jobs:
analyze:
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write # upload the SARIF to code scanning
strategy:
fail-fast: false
matrix:
language: [python, javascript]
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

- uses: github/codeql-action/init@v4
- uses: github/codeql-action/init@33d7b85da1a04171e211befe2c739303b9a4c066 # v4.39.3
with:
languages: ${{ matrix.language }}

- uses: github/codeql-action/analyze@v4
- uses: github/codeql-action/analyze@33d7b85da1a04171e211befe2c739303b9a4c066 # v4.39.3
with:
category: "/language:${{ matrix.language }}"
8 changes: 5 additions & 3 deletions .github/workflows/dependabot-auto-merge.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,19 @@ on:
types: [opened, reopened, synchronize]

permissions:
contents: write
pull-requests: write
contents: read

jobs:
auto-merge:
if: github.actor == 'dependabot[bot]'
runs-on: ubuntu-latest
permissions:
contents: write # enable auto-merge
pull-requests: write # approve the PR
steps:
- name: Fetch Dependabot metadata
id: metadata
uses: dependabot/fetch-metadata@v3
uses: dependabot/fetch-metadata@25dd0e34f4fe68f24cc83900b1fe3fe149efef98 # v3.1.0
with:
github-token: ${{ secrets.GITHUB_TOKEN }}

Expand Down
17 changes: 10 additions & 7 deletions .github/workflows/pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ on:

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: pages
Expand All @@ -31,22 +29,27 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Assemble the site
run: python3 .github/scripts/build_pages.py _pages
- uses: actions/configure-pages@v6
- uses: actions/jekyll-build-pages@v1
- uses: actions/configure-pages@45bfe0192ca1faeb007ade9deae92b16b8254a0d # v6.0.0
- uses: actions/jekyll-build-pages@44a6e6beabd48582f863aeeb6cb2151cc1716697 # v1.0.13
with:
source: _pages
destination: _site
- uses: actions/upload-pages-artifact@v5
- uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0

deploy:
needs: build
runs-on: ubuntu-latest
permissions:
pages: write # publish the artifact
id-token: write # verify the deployment's origin
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- id: deployment
uses: actions/deploy-pages@v5
uses: actions/deploy-pages@368f82528645a54fb793d4d04e342629a3f51346 # v5.0.1
4 changes: 2 additions & 2 deletions .github/workflows/release-drafter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
pull-requests: write
runs-on: ubuntu-latest
steps:
- uses: release-drafter/release-drafter@v7
- uses: release-drafter/release-drafter@978bb0b30c5ee8cdd332ced253758157150d43f0 # v7.10.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Expand All @@ -48,6 +48,6 @@ jobs:
# The dedicated autolabeler sub-action (not the main release-drafter action used above) --
# applies just the `autolabeler` rules from release-drafter.yml to this PR, with nothing
# else running (no draft-release read/write against a PR ref that isn't main).
- uses: release-drafter/release-drafter/autolabeler@v7
- uses: release-drafter/release-drafter/autolabeler@978bb0b30c5ee8cdd332ced253758157150d43f0 # v7.10.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
14 changes: 8 additions & 6 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,17 @@ concurrency:
cancel-in-progress: false

permissions:
contents: write
pull-requests: read # resolve_version.py reads merged PRs' labels through gh api
id-token: write # required for `npm publish --provenance`
contents: read

jobs:
release:
runs-on: ubuntu-latest
permissions:
contents: write # bump commit, tag, GitHub release, plugin branch
pull-requests: read # resolve_version.py reads merged PRs' labels through gh api
id-token: write # required for `npm publish --provenance`
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
# The tip of main, not the SHA that triggered this run: with two merges in quick
# succession the concurrency group queues the second run, and the first must bump on
Expand Down Expand Up @@ -266,14 +268,14 @@ jobs:

- name: Create tag and GitHub Release
if: steps.check.outputs.already_released == 'false'
uses: softprops/action-gh-release@v3
uses: softprops/action-gh-release@8a0cd651e5b2365bd640854a3fa5dfc70e4875f3 # v3.0.4
with:
tag_name: ${{ steps.check.outputs.tag }}
target_commitish: ${{ steps.check.outputs.sha }}
body_path: release_notes.md
generate_release_notes: true

- uses: actions/setup-node@v7
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
if: steps.check.outputs.already_released == 'false'
with:
node-version: "20"
Expand Down
Loading
Loading