release: v0.20.0 - #92
Merged
Merged
Conversation
…lidated against the build
…rrides and --karaoke word timing
Subtitles could leave a draft only as bare SRT/WebVTT; every colour, weight
and multi-range highlight stayed behind. export-ass emits the full look:
[Script Info] takes PlayRes from the draft canvas, one [V4+ Styles] line per
distinct text styling (font size/colour/alpha, bold/italic/underline,
alignment, border/shadow/background where they map onto BorderStyle/Outline/
Shadow/BackColour), and one Dialogue per text segment. A material's
styles[].range blocks (UTF-16 code units) that differ from the base style
become inline override tags with an explicit reset after the span. --karaoke
collapses word-timed caption segments the way export-srt --granularity word
does and writes {\k} centisecond timing on absolute rounded onsets, with the
highlight colour as PrimaryColour over the base SecondaryColour. Output goes
to stdout, or to --out with a JSON summary. Colour helpers encode/decode the
&HAABBGGRR / &HBBGGRR& blue-green-red forms and are tested in both
directions; the writer is pure and unit-tested without a draft on disk.
… per-range styles instead of dropping them
parseAss flattened every Dialogue with a single regex: each {...} override
block was deleted wholesale, \N/\n became newlines, \h a space, and the
result was trimmed — so a file's inline styling never reached the draft, and
the [V4+ Styles] section was never read at all. Now the Dialogue text is
walked with a running tag state: \b (0/1 and 400/700 weights), \i, \u,
\c/\1c (&HBBGGRR&, blue-green-red) and \fs map onto spans in UTF-16 code
units of the final stored text, \r resets to the Style line, and any other
tag ({\an8}, \pos, \k, ...) is stripped exactly as before. Spans that
merely restate the referenced Style's defaults (the \b0 half of a bold
range) produce no range. import-ass writes the spans through the same
per-range machinery text-ranges uses, and the Dialogue's [V4+ Styles] line
seeds font size, primary colour and alignment where no flag overrides them.
The round-trip test re-imports export-ass's styled output and asserts the
reproduced styles[] arrays and timings are identical.
… seed cut/compile
…isters an entry without its witness draft
… an audio segment
…nd bundles (#50) Issue #50 (CapCut 7.x reported to keep the live document at Timelines/<id>/draft_info.json) is stalled on four evidence items the reporter was asked for: Timelines/project.json, the file tree of the draft/template/project files, the exact app version + OS marker, and a root-vs-nested before/after showing whether a successful root write leaves the nested document stale. diagnose (and diagnose --bundle, plus the fixture bundle's diagnose.json) now attaches a nested_evidence section carrying all four whenever the timelines-nested layout or any nested Timelines/ document exists: the pointer file redacted through the standard bundle redactors (#59), the file tree with sizes and mtimes, the version marker via detectVersion, and a per-nested-document comparison - content hashes, which side is mtime-newer, and per-track segment/text counts plus a text hash, never raw text, so the report stays privacy-safe by construction. Read-only: no write-path change - whether the nested pointer is authoritative is a separate decision gated on this evidence arriving (refs #50). Non-nested drafts produce byte-identical diagnose output (regression-tested).
…o newer-build relink reports come with evidence Newer CapCut builds (reported on CapCut International 9.1.0, macOS) are reported to show timeline media as "file inaccessible" and to prompt per-clip relinking when draft_meta_info.json's draft_materials does not register the media, even with valid paths in the timeline file. This CLI never writes draft_materials and no real entry shape has been captured, so the registration write stays deliberately out of scope. diagnose gains a read-only media_registration note, attached only when the timeline references local media and draft_materials provably registers nothing: sidecar missing entirely (CLI-born drafts), the key absent, or present with every group empty. The note states what was observed, the reported symptom, and the one-command ask - capcut fixture on an app-authored draft from such a build produces the sanitized bundle (it includes draft_meta_info.json) the write can be built from. Any shape not provably empty suppresses the note; no exit-code change, and the all-clear next_action survives.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two threads run through this release. Subtitle styling now crosses the draft boundary in both directions —
export-asswrites it out,import-assstops throwing it away. And the raw-recording pipeline closes inside the CLI: find the speech, voice the script, cut the dead air. Underneath, the ffmpeg fail-fast work from 0.19.0 is finished on the audio chain, anddiagnosenow produces the evidence the two open store-layout questions are waiting on. No command was removed and no existing flag changed meaning.Fixed
atrim/asetpts/adelay/anull/amixdied on the raw parser error class 0.19.0 eliminated for video. Probed from the same single-filtersoutput; fail-fast up front for the unconditional five, and foratempo/volume/afadeexactly when the built plan uses them. A guard test extracts every filter name from a representativefilter_complexand asserts probe coverage for both chains. Closes render: audio-chain filters are never probed (same failure class as #89); add a chain/probe guard test #91.import-asskept nothing of a file's styling — inline{...}tags were deleted wholesale and[V4+ Styles]never read. Bold/italic/underline/colour/size spans now become per-range styles (UTF-16 code units, the text-ranges writes UTF-16LE byte offsets, but CapCut International stores code units #85 rule), and the referenced Style line seeds segment defaults. The export→import round-trip is pinned by test.Added
export-ass— styled ASS export:[V4+ Styles]derived from the draft's text styling, per-range override tags with explicit resets (&HAABBGGRRcolour order tested both directions),--karaokeword timing from the same timestamps the WebVTT karaoke writer uses.detect-silence— the audio twin ofdetect-scenes: silence spans plus the complementary keep segments, consumable bycut/compile;--padkeeps a margin around speech so no word clips mid-syllable.tts— voiceover through any local TTS command template (piper,say, espeak-ng); no shell in the path, text via argv token or stdin, landing as a real audio segment through the existingadd-audiopath;doctorreports the configuration.render --encoder— hardware/alternate video encoders, validated lazily againstffmpeg -encoders; without the flag the invocation is byte-identical to 0.19.1.harvest-enums --sync/--add— whole-library catalogue sweep (skip-and-report on broken drafts, idempotent) and manual entries with full validation, both on the existing plan/--applyconvention and atomic writer.diagnoseevidence capture — for nested-Timelines/drafts, the report and sanitized bundles now carry the pointer file, the draft-file tree, the version/OS markers, and a root-vs-nested divergence comparison (hashes and counts, never raw text) — the before/after needed to settle CapCut 7.x edits are discarded when the active draft lives under Timelines/ #50 (refs CapCut 7.x edits are discarded when the active draft lives under Timelines/ #50, not closed). Separately, a read-only note fires whendraft_meta_info.jsonregisters no timeline media — the reported relink condition on newer CapCut builds — asking for afixturebundle so the write side can be built from evidence instead of guesswork.Release chores
Version bump (lockfile touched on exactly the two version strings), changelog, README release notes rotated in both languages, command reference regenerated and the Chinese translation synced.
Verification
807 tests, up from 703 on master — every new surface has its own test file (export/import-ass round-trip, silence-span math on captured ffmpeg stderr, fake-TTS e2e, catalogue sweep fixtures, diagnose redaction/byte-stability).
biome check --error-on-warningsclean; the pre-commit hook re-ran the full suite on every commit on this branch.