Automated release: version and notes generated from pull requests merged since 3.8.13.
Fixed
verify.pynever writes over another of its inputs (review of #521). The names it
generates (<stem>_cut.mp4,_acc,_fit,_capwith its.srt/.ass,_cues.txt, ...)
were checked by each step against its own input only, soverify.py FOLDER --out FOLDER --overwritewithclip.mp4andclip_cut.mp4in it replacedclip_cut.mp4with the cut of
clip.mp4and then verified the replacement. Every name is checked against every input, a link
or another case of the name included, before anything is written:kind: input,
error.reason: output_is_input, naming both paths.batch.pyalready refused this (#428).--json-briefalone prints the JSON document on every tool (review of #521). It implies
--json, but the tools that branch on--jsonthemselves did not see it:probe.py --field
printed a bare string or an empty line,check.pyits text table,report.pythe document and
then a bare path,verify.pyits Markdown report and no document, andcropdetect.pyand
silence.py --lista bare document with nostatus.redact.py --blur-strength 1blurs colour too (review of #521). The chroma radius was half
the luma radius rounded down, 0 at strength 1, so detail carried by colour alone stayed
readable; it is at least 1 wherever the chroma plane can hold it (a region 6 px or more on its
short side).- The agent eval notices a second edit and refuses a run folder it would see (review of
#521).evals/run_agents_25.shcomparedgit statusalone, so a run that edited a tracked file
already modified, or an untracked file already there, went unreported; the checkout's state now
adds the tracked files' diff againstHEADand the untracked files' hashes. ARUN_DIRinside
the checkout that git does not ignore is refused (exit 2) before anything is staged: the run's
own transcript read as a change to the checkout.
The state also carriesHEADand the index, so a run that commits or only stages its edit is
seen; an untracked link is its target's name (a dangling one no longer fails the snapshot); and
a snapshot that cannot be taken stops the script (exit 3) instead of comparing equal to another
failed one. - A BT.2020 source with no transfer tag is no longer written as HLG (#463 A153). probe reads
BT.2020 primaries with no transfer tag as "BT.2020 SDR", and every re-encode on the 10-bit line
(x265, SVT-AV1, libaom, ProRes, VideoToolbox) tagged the outputarib-std-b67. It is tagged
bt2020-10, the SDR curve BT.2020 defines, and reads back as BT.2020 SDR. A Dolby Vision
source with no transfer tag keeps the HLG tag it had. color.py --to-sdr --forceon a file that is not HDR (#463 A161). The note said "tone-mapped
untagged input as PQ" for every such file, a BT.709-tagged one included, which the chain reads
as BT.709; it now names the transfer and primaries the chain read the file as. On a file with no
colour tags at all the run failed askind: ffmpeg(zscale on FFmpeg 6.1: "no path between
colorspaces"); a frame missing a tag is labelled with what the chain assumes first.fit.py --method trimfrom the start keeps subtitle and data tracks (#463 A158): it added
-ss 0.000, which the tool treats as moving the timeline. A trim with--from-centerstill
seeks and drops them, as decided.- An
-owithout an image extension is a stem in everylook.pymode (#463 A159):--compare
and the contact sheet used it verbatim and failed askind: ffmpeg; they now write
<stem>_vs_<other>_<i>_<t>s.pngand<stem>_sheet.png, as--atalready did. - A media output with no file extension is refused before ffmpeg runs (the sweep of A159).
Every tool that writes media handed it to ffmpeg, which failed askind: ffmpeg("Unable to
choose an output format"), and the dry run said completed. It iskind: input,
error.reason: output_extension_missing, dry runs included, unless the command names its format
with-f. Side files (a report, an SRT) are not checked;look.pytakes such an-oas a stem. proxy.pynever writes a proxy wider than its source (#463 A162): the default--width 640
upscaled a smaller source, and a--scalethat rounded to 0 becamescale=0, which FFmpeg reads
as the source's width. The width is capped at the source's (even) width and floored at 2, with a
notesline when either applies.sphere.py's default view has square pixels (#463 A163):--v-fovdefaulted to 60 whatever
--h-fovand the frame were, and 90 x 60 at 16:9 squashed the view 2.6 % vertically. Without
--v-fovthe vertical field of view now follows from--h-fov,--widthand--height
(58.7 at the defaults); a pair given that is not square-pixel is drawn as given, with anotes
line.stabilize.py --zoomis the only zoom (#463 A156): vidstab's own "optimal zoom" was always
on, so--zoom 0did not keep the original framing and--crop blackrarely had an edge to
fill. The default output now keeps the framing and shows the edges stabilizing reveals.- The youtube presets stay within YouTube's frame-rate limit (#464 A115): they keep the
source's rate, so a 120 fps source was exported at 120 fps andcheck.py --platform youtube
failed it. A source above the platform'sfps_maxis exported at its rate over the smallest
whole divisor within the limit (120 to 60, 119.88 to 59.94, 100 to 50), with anotesline. export.py --max-mbwith--normalizestays within the size it was encoded to (#464 A112):
the loudness pass re-encoded the sound at 192k (raised to 256k or 320k on a true-peak overshoot)
against a budget built on the preset's 128k. Under--max-mbit runs at the preset's bitrate.probe.py --fieldprints JSON, not Python (#464 A123): a boolean, a missing field or an
object came out asTrue,Noneor{'codec': ...}. A string is printed as itself and any
other value present as JSON; a missing field is still an empty line, as it always was. With
--jsonor--json-briefevery line is JSON (a string is quoted, a missing field isnull).verify.pykeeps its outputs apart and where it says (#464 A121, A119, A120). Twoclip.mp4
and aclip_1.mp4were given the output stemclip_1twice; an indexed stem now skips every
stem already taken, compared case-folded.--overwriteand--fastreach every step, so a
rerun into the same--outreplaces the earlier outputs instead of failing every step.
--keepwithout--outkept nothing (the temporary folder was deleted at exit) and named no
folder; it keeps the outputs in a new folder, named in the newout_dir(also set for--out,
nullwhen the outputs were deleted) and on stderr.- One tool's contract without the other 41 (#467: A220). SKILL.md and
references/flags.md
sent an agent tocontract --json, about 950 KB, for one tool'sdry_run.contract --json --tool NAMEkeeps only the named tools undertools(repeatable;cutorcut.py), in the
order given, and every other key as it is: about 55 to 85 KB for one tool. An unknown name is
refused (exit 2) with the list of tools; the two pages now name the flag. verify.pywalks every media extension the skill reads (#467: A218). A folder argument
skipped.ts,.3gp,.wmv,.gif,.ogg,.opus,.aif/.aiff,.cafand.wma: verify
kept a list of its own. It uses_common's list less the stills, asbatch.pydoes.- The npm package no longer ships Python bytecode (#467: A222, A27, A36). With npm 10,
package.json'sfileswins over.npmignore, so a checkout that had run the tests packed
59scripts/__pycache__/*.pycfiles carrying the machine's paths.filesends with negated
entries for them, andtests/release_check.shfails a tarball that has one. - Dead code and unused imports in the runtime (#467: A224): 39 unused imports, the unused
loudness.pyloudnorm string andgraphics.pylist, and two functions nothing called
(_platforms.has_frame,_contract._ff_list) are gone, and a test fails on an import a shipped
module never uses. - The gallery prints the command its picture was made with (#467: A243, A244).
cropdetect_cropread the rectangle from the wrong level of cropdetect's document and cropped a
hard-coded one labelled "detected";scenes_highlightsprinted a cut list (0.00-1.50,4.00-5.50)
the build never ran. Both run the measured value,docs/demos.mdprints the one the build
measures (0.00-2.00,2.00-4.00), and a build that measures anything else stops. - The agent eval runs the shipped skill and notices a changed checkout (#467: A271, A274).
evals/run_agents_25.shlinked the whole repository in as the skill, the eval's answer keys
included, and with every permission check off a run could edit the tracked tree unnoticed. It
installs the skill withbin/install.js --dir, and exits 1 naming the runs during which the
checkout'sgit statuschanged. - fix: audit #463, #464 and #467 open items across media tools, delivery and packaging (#521)
What's Changed
- fix: audit #463, #464 and #467 open items across media tools, delivery and packaging by @kajisho5 in #521
Full Changelog: v3.8.13...v3.8.14