Azure Blobs is a great, inexpensive, and scalable cloud storage service that you can use to host any static file. In particular, I find it extremely useful for hosting progressive download videos (e.g. .mp4 files). Note: if you need the uber-solution (encoding, adaptive streaming, …etc) check out Windows Azure Media Services which offers a full range of services to deliver high quality video to a range of different platforms.
While Azure Blobs is very easy to setup and manage, there’s one essential configuration setting you will want to change before serving progressive download video that isn’t so obvious: byte-range support.
Let’s start with the problem. Out of the box, if you throw a .mp4 file on your Azure Blobs container and point your video player at the video, you’ll see the video play and buffer just fine. But, what happens, when you try to seek to an unbuffered portion of the content?
Result: Buffering, waiting, annoyance, time for a coffee break?
The reason is simple: by default, Azure Blobs does not enable support for byte range requests. Described with less jargon: in order to jump to a portion of the video that hasn’t downloaded yet you can either:
1) wait until the download (buffer) catches up to the new position of playback (results seen above) or
2) the solution: tell the server to skip all the data yet to be buffered prior to the new position (identified below in red) and instead start buffering from the new position.
Under the hood, this is supported automatically by most modern video players AS LONG AS the server serving the video supports returning byte ranges and returns the response header: “Accept-Ranges: bytes”
The good news is, Azure Blobs does support this, you just need to enable it by setting the default version of the service to a newer one.
So how do it change it? Send a Set Blob Service Properties REST API request.
Seriously? Isn’t there an easier way? Well, there are free tools out there to do this for you. For example: Plasma AzureBlobUtility.
BlobUtility.exe -k AccessKey -a AccountName -c ContainerName --setDefaultServiceVersion 2012-02-12
Or, if you’re paranoid like me and don’t like to give the key to your house to a stranger (no offense Plasma). Here are the steps and code to do it yourself in VS2012 in <1 minute:
Create a new C# project. (I chose a WPF application which is probably not the best choice but I’m just going to throw this away when I‘m done).
Add a NuGet package for Azure Storage by right clicking on your project and choosing Manage NuGet Packages.
Search for “azure storage” and install the “Windows Azure Storage” NuGet Package by Microsoft.
Finally, add the following code to your app, replace the account name and secret key for your Azure Blobs account and run it…
var credentials = new StorageCredentials("myaccountname", "mysecretkey");
var account = new CloudStorageAccount(credentials, true);
var client = account.CreateCloudBlobClient();
var properties = client.GetServiceProperties();
properties.DefaultServiceVersion = "2012-02-12";
Notice that we didn’t need to specify the container. This change will apply to all containers for that account.
DONE! Now all videos served from your Azure Blobs account will support seeking into the unbuffered area of the video without significant delay.