94 lines
5.4 KiB
Markdown
94 lines
5.4 KiB
Markdown
# Storage and cleanup
|
||
|
||
av-tools separates source bytes, engine files, derivatives and project
|
||
metadata. The default policy is deliberately non-persistent for source media.
|
||
|
||
## Object URLs
|
||
|
||
Browser preview and result playback use `URL.createObjectURL(File|Blob)`.
|
||
Object URLs reveal bytes only to the current browser context but retain the
|
||
underlying object until revoked. Each owner revokes its previous URL when a
|
||
source/result changes and all URLs on project close/unmount. A preview failure
|
||
does not trigger an upload or external fallback.
|
||
|
||
## FFmpeg virtual filesystem
|
||
|
||
Every execution receives a generated job directory. Inputs are copied to the
|
||
in-memory filesystem or mounted read-only through WORKERFS where browser/core
|
||
support is verified. Outputs are always in generated paths. The runner reads
|
||
only declared outputs, then deletes output/input/control files and unmounts.
|
||
|
||
WORKERFS can avoid an initial JavaScript byte copy; FFmpeg decoding and output
|
||
still consume WASM/browser memory. Cancelling terminates the engine, so cleanup
|
||
also discards that entire virtual filesystem.
|
||
|
||
Each probe/export records its actual input mode and byte accounting. A
|
||
successful WORKERFS mount reports zero copied input bytes; if mounting fails,
|
||
the bounded compatibility fallback reports the exact bytes copied into engine
|
||
memory. This is runtime evidence rather than a speculative preflight claim.
|
||
|
||
## IndexedDB
|
||
|
||
The mounted application currently stores validated user presets in IndexedDB.
|
||
The codebase also contains a durable job-metadata store, but the application
|
||
queue described in the UI is deliberately in memory and does not instantiate
|
||
that store. Project documents are validated, versioned JSON that the user
|
||
explicitly saves and loads; they are not currently auto-saved to IndexedDB.
|
||
Media source bytes are not written there by default.
|
||
|
||
Clearing site data removes these records. Private browsing and quota eviction
|
||
may remove them earlier; the app must treat storage as recoverable cache, not
|
||
the only copy of an important user preset.
|
||
|
||
## Origin-private file system
|
||
|
||
OPFS is optional for bounded preview proxies, waveform peaks, thumbnails and
|
||
other regenerable derivatives. The current implementation uses asynchronous
|
||
origin-private file handles and falls back to a 128 MiB least-recently-used
|
||
in-memory cache if OPFS is unavailable or fails. A derivative key includes a
|
||
source fingerprint, operation, relevant settings and a cache-schema version;
|
||
waveform keys additionally identify the selected stream and analysis settings.
|
||
|
||
Preview-proxy settings are part of that identity. The current UI validates a
|
||
1–300 second maximum duration and a 480, 720, 960, 1280 or 1920 pixel maximum
|
||
width. A matching local derivative is reused without FFmpeg execution; changing
|
||
the source or either setting produces a different cache lookup. A cache miss or
|
||
cache failure falls back to generation and never mutates/persists the source.
|
||
|
||
The application works without OPFS. The storage panel reports the browser's
|
||
origin-wide quota estimate when available and offers per-entry or global cache
|
||
deletion. The current OPFS layer relies on browser quota enforcement rather
|
||
than pre-reserving space; a failed cache write switches subsequent cache work
|
||
to the bounded in-memory fallback. OPFS writes close their
|
||
`FileSystemWritableFileStream` on success and abort it on error.
|
||
|
||
OPFS is private to the current **origin**. Moving an app from one hostname,
|
||
scheme or port to another does not move cached data. Toolbox and standalone
|
||
deployments at different origins have different caches even if their files are
|
||
identical.
|
||
|
||
## Source persistence policy
|
||
|
||
Normal import retains the user-selected `File` only in the active page. Saved
|
||
projects contain source descriptors/fingerprints and prompt for reattachment;
|
||
they do not embed source bytes. If a later UI offers “keep source on this
|
||
device,” it must be explicit, show estimated/quota usage, identify the origin,
|
||
allow per-source deletion and never be silently enabled by a project import.
|
||
|
||
Downloads are explicit user actions. The File System Access API, when
|
||
available, writes only after the user selects a target; Blob download remains
|
||
the fallback.
|
||
|
||
## Cleanup matrix
|
||
|
||
| Resource | Normal completion | Cancellation/error | User control |
|
||
| ------------------------ | ---------------------------------------------------- | -------------------------------------------------------- | ----------------------- |
|
||
| source/result object URL | retained only while displayed, then revoked | revoked when owning state clears | clear source/result |
|
||
| FFmpeg job files/mount | delete/unmount in finalization | engine termination discards FS; stale generation ignored | cancel job/reset engine |
|
||
| result Blob | retained until replaced/cleared/download page closes | failed partial output is not published | clear result |
|
||
| IndexedDB user presets | retained intentionally | transaction rollback | delete/reset presets |
|
||
| OPFS derivative | retained until expiry or explicit deletion | failed write is not indexed; cache switches to memory | delete item/clear all |
|
||
|
||
The storage screen reports approximate usage; browser quota figures remain
|
||
estimates and are not a durability promise.
|