cd /news/ai-products/the-video-that-played-everywhere-exc… · home topics ai-products article
[ARTICLE · art-97655] src=dev.to ↗ pub= topic=ai-products verified=true sentiment=· neutral

The Video That Played Everywhere Except on Phones: A Codec Bug Hiding Behind a Healthy Server.

A solo developer of the AI video editing SaaS snipforge.video fixed a bug where shared videos showed 0:00 and refused to play on iPhones. The root cause was a VP9 codec inside an MP4 container, which Safari does not support, and a parser bug that failed to detect it due to ffprobe's field order. The fix involved re-encoding to H.264/AAC when needed.

read4 min views2 publishedAug 15, 2026

This is a submission for DEV's Summer Bug Smash: Smash Stories powered by Sentry.

I run snipforge.video, an AI video editing SaaS, solo. One of its core features is share links: process a video, get a URL, send it to someone. A user reported that a shared video showed 0:00 and refused to play on their iPhone. I opened the same link on desktop Chrome and it played perfectly. Classic "works on my machine," except my machine was every desktop and the failure was every iPhone.

This is the worst kind of bug report for a solo founder, because the person hitting it is usually not your user. It is the person your user shared the video with. They do not file a bug. They just conclude your product is broken and close the tab.

Everything about the symptom pointed at the serving path, so that is where I went first. Shared files live on Cloudflare R2 behind the app, and mobile Safari is famously picky about how video is served, so I had a lineup of plausible suspects:

faststart

makes Safari wait for metadata that lives at the end of the fileI checked each one. Range requests: honored, correct 206 responses with proper Content-Range

. Faststart: moov atom at the front, verified. Headers: video/mp4

, correct. Every infrastructure suspect had an alibi. The serving path was completely healthy, which was somehow worse news, because now the file itself was the suspect and the file was "an MP4 that plays fine."

ffprobe

on the shared file settled it in one line. The container was MP4, but the video stream inside it was VP9. Desktop Chrome plays VP9 in an MP4 wrapper without complaint. iPhone Safari does not, and it fails the way Safari loves to fail: no error, no console message, just a player showing 0:00 forever.

The file extension said .mp4, the Content-Type said video/mp4, and both were telling the truth about the container while saying nothing about the codec. Every layer of the stack was technically honest and the sum was a lie.

The fix belonged in the share pipeline's web-optimize step: probe the actual codecs, and if the video is not H.264 or the audio is not AAC, re-encode to the one combination that plays everywhere, instead of trusting the container.

Here is the part I am actually writing this post for.

My first patch probed the streams with ffprobe's CSV output, something shaped like this:

ffprobe -v error -show_entries stream=codec_type,codec_name -of csv=p=0 input.mp4

I wrote the parser assuming each line came back as codec_type,codec_name

, so video,vp9

. Deployed it, re-shared the test video, still 0:00 on the iPhone.

The re-encode condition never fired, because ffprobe prints the fields in its own fixed order, not the order you listed them in -show_entries

. The actual output was vp9,video

. My parser was comparing the codec name against the string "video", the match always failed, the code concluded every file was fine, and the function returned the original untouched file. No exception, no log noise, a clean deploy, and zero effect.

A fix that runs successfully and does nothing is more dangerous than a fix that crashes, because a crash tells you where to look. This one told me nothing, and for a little while I went back to re-suspecting the innocent serving path.

Printing the raw ffprobe output side by side with what my parser thought it saw ended the mystery in about thirty seconds. The lesson was old and evergreen: when parsing tool output, log the raw input next to the parsed result, because your mental model of the format is a hypothesis, not a fact.

With the parser reading fields in the right order, the probe correctly flagged VP9, the pipeline re-encoded to H.264/AAC with faststart, and the same share link played on the same iPhone immediately.

The durable wins:

Not the fix itself, which is twenty lines. It is that the debugging held discipline when the evidence was contradictory: the server was provably healthy AND the file provably did not play. Instead of picking a side and flailing, following the contradiction down one more layer found the third option nobody was accusing, the codec inside a truthful container.

Also, mild pride in having personally shipped, broken, and re-shipped the fix within the same day, which is the full solo founder experience in miniature.

── more in #ai-products 4 stories · sorted by recency
── more on @snipforge.video 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/the-video-that-playe…] indexed:0 read:4min 2026-08-15 ·