diff options
| author | Adam Soltys <[email protected]> | 2026-09-30 10:10:10 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-09-30 10:10:10 -0700 |
| commit | 505cd84813a80e0a69b2cc95aa93c68cf2856cb2 (patch) | |
| tree | 3453513920b23476e01efe508e73ba8651f438da /build.js | |
| parent | 93c07bec934e8e8d847349b7792f4cc9089adbb7 (diff) | |
| download | coinosv3-505cd84813a80e0a69b2cc95aa93c68cf2856cb2.tar.gz coinosv3-505cd84813a80e0a69b2cc95aa93c68cf2856cb2.zip | |
Videos are shrunk on the phone before upload; nostr.build is the first media host.
No public Blossom host transcodes (nostr.build's and primal's BUD-05 /media
return the same bitrate), so a 15-20 Mbps phone clip stalled on playback.
src/video-compress.js re-encodes on the device with WebCodecs via
Mediabunny (a lazily loaded chunk, left out of the SW precache and the
standalone file): H.264, short edge 720, ~2.5 Mbps, moov first, audio
passed through, rotation baked in. Anything short of a clear win uploads
the original. A toast counts the shrinking down.
Media hosts: blossom.nostr.build first, nostr.download second (it was
unreachable for hours); a HEAD probe skips a host that doesn't answer
within 5 s instead of waiting out the whole upload timeout.
video-compress-test: 1080p 20 Mbps 5 s (landscape and rotated portrait) →
1.6 MB H.264 720p 2.49 Mbps with audio, moov first, in 2-3 s.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Du1qT1wbkYwYK6zkGH79Rp
Diffstat (limited to 'build.js')
| -rw-r--r-- | build.js | 13 |
1 files changed, 11 insertions, 2 deletions
@@ -332,7 +332,13 @@ async function bundleApp({ minify, features, staging, splitting = false }) { // The split build emits real ESM chunks (deferred features arrive as their // own files); the single-file build inlines the dynamic imports instead. ...(splitting ? { splitting: true, format: 'esm', naming: { chunk: 'chunk-[hash].[ext]' } } : {}), - plugins: [featurePlugin(enabledFeatures(features)), flagsPlugin(staging)], + plugins: [featurePlugin(enabledFeatures(features)), flagsPlugin(staging), + // the single file inlines every dynamic import: the video compressor + // (Mediabunny, ~700 KB) would ride along in a file meant to be small + // and offline — there it uploads the original, as before + ...(splitting ? [] : [{ name: 'no-video-compress', setup(build) { + build.onLoad({ filter: /src\/video-compress\.js$/ }, () => ({ loader: 'js', contents: 'export async function compressVideo(f) { return f; }' })); + } }])], }); if (!result.success) { for (const log of result.logs) console.error(log); @@ -470,7 +476,10 @@ if (import.meta.main) { const nwcSw = feats.includes('nwc') && feats.includes('ark'); const swBody = SW .replaceAll('{{VERSION}}', version) - .replaceAll('{{EXTRA_SHELL}}', chunks.map((c) => `, '${c.name}'`).join('')) + // precached for offline use — except what only works online anyway: + // the video compressor (Mediabunny, ~700 KB) loads when a video is + // picked for upload, not on every install + .replaceAll('{{EXTRA_SHELL}}', chunks.filter((c) => !c.text.includes('Mediabunny Codec Registry')).map((c) => `, '${c.name}'`).join('')) .replaceAll('{{NWC_WAKE_FALLBACK}}', nwcSw ? '' : SW_WAKE_ONLY); await Bun.write('dist/sw.js', nwcSw ? swBody + '\n' + await buildSwNwc() : swBody); for (const f of STATIC) await Bun.write('dist/' + f, Bun.file('static/' + f)); |
