feat: publish av-tools 0.2.0

This commit is contained in:
2026-07-27 01:04:21 +02:00
parent fcc537b024
commit 0a4548851c
68 changed files with 4130 additions and 605 deletions

119
README.md
View File

@@ -8,8 +8,8 @@ telemetry, runtime CDN, remote-media fetch or third-party script.
It is also a Toolbox SDK application. The same static build runs directly or
under Toolbox Portal with shared shell, theme, help and app switching.
> **Release status:** 0.1.0 is licensed GPL-3.0-or-later. Its canonical
> release consists of the exact reviewed `v0.1.0` source, production
> **Release status:** 0.2.0 is licensed GPL-3.0-or-later. Its canonical
> release consists of the exact reviewed `v0.2.0` source, production
> ZIP/checksum and Corresponding Source bundle published together. See
> [Licensing](#licensing).
@@ -23,7 +23,7 @@ Two workflows keep the product intentionally smaller than a nonlinear editor:
- **Edit:** a media bin and sequential non-overlapping clip timeline with
non-destructive settings, one export at a time.
The planned 0.1 line covers typed/capability-gated conversion and remux,
The 0.2 release covers typed/capability-gated conversion and remux,
fast/accurate trim, split, compatible/normalized concatenate, reorder, crop,
resize, frame-rate change, audio extraction/stream removal, waveform,
peak/two-pass loudness normalization, gain, audio/video fades, metadata,
@@ -34,10 +34,18 @@ diagnostics and explicit browser export.
The Edit workspace now exposes structural exports directly: fast stream-copy
or preset-backed accurate trim uses the selected clip's timeline range, while
fast concatenate requires explicit compatibility diagnostics and normalized
concatenate requires a preset plus an explicit missing-audio policy.
concatenate requires a preset plus an explicit missing-audio policy. Normalized
joins can apply a uniform, capability-gated 0.0410 second audio/video
crossfade at every edit, with clip-material checks before queueing.
Operations enter a bounded, in-memory application queue with at most eight
scheduled operations and one FFmpeg execution at a time.
Thumbnail series and contact sheets support even, interval, chapter, marker or
bounded scene-change selection. Scene analysis records exact source
presentation timestamps before extraction. Contact-sheet labels use only the
bundled, SHA-256-verified DejaVu Sans 2.37 file and remain disabled unless the
active core exposes `drawtext`; there is no remote/system-font fallback.
When a source cannot be played directly, the preview panel can create a
disposable H.264/AAC MP4 proxy. The user can bound it to 1300 seconds and
choose a maximum width from 4801920 pixels. A proxy is reused from the local
@@ -53,14 +61,15 @@ Exact runtime packages:
- `@ffmpeg/ffmpeg` 0.12.15;
- `@ffmpeg/util` 0.12.2;
- `@ffmpeg/core` 0.12.10 (single-thread);
- `@ffmpeg/core-mt` 0.12.10 (multithread).
- reviewed FFmpeg core build `0.12.10-reviewed-stack5m.1` in single-thread and
multithread profiles.
The published cores contain **FFmpeg n5.1.4** (libavcodec 59.37.100), built
The reviewed cores contain **FFmpeg n5.1.4** (libavcodec 59.37.100), built
with x264, x265, libvpx, LAME, Ogg/Theora/Opus/Vorbis, zlib, libwebp,
FreeType/FriBidi/HarfBuzz/libass and zimg. Both ~32 MiB WASM cores and their
JS/worker files are copied from exact npm packages and served from the app's
own origin. `npm run build` does not download them.
JS/worker files are verified against a tracked build lock, unpacked from a
deterministic repository artifact and served from the app's own origin.
`npm run build` does not download them.
Every engine load queries actual demuxers, muxers, decoders, encoders and
filters. Presets remain disabled when requirements are absent; an extension or
@@ -92,10 +101,12 @@ WebM/VP8/Vorbis, MP3 and WAV are common preview candidates, but actual codec,
browser and platform support is checked at runtime. Matroska and many other
valid outputs may be download-only. A preview proxy may require re-encoding.
The pinned core has an unresolved Opus encoding regression risk (zero-byte or
out-of-bounds behavior reported around upstream stack-size fixes). Opus
presets must stay unavailable unless a real non-empty, re-probeable ST/MT smoke
passes. Details are in [FFmpeg build](docs/FFMPEG_BUILD.md).
The 2026-07-26 Chromium regression harness ran the real built-in `audio-opus`
plan against both reviewed cores. Each selected the requested ST/MT mode,
produced non-empty Opus and passed codec/duration re-probing. Opus presets are
therefore enabled when runtime capability discovery also succeeds. Exact
commands and evidence boundaries are in
[FFmpeg build](docs/FFMPEG_BUILD.md).
## Execution modes
@@ -169,9 +180,14 @@ Core assets are generated local build inputs:
```sh
npm run vendor:ffmpeg
npm run vendor:verify
npm run vendor:verify-runtime
```
The runtime verifier checks the tracked deterministic core artifact, source
lock, build driver and generated same-origin files. The stricter
`npm run vendor:verify` publication gate additionally requires and hashes the
ignored Corresponding Source archive generated by `npm run source:package`.
Regenerate or verify the tiny synthetic fixtures:
```sh
@@ -183,7 +199,7 @@ npm run fixtures:verify
```sh
npm run manifest:check
npm run vendor:verify
npm run vendor:verify-runtime
npm run typecheck
npm run lint
npm run format:check
@@ -191,6 +207,8 @@ npm test
npm run build
npm run toolbox:check
npm run test:browser
npm run evidence:large-preview # set AV_TOOLS_LARGE_MEDIA first
npm run evidence:opus
```
`npm run check` combines the non-browser production checks. Browser tests cover
@@ -198,13 +216,27 @@ the real pinned cores, MT-to-ST fallback, cancellation/recovery, generated
fixtures, nested deployment, Toolbox context and the absence of runtime CDN
traffic.
The latest recorded local Vitest run on 2026-07-24 completed **303 passing
tests and one conditional skip**. It includes broad structured-command
execution against native FFmpeg 7.1.3; the skipped native subtitle burn-in case
requires a `subtitles` filter unavailable in that host build.
`npm run evidence:opus` independently contains each ST/MT browser process,
prints one JSON report and exits normally even when the result is unsafe.
`npm run test:opus-regression` runs the same evidence as the positive Opus
enablement gate and exits nonzero unless both modes produce non-empty,
re-probeable Opus. It is a mandatory release gate for the reviewed core
profile.
`AV_TOOLS_LARGE_MEDIA=/absolute/video.mp4 npm run evidence:large-preview`
performs the opt-in large-file regression: the native video element must mount
and advance before bounded inspection finishes, remain the same element after
the authoritative probe completes and produce no browser error.
The latest recorded local Vitest run on 2026-07-26 completed **313 passing
tests and two conditional skips**. It includes broad structured-command
execution against native FFmpeg 7.1.3; the skipped native subtitle burn-in and
labeled contact-sheet cases require `subtitles` and `drawtext` filters that are
unavailable in that host build.
The Chromium suite exercises the pinned ST core across conversion,
trim/concat/split, analysis, waveform, image, metadata, chapter, subtitle,
trim/concat/split, bounded crossfades, analysis, waveform, scene-selected image
generation, bundled-font contact-sheet labels, metadata, chapter, subtitle,
queue and recovery workflows. The MT core is directly initialized and queried,
and completes a real non-empty, re-probeable H.264/AAC conversion; the same
path is benchmarked with 2-second 160×90 and 6-second 640×360 inputs. Nested
@@ -243,12 +275,12 @@ repository and the `GPL-3.0-or-later` SPDX licence.
Portal must consume an independently built ZIP; it must not build or import
av-tools source. Immutable Portal revision
`bda9da044d61c109afd9969d357cc27f76648938` has isolation and WASM CSP
permissions but lacks `media-src blob:`, which blocks Blob previews. The
developer's active Toolbox Portal worktree currently contains the narrow local
`media-src 'self' blob:` patch; that uncommitted worktree state does not change
the immutable reference or release evidence. The exact distinction, smallest
change and fallback are documented in
`5c052bc6d1073a66600cfddc44c0e16da34bede8` (`v0.6.0`) provides the required
isolation, narrow WebAssembly CSP, Blob media policy and explicit WASM MIME
mapping. The active Portal worktree additionally extends immutable caching to
the exact reviewed FFmpeg build profile without accepting mutable-looking
suffixes. Its exact reviewed and staged
boundaries are documented in
[Portal requirements](docs/PORTAL_REQUIREMENTS.md).
## Release
@@ -272,11 +304,11 @@ metadata:
```sh
npm run package:release
npm run portal:smoke -- \
--allow-known-header-gap
--portal-root ../toolbox-portal
```
The header-gap override remains development-only until the Portal CSP change is
committed. Full commands and safety behavior are in
The smoke harness clones the selected Portal `HEAD`; it never consumes
uncommitted Portal files silently. Full commands and safety behavior are in
[release documentation](docs/RELEASE.md).
## Licensing
@@ -286,11 +318,11 @@ and licensed **GPL-3.0-or-later**. See [LICENSE](LICENSE). The application
provides a visible licence, source and no-warranty notice in its Help dialog.
Third-party components retain their copyright and licence terms.
The wrapper/util are MIT. Core/core-mt 0.12.10 declare
GPL-2.0-or-later and statically include FFmpeg/external codec code with
additional terms. The branch-based x264/LAME inputs have been resolved to
immutable commits in the source record. A binary publication must include
equivalent access to the reviewed Corresponding Source and notices. See:
The wrapper/util are MIT. The reviewed 0.12.10 cores statically include
GPL-enabled FFmpeg/external codec code with additional terms. The branch-based
x264/LAME inputs have been resolved to immutable commits in the source record.
A binary publication must include equivalent access to the reviewed
Corresponding Source and notices. See:
- [third-party notices](THIRD_PARTY_NOTICES.md)
- [source record](SOURCE.md)
@@ -317,19 +349,18 @@ The auditable list is in
- Metadata removal is best effort, not an anonymity guarantee.
- Browser preview supports fewer combinations than FFmpeg.
- MT depends on isolation; ST can still hit memory/time limits.
- Opus output is release-gated for the pinned core.
- Opus enablement is supported by Chromium ST/MT fixture evidence, not a
cross-browser or arbitrary-input guarantee.
- Projects do not contain source bytes by default and require reattachment.
- Cross-browser/mobile and exhaustive MT performance matrices remain
unrecorded; published support claims must stay within the tested evidence.
## Roadmap
1. Complete Quick Convert and structural-export browser verification with the
real pinned ST/MT cores, including fallback and queued execution.
2. Verify waveform, loudness normalization and combined filters in browsers.
3. Verify metadata/chapter/subtitle round trips in browsers.
4. Verify bounded thumbnails/contact sheets, projects, derivative-cache reuse
and export in browsers.
5. Complete accessibility, mobile, performance and nested Portal matrices.
6. Commit/tag exact source, publish its reviewed Corresponding Source, assemble
the exact production ZIP through Portal and verify deployed headers.
1. Extend the evidence matrix beyond Chromium to Firefox, Safari and mobile;
broaden MT operation parity and replace the one-run performance observation
with repeated cold/warm measurements.
2. Evaluate optional editing breadth without weakening local-first guarantees:
additional reviewed transition shapes, richer scene-ranking controls and
explicit transition audio-curve choices beyond the current bounded uniform
crossfade.