Source
This app’s code and revision history are public. Download a copy or explore the files below.
Public
The app’s code and revision history are public.
Run it yourself
Take the whole tree and run it on your own machine. The download needs no account. Cloning needs a sign-in.
Download .zip
bounded clone 46e773698d4102c284d30369
A copy you download is not bounded. The guarantees this app runs under - declared egress, proven invariants, writes that fail closed - live in the runtime serving this page, not in the files. What you get is auditable source you can read and run, with no runtime guarantees attached.
src/lib/media.ts
// Rewrites a recording into a clean file, optionally cut to a start and end, with Mediabunny
// (https://mediabunny.dev). Loaded only when a recording is saved or trimmed; runs on this device.
//
// The browser's recorder writes files as a stream, without their length and with few points a player
// can seek to. Rewriting them (no re-encoding) adds both, so the file shows its length and seeks
// everywhere. Trimming re-encodes the video with the browser's own encoder, so the cut lands exactly
// where the person put it, not on the nearest key frame.
import { BlobSource, Conversion, Input, MP4, Mp4OutputFormat, Output, StreamTarget, WEBM, WebMOutputFormat, type StreamTargetChunk } from "mediabunny";
const read = (blob: Blob) => new Input({ source: new BlobSource(blob), formats: [MP4, WEBM] });
export async function remake(blob: Blob, cut: { start: number; end: number } | null, onProgress: (done: number) => void): Promise<{ blob: Blob; duration: number }> {
const type = blob.type;
// Built as a Blob, not one big buffer, so long recordings do not have to fit in memory at once.
let out = new Blob([]);
const target = new StreamTarget(
new WritableStream<StreamTargetChunk>({
write({ data, position }) {
out = new Blob([out.slice(0, position), data, out.slice(position + data.byteLength)]);
},
}),
{ chunked: true },
);
const output = new Output({ format: type.includes("mp4") ? new Mp4OutputFormat() : new WebMOutputFormat(), target });
const conversion = await Conversion.init({
input: read(blob),
output,
trim: cut ?? undefined,
// Audio packets are copied as they are, shifted by at most a few hundredths of a second to line up with
// the cut. Video is re-encoded unless a key frame falls on the cut.
copy: cut ? { boundaryTolerance: 0.05, shiftTolerance: 0.05 } : {},
showWarnings: false,
});
if (!conversion.isValid) throw new Error("This browser cannot edit this recording.");
conversion.onProgress = onProgress;
await conversion.execute();
const file = new Blob([out], { type });
return { blob: file, duration: await read(file).computeDuration() };
}
Change history
Point store links to openapps.free
Bind agent address in policy
Link OpenApps pages and add contribution strip
Bounded source sync
Bounded source sync
Bounded source sync