简体   繁体   中英

Stream videos from Azure blob storage and ASP.NET Core 3

I'm using latest and recommended Azure.Storage.Blobs package. I'm uploading the video file as chunks, which works fine. The problem is now returning back the video to the web client, which is videojs . The player is using Range request.

My endpoint:

[HttpGet]
[Route("video/{id}")]
[AllowAnonymous]
public async Task<IActionResult> GetVideoStreamAsync(string id)
{
   var stream = await GetVideoFile(id);

   return File(stream, "video/mp4", true); // true is for enableRangeProcessing
}

And my GetVideoFile method

var ms = new MemoryStream();
await blobClient.DownloadToAsync(ms, null, new StorageTransferOptions
{
    InitialTransferLength = 1024 * 1024,
    MaximumConcurrency = 20,
    MaximumTransferLength = 4 * 1024 * 1024
});

ms.Position = 0;

return ms;

The video gets downloaded and streamed just fine. But it downloads the whole video and not respecting Range at all. I've also tried with DownloadTo(HttpRange)

var ms = new MemoryStream();

// parse range header... 
var range = new HttpRange(from, to);
BlobDownloadInfo info = await blobClient.DownloadAsync(range);
await info.Content.CopyToAsync(ms);
return ms;

But nothing gets displayed in the browser. What is the best way to achieve that?

Answering my own question if someone comes across.

CloudBlockBlob (version I'm using: 11.2.2) now has OpenReadAsync() method which returns stream. In my case I'm returning this stream to videojs which handles the Range header on its own.

Please try by resetting the memory stream's position to 0 before returning:

var ms = new MemoryStream();

// parse range header... 
var range = new HttpRange(from, to);
BlobDownloadInfo info = await blobClient.DownloadAsync(range);
await info.Content.CopyToAsync(ms);
ms.Position = 0;//ms is positioned at the end of the stream so we need to reset that.
return ms;

I believe it's not possible to achieve it only using Azure Blob. More info in here: https://stackoverflow.com/a/26053910/1384539

but in summary, you can use a CDN that offers the Seek Start / End position: https://docs.vdms.com/cdn/re3/Content/Streaming/HPD/Seeking_Within_a_Video.htm

Another possibility is to use Azure Media Services that supports streamming. Your approach is actually a progressive download which is not exactly the same idea, and you'd probably spend a lot with network out. (assuming you have many access to the same file)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM