# Video-export playback study: protocol v1.1

Original v1 was frozen before the first encoding matrix. This v1.1 tooling amendment is frozen before either complete accepted playback matrix. This is an original local file/browser experiment. It uses no account, existing creator video, paid service, LinkedIn upload, human reader or customer. No result establishes platform acceptance, visual accessibility, real-world browser population support or conversion.

## Tooling amendment before full matrices

The first v1 attempt generated all eight case files but failed before any browser attempt because Puppeteer's default Chrome 155.0.8059.84 binary was absent. No browser was installed. Preserve the original protocol, runner, freeze and incomplete-attempt receipt under amendments/. v1.1 accepts an explicit existing Chrome binary, preflights its file presence and saves the full generation report before browser work. Actual Chrome version is recorded. Cases, source, codec arguments, conditions, order policy and deadlines are unchanged. Run the entire corrected matrix twice, not selected failed cases. No v1 result is counted as a complete run.

## Question and fixed sample

Does a file extension or a container-only canPlayType response establish successful playback of the actual file? What changes, within one controlled pair, when MP4 index metadata moves to the front?

Generate a four-second original synthetic source with FFmpeg testsrc2: 480x270, 24 frames/second, plus a 440 Hz 48 kHz stereo tone. Save one lossless FFV1/PCM Matroska master. All normal encodings derive from this same source. Eight fixed cases in cases.json: H.264/AAC MP4 with trailing index; stream-copy faststart of that file; H.264 4:4:4/AAC MP4; HEVC 10-bit/AAC MP4; VP9/Opus WebM; AV1/Opus WebM; ProRes 422/PCM MOV; deliberate first-half truncation of the trailing-index MP4. The last is a damaged-input challenge, not a valid codec comparison.

No substitute codec, repair, changed setting or omitted case after outcomes are seen. Missing encoders, generation failures and timeouts stay explicit. Commands, exit codes, diagnostics and partial/missing outputs are retained. Prerequisites were inspected, not media outcomes. Request one thread where supported; an encoder may manage its own workers.

## Two full runs

Use Node 24, the installed FFmpeg/ffprobe 9 and existing Puppeteer 25.15.0 and installed Google Chrome. Record actual browser/OS/architecture and versions; do not publish usernames or local executable paths. Each execution uses a new output directory. Complete the whole matrix twice. Reverse browser-attempt order in run2; encodings remain dependency-ordered. Do not claim timing observations or repeated files are independent samples.

For each file save bytes/SHA256, complete ffprobe stream/format/frame count and packet-payload hashes, plus top-level MP4/MOV atom offsets where parsable. Confirm or refute identical packet payloads in the tail/faststart pair rather than assuming copy preserved them. Decode an additional video-only frame hash independently of the browser. Invalid input/absent streams return missing evidence rather than fabricated zero.

## Browser measurements

Use a fresh isolated headless Chrome context for each attempt, no account/profile/extensions, empty cache and a muted native video element. Launch with mute-audio to prevent unexpected sound, without disabling browser security. Record container-only canPlayType (no codec string), loadedmetadata, loadeddata, first video-frame callback when available, playing, ended/error, playback progress and final playback-quality counters. A positive prediction is not file validation. Ended/progress supports local decoding only; no audible review or human quality inference.

All eight cases use the unthrottled loopback HTTP server. Additionally test only the tail/faststart pair at a nominal 64 KiB/s, emitted in 4 KiB chunks with a requested 62.5 ms timer interval. Thus ten attempts per run, twenty across two runs, not twenty devices. Server supports single byte ranges and no-store. Log range/status/bytes offered; a controller checkpoint at loadeddata records bytes already offered by the server when that notification arrives. This is not exact client received bytes at the instant a frame appears; cross-process scheduling is a limitation. Fast loopback is not an internet/CDN benchmark.

The per-attempt deadline is 15 seconds; timeouts, media errors, rejected play promises and partial progress are separate statuses. Capture final media error code/message and missing timings as null, not0. Do not retry individual failures or select the fastest run. Keep every attempt and the fixed deadlines visible. A successful ended event does not establish frame-by-frame picture equivalence, correct speech or synchronization to a real video.

## Reporting and reproducibility

Publish all cases, actual commands, probes/packet hashes/frame hashes, complete attempt events/HTTP logs, diagnostics and both full runs. A content-addressed blob manifest may deduplicate byte-identical master/output files; map every run/file to its exact blob. Deduplication does not drop a failed result or claim independent replication. Keep source/measurement recipe with the raw records. Display both runs instead of a population score or universal best codec. Any harness correction requires an explicit version/reason and an entirely rerun affected matrix, not selective replacement.
