The Weird Case of Streaming in Safari
June 25, 2021, posted in Programming · 1 min read
Last week I had the pleasure of having to write some code in order to get Safari to stream video. There are plenty of other valuable blog posts out there explaining how to do it. But the gist of it is to support the Range header, and to make sure the url ends with an extension.
Returning partial content through HTTP
Basically the Range
header is a way for the browser to tell our server how much of a resource it wants.
The server in turn responds with status 206 partial content,
with more headers telling the browser how much content is left to be consumed.
Safari won’t render a video unless we support partial content response, in fact we can see that Safari actually tests us.
You can see that safari splits the request for the video resource into two. The first requests only requests the first 2 bytes, if we fail to respond with 206 Safari will not render the video.Although my server responded correctly, Safari still won’t play the video.
Content type and Safari
I couldn’t figure out what was wrong. The video was obviously formatted correctly, because when I just link to the file locally it would play. The Content-Type was correct, so was the type attribute.
Then I tried to add a file extension, I was out of ideas, I changed the route from /video
to
/video.webm
and it worked! Apparently Safari checks three things in order to determine the type
of a resource to be a video. The type attribute must match the Content-Type
header, and the url
must end with a matching extension.
Conclusion
Safari doesn’t follow the path of other browsers when it comes to streaming videos, in order to get videos to stream on Safari make sure to follow these guidelines
- Support 206 partial content
- Return the correct
Content-Type
header andtype
attribute - Add a matching file extension to the video
src
URL
A working WebM example can be found here, cheers!
Tomer Steinfeld writes code for a living. Currently works on Selenium IDE and other opensource projects.