Limits and support
Browsers
| Browser | State |
|---|---|
| Chromium (Chrome, Edge) | Tested in automation on every change: the browser test suite runs in Chromium through Playwright. |
| Safari | Works where WebCodecs encoders exist (Safari 17 and later). Not automated. |
| Firefox | Not automated. |
Two things need a secure context (HTTPS, or localhost). File storage for media needs it. The licence check needs it too, plus Ed25519 in WebCrypto: Chrome 137, Safari 17 or Firefox 129, or later. In an older browser the key cannot be checked, so the mark is drawn.
Export needs the WebCodecs VideoEncoder and AudioEncoder. A browser without them gets a message in the export dialog instead of a crash.
Phones and tablets
The editor runs on phones. Its layout changes with the width of its root element, not the window: the properties panel folds into a bar below 640 px. The engine also changes four things on a phone. It makes no preview proxies. It runs one transcode at a time. It uses the smaller tiny.en model for captions. It passes export frames in I420 format. Big exports can still run out of memory on a phone. The export dialog then says so and suggests a smaller size.
Export size, codecs and container
There is no fixed maximum. The limit is the browser's encoder. Before an export starts, the dialog asks the encoder whether it accepts the chosen size, bit rate and frame rate. It greys out a combination the encoder refuses. From code, detectCodecs does the same for the codec; a refused size fails inside exportProject.
| Setting | Choices in the export dialog |
|---|---|
| Size, landscape | 720p, 1080p, 1440p, 4K (3840 px wide), always in the canvas's shape |
| Size, portrait or square | 720p, 1080p, 1440p (2560 px tall), plus the canvas's own size when it is not listed |
| Frame rate | 24, 25, 30, 60, plus the project's own rate |
| Video bit rate | 4, 8, 16 or 32 megabits per second |
| Container | MP4, always |
| Video codec | H.264 (High 5.2 down to Baseline 3.0, the first the browser accepts); VP9 when the browser has no H.264 encoder |
| Audio codec | AAC-LC at 128 kilobits per second; Opus when the browser has no AAC encoder |
H.264 needs even pixel sizes; the dialog rounds odd values up.
Captions
Captions come from Whisper models running on the device: base.en on a desktop and tiny.en on a phone. Both are English only. There is no language option today.
Memory and big files
Import and preview read only a file's index, about 2 MB, and the frames being decoded. A 1 GB screen recording imports without loading into memory. Sound is the exception: an audio file is decoded whole, about 10 MB a minute. A project waits for every sound on its timeline before the first frame.
The network
The engine itself fetches nothing from us. It makes no licence call and sends no usage report. Three things reach the network. You control the first two addresses.
| What | Where it goes |
|---|---|
| Fonts for text tracks | Your options.assets.fonts folder, default /fonts/ |
| Speech and background-removal models | Your options.assets.models folder, default /models/ |
| The speech runtime's WebAssembly files | https://cdn.jsdelivr.net/npm/@huggingface/[email protected]/dist/, the default of the transformers.js library the engine uses. Only a transcription triggers it. |
A page that blocks that content delivery network loses captions and nothing else. Turning captions off (features={{ captions: false }}) removes the fetch entirely.
Content Security Policy
The engine runs three module workers from your own origin, compiles WebAssembly, loads fonts and decodes image clips through blob: addresses. This policy covers all of it with the default asset folders.
| Directive | Value |
|---|---|
script-src |
'self' 'wasm-unsafe-eval' https://cdn.jsdelivr.net |
worker-src |
'self' |
connect-src |
'self' https://cdn.jsdelivr.net, plus every host you import media from |
font-src |
'self' |
img-src |
'self' blob: |
If your fonts or models sit on another host, add that host to connect-src and font-src. For the models, add it to script-src too, because background removal loads a small script from the model folder. Leave out https://cdn.jsdelivr.net when captions are off.
The licence
The packages are free to install and to run on localhost. Without a licence key, and outside the domains a key covers, the engine draws a small "vidstudio.app" mark. The mark sits in the lower right of the preview, of renderFrameAt and of every exported frame. Every feature still works. Serving the editor to the public on any domain other than localhost requires a key for that domain. This holds whether or not the mark is shown.
A licence key is { name, key }. Pass it as the licence prop of the editor, or as options.licence of the backend. The key names one or more domains and an end date. It covers each listed domain and every subdomain of it, so a key for example.com covers app.example.com and www.example.com, but not example.org. Ports do not matter.
The check runs once, in open(), offline, against the page's host name. It takes about a millisecond and makes no network call. getLicenceState() resolves to one of three states.
| State | Meaning | Mark |
|---|---|---|
"valid" |
The signature checks out, the name matches, the key has not expired, the host is covered. | No |
"localhost" |
The page is on localhost or 127.0.0.1 with no key covering it. |
Yes |
"invalid" |
Anything else: no key, another domain, expired, or a browser that cannot check Ed25519. | Yes, plus a notice in the editor the user can dismiss |
To get a key, write to [email protected] with your domains. The full terms are in the LICENSE file of each package.
Versions
Both packages are at version 0.1.0. @vidstudio/editor pins @vidstudio/engine to the exact same version, and both pin every dependency exactly. Pin an exact version in your own package.json too, and upgrade both packages together. There is no changelog yet. Read the readme of the new version before you upgrade.
Help
Write to [email protected]. Include the package version, the browser and its version, and the console output. For an export problem, include the export settings and the size of the source file.