DEV Community

Peter O'Connor
Peter O'Connor

Posted on

Streaming Videos from Azure Blob Storage

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.

first attempt network response

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));
Enter fullscreen mode Exit fullscreen mode

How to set the default service version via the JavaScript SDK.

streaming network response

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.

Further Info

Top comments (2)

Collapse
 
ivanfedotov profile image
Ivan Fedotov • Edited

Thanks for the article!
Here's how you can do this with az cli and curl:

token=$(az account get-access-token --resource "https://storage.azure.com/" -o tsv --query accessToken)

curl -X PUT \
     -H "authorization: bearer $token" \
     -H "x-ms-version: 2021-04-10" \
     -H "content-type: application/xml" \
     --data '<?xml version="1.0" encoding="utf-8"?><StorageServiceProperties><DefaultServiceVersion>2021-04-10</DefaultServiceVersion></StorageServiceProperties>' \
     "https://STORAGE_ACCOUNT.blob.core.windows.net/?restype=service&comp=properties"

Enter fullscreen mode Exit fullscreen mode
Collapse
 
schusterbraun profile image
Schuster Braun

I'd appreciate a code snippet of a working demo. Haven't found one online yet