Video files that break things, with the facts to prove it.
Generated test files for players, upload pipelines and transcoders. Every frame is numbered, the audio beeps on known frames, and each file ships with a fact sheet your tests can assert against.
The parameters are the address.
Describe the file in the URL and fetch it with your API token. It is generated once and cached forever, and the same URL always returns the same bytes, so it can live in a test suite or a CI job.
Ask for .json instead and you get the fact sheet: what the file contains, measured and checked by two decoders.
# the file curl -H "Authorization: Bearer $TESTSRC_KEY" -O \ https://testsrc.com/v/hevc-main10/1080p/29.97fps/6s/rotate-90.mov # its fact sheet curl -H "Authorization: Bearer $TESTSRC_KEY" \ https://testsrc.com/v/hevc-main10/1080p/29.97fps/6s/rotate-90.json { "codec": "hevc", "profile": "Main 10", "coded_size": "1920x1080", "display_matrix_rotation": 90, "displayed_size": "1080x1920", "frames": 180, "keyframes": [0, 60, 120], "beeps_at_frames": [0, 30, 60, 90, 120, 150], "verified_by": ["ffprobe 7.1", "gstreamer 1.24"] }
Each file reproduces something that broke a real player.
The basic codec and container grid is here too. The edge cases are the point: structure, timing and damage that only show up in production, each traced to a real bug report.
| File | What it does | Breaks |
|---|---|---|
| mov-quicktime-trimmed-editlist.mov | Several edit-list entries from a QuickTime trim. Playback hangs after the first cut. | Players |
| mp4-initial-empty-edit.mp4 | Edit list starts with an empty edit, as Samsung Galaxy cameras write. Black frames at the start. | Players, transcoders |
| fmp4-free-between-moof-mdat.mp4 | A free box between moof and mdat in a fragmented file. Playback never starts. | Players |
| ts-pcr-wrap.ts | Timestamps wrap past 233 a few seconds after the start. | Players, recorders |
| ts-aac-stereo-to-5.1.ts | Audio switches from stereo to 5.1 in the middle of the stream. | Decoders |
| ts-resolution-change.ts | Video switches from 1080p to 720p at 9 seconds. | Players, hardware decoders |
| webm-truncated-mid-cluster.webm | Cut in the middle of a cluster. Playback never starts. | Players |
| mka-opus-codec-delay.mka | Opus with pre-skip in Matroska. The first two seconds are silent. | Players, transcoders |
| avi-rawvideo-bgr24.avi | Top-down raw RGB with a negative height, read as 4294966216 pixels tall. | Players |
| flac-5-hours.flac | Five hours of FLAC. Seeking past the halfway point fails. | Players |
| opus-5.1-family-1.opus | 5.1 Opus with channel mapping family 1. Wrong or no output. | Decoders |
11 of 205 edge cases shown. New cases every week, with a changelog and RSS feed.
You can check it by looking at it.
All picture and sound is synthetic, so every file is ours to give away. What it carries is chosen so a test, or a person, can see what went wrong.
Frame number on every frame
Dropped, repeated or reordered frames are visible in a screenshot. Seek to frame 120 and check that 120 is what you see.
Burned-in timecode
Compare the picture's own clock with what the player reports, after a seek, a speed change or a transcode.
A flash and a beep once per second
They start on the same frame. If they drift apart in your output, so did your audio and video.
A fact sheet a test can assert
Duration, frame count, keyframes, rotation, colour tags and A/V offset, measured with ffprobe and checked against a second decoder.
Can't share the file? Get one you can.
Paste the ffprobe output of the file that breaks. You get back a twin you're free to attach to a public bug report or commit to a test suite. Only the text you paste is sent, never your video.
From a browser, a script, a CI job or an AI agent.
// any test, any language const headers = { Authorization: `Bearer ${process.env.TESTSRC_KEY}` }; const file = await fetch("https://testsrc.com/v/edge/vfr-screen-recording.mp4", { headers }); const facts = await (await fetch("https://testsrc.com/v/edge/vfr-screen-recording.json", { headers })).json(); expect(myPlayer.duration).toBeCloseTo(facts.duration_s, 2);
CORS and range requests are on. Browser tests use short-lived signed URLs made with your token.
# free CLI, signed binaries
npx testsrc login
npx testsrc get torture-pack --out fixtures/
npx testsrc get edge/ts-pcr-wrap.ts edge/mp4-initial-empty-edit.mp4
npx testsrc facts edge/mp4-initial-empty-edit.mp4
Files are cached locally and checked against their published checksums.
- uses: testsrc/fetch@v1 with: snapshot: 2026-10 # pinned: same bytes on every run packs: torture, hdr, subtitles path: fixtures/media api-key: ${{ secrets.TESTSRC_KEY }}
Pin a monthly snapshot so updates never change your build without you asking. Open-source projects get a free token; company plans cover CI.
// in Claude Code, Cursor or any MCP client // add the server with your TESTSRC_KEY get_test_file({ describe: "MP4 where audio runs 3 s past the end of video" }) → edge/audio-3s-longer-than-video.mp4 url, facts, why it breaks things
Agents writing media code get a real file with known properties, instead of guessing at ffmpeg flags.
Browse for free. Fetch with a token.
Browse
No accountThe catalog and every case page: what the file does, what it breaks and its main facts. Baseline files come with their full recipe and fact sheet.
Try a file
Sign in with GitHub (soon)Download up to 5 files by hand and check them against your bug.
Open-source projects
Free token on requestRate-limited, honest use welcome: CI, bug-report templates, regression tests.
Companies
$99/month per organisationA token for CI, scripts and agents. Pinned snapshots, full fact sheets and expected outcomes. Try it for a week.
Usage is metered per token. Tokens used to mirror or resell the catalog are revoked.
Test, modify, commit to your repo, ship in your test suite, attach to bug reports. Commercial use included. Credit “Test media by testsrc.com”.
No hosting the files as a collection or sample library, no reselling, no public datasets. Open-source projects that need a permission for their repo can ask.
Hitting a media bug you can't crack?
Some bugs live in the bitstream, a muxer's quirk or a decoder's corner case. Tell us what breaks. We are multimedia experts with over 20 years of experience, and we fix this kind of problem for a living.