Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
381 views
in Technique[技术] by (71.8m points)

video - How to set content disposition on individual azure blob requests?

I have an application that hosts videos, and we recently migrated to Azure.

On our old application we gave the ability for users to either play or download the video. However on Azure it seems like I have to pick between which functionality I want, as the content disposition has to be set on the file and not on the request.

So far I have came up with two very poor solutions.

The first solution is streaming the download through my MVC server.

CloudStorageAccount storageAccount = CloudStorageAccount.Parse(ConfigurationManager.AppSettings["StorageConnectionString"]);
                        CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
                        CloudBlobContainer container = blobClient.GetContainerReference("videos");
                        string userFileName = service.FirstName + service.LastName + "Video.mp4";
                        Response.AddHeader("Content-Disposition", "attachment; filename=" + userFileName); // force download
                        container.GetBlobReference(service.Video.ConvertedFilePath).DownloadToStream(Response.OutputStream);
                        return new EmptyResult();

This option works okay for smaller videos, but it is very taxing on my server. For larger videos the operation times out.

The second option is hosting every video twice.

This option is obviously bad, as I will have to pay double the storage cost.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

However on Azure it seems like I have to pick between which functionality I want, as the content disposition has to be set on the file and not on the request.

There's a workaround for that. As you may know there's a Content-Disposition property that you can define on a blob. However when you define a value for this property, it will always be applied on that blob. When you want to selectively apply this property on a blob (say on a per request basis), what you do is create a Shared Access Signature (SAS) on that blob and override this request header there. Then you can serve the blob via SAS URL.

Here's the sample code for this:

        CloudStorageAccount storageAccount = CloudStorageAccount.Parse(ConfigurationManager.AppSettings["StorageConnectionString"]);
        CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
        CloudBlobContainer container = blobClient.GetContainerReference("videos");
        string userFileName = service.FirstName + service.LastName + "Video.mp4";
        CloudBlockBlob blob = container.GetBlockBlobReference(userFileName);
        SharedAccessBlobPolicy policy = new SharedAccessBlobPolicy()
        {
            Permissions = SharedAccessBlobPermissions.Read,
            SharedAccessExpiryTime = DateTime.UtcNow.AddHours(1)
        };
        SharedAccessBlobHeaders blobHeaders = new SharedAccessBlobHeaders()
        {
            ContentDisposition = "attachment; filename=" + userFileName
        };
        string sasToken = blob.GetSharedAccessSignature(policy, blobHeaders);
        var sasUrl = blob.Uri.AbsoluteUri + sasToken;//This is the URL you will use. It will force the user to download the video.

I wrote a blog post about the same long time ago that you may find useful: http://gauravmantri.com/2013/11/28/new-changes-to-windows-azure-storage-a-perfect-thanksgiving-gift/.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...