Auto-detect or reject VP9 video uploads incompatible with iOS Safari

I recently discovered that several videos on my self-hosted Discourse forum were silently failing to play on iPhone and iPad. After investigation, the root cause was that the videos had been encoded with the VP9 codec inside an MP4 container β€” a combination that iOS Safari cannot play.

How it happens

Facebook (and possibly other platforms) sometimes delivers VP9-encoded video when users download their content. When those files are uploaded to Discourse, they are accepted without issue β€” the .mp4 extension gives no indication of the codec inside. On desktop browsers and Android the videos play fine, so the problem goes unnoticed. On iOS Safari, the video shows a thumbnail and a play button, but tapping it produces only a spinning indicator. Users typically assume it’s a network issue and move on without reporting it.

Why it’s hard to catch

  • The file extension (.mp4) is identical to a working H.264 file
  • Desktop browsers support VP9, so admins testing on desktop see no problem
  • iOS users often don’t report individual media failures, especially when other content in the same post is visible and playable
  • There is no admin-facing warning or error

Suggested resolution

On video upload, Discourse could inspect the video codec (ffprobe is already available in the Docker container) and either:

  1. Reject the upload with a clear message explaining that VP9 is not supported on iOS, and asking the user to re-encode to H.264, or
  2. Automatically transcode the video to H.264 on upload (similar to how some platforms normalize uploads)

Option 1 is lower complexity and would already be a significant improvement. Option 2 would be ideal for a seamless user experience.

Environment

  • Self-hosted Discourse in Docker, local storage (no S3)
  • Discourse version: 2026.4.0-latest
  • Apache reverse proxy in front of Discourse nginx

Workaround

For admins who encounter this, the fix involves:

  1. Identifying VP9 files with ffprobe
  2. Re-encoding to H.264 with ffmpeg -c:v libx264 -profile:v main -level 3.1 -r 30 -movflags +faststart
  3. Updating the sha1, url, filesize in the uploads table
  4. Updating upload:// short URL tokens in affected post raw markdown
  5. Rebaking affected posts

This is a non-trivial manual process that most forum admins would not be equipped to perform.

1 Like

For automatic transcoding you can check Discourse Video Stream :movie_camera:.

Automatic local transcoding works, but delivering that in a way that is safe for most setups is the main issue.

2 Likes

Thanks for the pointer to the Video Stream plugin, @Falco. For a small enthusiast forum like mine, adding a dependency on a paid third-party service feels like more than the problem warrants β€” though I can see the appeal for higher-traffic sites with heavy video usage.

Your note about local transcoding is interesting. I manually ran ffmpeg on the 9 affected files on my VPS during the fix process, and the server handled it without issue. I understand the concern about doing this synchronously during upload β€” CPU spikes, timeouts, and disk pressure are all real risks. But would an asynchronous background job approach address most of those concerns? The upload completes normally, and the transcode happens in a queued job afterward β€” similar to how Discourse already handles image thumbnailing. The video would simply not be playable on iOS until the job completes, which seems like an acceptable tradeoff.

Even short of full transcoding, a lighter-weight option β€” detecting VP9 on upload and either rejecting it with a clear error message or flagging it in the admin panel β€” would go a long way for self-hosted admins who may not have the technical background to diagnose silent iOS playback failures.

1 Like

Video is a bit more complicated, as there are so many ways a user could maliciously upload something to hog the CPU, especially in the many 1vCPU self-hosted instances.

I can try to explore a plugin here, so it becomes an option that the admin can reach to only if they are happy with the trade-offs.

3 Likes