Service workers and videos in Safari

Alright, so I’ve already talked about some gotchas when debugging service worker issues. But what if you don’t even realise the problem has anything to do with your service worker?

This is not a hypothetical situation. I encountered this very thing myself. Gather ‘round the campfire, children…

One of the latest case studies on the Clearleft site is a nice write-up by Luke of designing a mobile app for Virgin Holidays. The case study includes a lovely video that demonstrates the log-in flow. I implemented that using a video element (with a poster image). Nice and straightforward. Super easy. All good.

But I hadn’t done my due diligence in browser testing (I guess I didn’t even think of it in this case). Hana informed me that the video wasn’t working at all in Safari. The poster image appeared just fine, but when you clicked on it, the video didn’t load.

I ducked, ducked, and went, uncovering what appeared to be the root of the problem. It seems that Safari is fussy about having servers support something called “byte-range requests”.

I had put the video in question on an Amazon S3 server. I came to the conclusion that S3 mustn’t support these kinds of headers correctly, or something.

Now I had a diagnosis. The next step was figuring out a solution. I thought I might have to move the video off of S3 and onto a server that I could configure a bit more.

Luckily, I never got ‘round to even starting that process. That’s good. Because it turns out that my diagnosis was completely wrong.

I came across a recent post by Phil Nash called Service workers: beware Safari’s range request. The title immediately grabbed my attention. Safari: yes! Video: yes! But service workers …wait a minute!

There’s a section in Phil’s post entitled “Diagnosing the problem”, in which he says:

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.

That described my situation exactly. Except Phil went further and nailed down the real cause of the problem:

Nginx was serving correct responses to Range requests. So was the CDN. The only other problem? The service worker. And this broke the video in Safari.

Doh! I hadn’t even thought about service workers!

Phil came up with a solution, and he has kindly shared his code.

I decided to go for a dumber solution:

if ( request.url.match(/\.(mp4)$/) ) {
  return;
}

That tells the service worker to just step out of the way when it comes to video requests. Now the video plays just fine in Safari. It’s a bit of a shame, because I’m kind of penalising all browsers for Safari’s bug, but the Clearleft site isn’t using much video at all, and in any case, it might be good not to fill up the cache with large video files.

But what’s more important than any particular solution is correctly identifying the problem. I’m quite sure I never would’ve been able to fix this issue if Phil hadn’t gone to the trouble of sharing his experience. I’m very, very grateful that he did.

That’s the bigger lesson here: if you solve a problem—even if you think it’s hardly worth mentioning—please, please share your solution. It could make all the difference for someone out there.

Have you published a response to this? :

Responses

ruk.ca

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:

.(mp4)$

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.

# Friday, October 26th, 2018 at 3:07am

Šime Vidas

I assume, UA sniffing is out of the question 😅 let safari = !/^((?!chrome|android).)*safari/i.test(navigator.userAgent); if ( safari && request.url.match(/.(mp4)$/) ) { return; }

# Posted by Šime Vidas on Friday, October 26th, 2018 at 8:52pm

3 Likes

# Liked by Emmanuel DEMEY on Friday, October 26th, 2018 at 4:51pm

# Liked by Phil Nash on Friday, October 26th, 2018 at 8:25pm

# Liked by Mohamed Hussain on Friday, October 26th, 2018 at 8:58pm

Previously on this day

7 years ago I wrote Medieval times

Two German trips in two months.

11 years ago I wrote Talking the talk

Shooting the breeze in MP3s.

11 years ago I wrote Tears in the rain

All of these moments will be lost in time.

12 years ago I wrote </head>

A virtual conference is a real success.

13 years ago I wrote Voices that natter

Presentation: done. Conference: done.

16 years ago I wrote D'ye ken John Peel?

“Then here’s to John Peel with my? heart and soul”

18 years ago I wrote The Chimera Project

I’ve started surfing the web with a new browser. It’s called Chimera, a Mac OS X browser from Mozilla.

18 years ago I wrote Direct Marketing

Don Henley improves his street cred:

19 years ago I wrote Robohouse

Hmm… apparently I’m "Number 5, Goofy robot with life from Short Circuit".