Jeremy Keith writes of issues with Safari, video and service workers, and in doing so helped to solve a perplexing mystery for me: a while ago I noticed that videos I posted here, like, say, the one in this post, would no longer play in Safari. Firefox, Chrome, Brave, and everything else I tried, played the video. But not Safari.
It turns out that a combination–fortuitously the same combination Jeremy encountered–of videos hosted on Amazon S3, service workers, and Safari causes an issue with the video playback. Jeremy pointed to this post from Phil Nash that got to the bottom of the issue:
Some time passes and you deploy a video to your site. Everything is still working well in Chrome, in Firefox, in Edge. You check Safari. The video is broken. You don’t know what’s gone wrong.
I first thought it could have something to do with the CDN I’m using. There were some false positives regarding streaming video through a CDN that resulted in some extra research that was ultimately fruitless. Once I’d exhausted that line of inquiry I went back to the failing request.
Observing the request in Safari’s inspector lead to further trawling the internet and eventually things started to add up. Safari was sending an initial request to fetch the video with a Range header set to bytes=0-1. You see, Safari requires HTTP servers that are serving video and audio to support Range requests like this.
The solution Jeremy suggested–instructing the service worker to ignore MP4 files–was one easily implemented here in Drupal, where I’m using the Progressive Web App module: on the service worker settings page (/admin/config/system/pwa/serviceworker), add this pattern to the “Exclude URL patterns” field:
Bump up the “Cache version” field at the bottom of the settings by one, flush the Drupal cache for good measure and, ta-da, videos now play in Safari.