mirror of
https://github.com/storytold/filmcraft.git
synced 2026-10-24 10:10:05 -06:00
- eframe web runner on WebGPU (WebGL2 fallback; GPU compositor on WebGPU, CPU on WebGL2). - fs: virtual file table of File/Blob handles, 1 MiB chunked async range reads with an LRU cache and read-ahead (pending + retry instead of blocking), downloads for written files, /opfs/ paths written to OPFS. - import: File System Access picker / <input type=file>, drag-and-drop anywhere, container index prefetch (moov wherever it is), retried imports; project open/save. - recovery: OPFS auto-save snapshot while dirty, media copies, reopened on next visit. - audio: AudioWorklet output fed ahead from the UI thread; played-frame audio clock. - webcodecs: H.264/HEVC/VP9/AV1 MP4/MOV decoded by the browser VideoDecoder via a reader opener (fallback to our decoders on any error), probed with isConfigSupported. - api: window.filmcraft (execute/request/commands/screenshot/importFiles/importUrl/ openProject/files/readFile/info). - cargo xtask web [--dev] [--serve PORT] (wasm-bindgen CLI); xtask wasm also checks filmcraft-ui-egui and filmcraft-web; layer L6 for the web app. - Original web icon (favicon.svg) with attribution sidecar; docs/web.md; headless-Chrome smoke test (tests/smoke.mjs). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
42 lines
1.6 KiB
HTML
42 lines
1.6 KiB
HTML
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<meta name="color-scheme" content="dark">
|
|
<title>FilmCraft</title>
|
|
<link rel="icon" href="favicon.svg" type="image/svg+xml">
|
|
<style>
|
|
html, body { margin: 0; height: 100%; overflow: hidden; background: #1b1c1f; }
|
|
canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
|
|
#loading {
|
|
position: absolute; inset: 0; display: flex; flex-direction: column; gap: 14px;
|
|
align-items: center; justify-content: center; color: #c9c9cc;
|
|
font: 14px/1.4 system-ui, sans-serif; pointer-events: none;
|
|
}
|
|
#loading img { width: 56px; height: 56px; }
|
|
#loading .err { color: #ff8a7a; white-space: pre-wrap; max-width: 70ch; pointer-events: auto; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<canvas id="filmcraft_canvas"></canvas>
|
|
<div id="loading"><img src="favicon.svg" alt=""><div id="status">Loading FilmCraft…</div></div>
|
|
<script type="module">
|
|
import init, { start } from "./filmcraft_web.js";
|
|
const t0 = performance.now();
|
|
window.filmcraftLoad = {};
|
|
try {
|
|
await init();
|
|
window.filmcraftLoad.wasmMs = performance.now() - t0;
|
|
await start("filmcraft_canvas");
|
|
window.filmcraftLoad.readyMs = performance.now() - t0;
|
|
} catch (e) {
|
|
const s = document.getElementById("status");
|
|
if (s) { s.className = "err"; s.textContent = "FilmCraft failed to start:\n" + (e && e.stack || e); }
|
|
window.filmcraftLoad.error = String(e);
|
|
throw e;
|
|
}
|
|
</script>
|
|
</body>
|
|
</html>
|