Last active
March 6, 2021 11:44
-
-
Save JeepNL/6a2bedf2be753aebc949549d40cf435e to your computer and use it in GitHub Desktop.
Stream video in chunks to client. Server controller in a Kestrel hosted Blazor WASM ASP.NET Core 6 preview 1 / C# 9 project
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Microsoft.AspNetCore.Hosting; | |
using Microsoft.AspNetCore.Mvc; | |
using Microsoft.Extensions.FileProviders; | |
using Microsoft.Extensions.Logging; | |
using System; | |
using System.IO; | |
using System.Threading.Tasks; | |
namespace Media.Server.Controllers | |
{ | |
[Route("[controller]")] | |
public class StreamController : ControllerBase | |
{ | |
private readonly IWebHostEnvironment env; | |
private readonly ILogger<StreamController> logger; | |
public StreamController(ILogger<StreamController> logger, IWebHostEnvironment env) | |
{ | |
this.logger = logger; | |
this.env = env; | |
} | |
[HttpGet("{file}")] | |
public async Task GetStream(string file) | |
{ | |
var provider = new PhysicalFileProvider(env.ContentRootPath); | |
string videoPathFile = Path.Combine(provider.Root, "Files", "Videos", $"{file}"); | |
byte[] buffer = new byte[1024 * 1024 * 4]; // 'Chunks' of 4MB | |
long startPosition = 0; | |
if (!string.IsNullOrEmpty(Request.Headers["Range"])) | |
{ | |
string[] range = Request.Headers["Range"].ToString().Split(new char[] { '=', '-' }); | |
startPosition = long.Parse(range[1]); | |
} | |
using FileStream inputStream = new(videoPathFile, FileMode.Open, FileAccess.Read, FileShare.Read) | |
{ | |
Position = startPosition | |
}; | |
//using FileStream inputStream = fileStream; | |
int chunkSize = await inputStream.ReadAsync(buffer.AsMemory(0, buffer.Length)); | |
long fileSize = inputStream.Length; | |
if (chunkSize > 0) | |
{ | |
Response.StatusCode = 206; | |
Response.Headers["Accept-Ranges"] = "bytes"; | |
Response.Headers["Content-Range"] = string.Format($" bytes {startPosition}-{fileSize - 1}/{fileSize}"); | |
Response.ContentType = "application/octet-stream"; | |
using Stream outputStream = Response.Body; | |
await outputStream.WriteAsync(buffer.AsMemory(0, chunkSize)); | |
}; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment