I recently had a project where I needed to stream video content from an Azure Blob Storage account. Should be easy enough right? Just plonk a <video>
tag in and point it to the Blob URL (the blobs are publicly accessible). Well, it wasn't quite so straightforward. Here are some gotchas that might help you if you need to do something similar.
Why are we waiting?
For my first naïve attempt, a <video>
tag pointing to the Blob URL, it turned out it was trying to download the complete video file first before playing, and the videos I wanted to stream were too large for that to be acceptable.
Full video download took 43 seconds, not great...
For streaming, the request needs to specify a range of data at a time instead of the entire video. This is supported via the Accept-Ranges
HTTP header which returns a HTTP 206 Partial Content response. Support for this didn't come in until version '2011-08-18' of the Azure Storage service which is why the entire file was being downloaded first. You can specify the version when using an SDK or the REST API (via the x-ms-version
header), but for public anonymous access where I wanted to point a <video>
tag at a URL, this wasn't an option.
Set a global default version
Instead, you can set the default version globally at the account level using either one of the SDKs or the 'Set Blob Service Properties' REST API method. This is the part that probably isn't explained fully in the docs, particularly for public anonymous access, although it is hinted at here. Make a REST/SDK call setting the version to 2011-08-18
or later and your storage account will now support range requests and streaming will work as expected.
blobServiceClient.setProperties({
defaultServiceVersion: "2021-04-10"
})
.then(res => console.log("Set Properties response", res))
.catch(err => console.error("Set Properties error", err));
How to set the default service version via the JavaScript SDK.
With the correct default storage version set, the video can start playing immediately (note the response status code for the video).
Note: To set the default version you will probably need a
PUT
CORS rule on your storage account and a role assignment for the identity making the call.Storage Account Contributor
should do the trick.
Bonus: The partial content response will also let your users scrub the video.
Content Type
Another gotcha to be aware of is to make sure your blobs' content types are set correctly. This is usually set appropriately during upload but ensure it is a video/...
type and hasn't defaulted to something like application/octet-stream
.
Top comments (2)
Thanks for the article!
Here's how you can do this with
az cli
andcurl
:I'd appreciate a code snippet of a working demo. Haven't found one online yet