Hi everyone,
I'm making a website which uses ASP.NET Core as a back-end for video/audio streaming.
VideoController.cs
public class VideoController: Controller { // Singleton registered at Startup.cs private readonly IStreamingService _streamingService; private readonly IHostingEnvironment _hostingEnvironment; public VideoController(IStreamingService streamingService, IHostingEnvironment hostingEnvironment) { _streamingService = streamingService; _hostingEnvironment = hostingEnvironment; } [HttpGet("initiate")] public IActionResult Initiate() { _streamingService.Connections.Add(Response.Body); } [HttpPost("broadcast")] public async Task<IActionResult> Broadcast() { // Retrieve data submitted from POSTMAN. var data = _streamingService.AnalyzeStream(Request.Body); foreach (var stream in _streamingService.Connections) { try { await stream.WriteAsync(data, 0, data.Length); } catch (Exception exception) { stream.Dispose(); _streamingService.Connections.Remove(stream); } } } }
StreamingService.cs
public class StreamingService: IStreamingService { public IList<Stream> Connections {get;set;} public StreamingService() { Connections = new List<Stream>(); } // Read all bytes from stream. public byte[] AnalyzeStream(Stream stream) { long originalPosititon = 0; if (stream.CanSeek) { originalPosititon = stream.Position; stream.Position = 0; } try { var readBuffer = new byte[4096]; int bytesReader; while ((byteRead = stream.Read(readBuffer, totalBytesRead, readBuffer.Length - totalBytesRead)) > 0) { totalBytesRead += byteRead; if (totalBytesRead == readBuffer.Length) { var nextByte = stream.ReadByte(); if (nextByte != -1) { var temp = new byte[readBuffer * 2]; Buffer.BlockCopy(readBuffer, 0, temp, 0, readBuffer.Length); Buffer.SetByte(temp, totalBytesRead, (byte)nextByte); readBuffer = temp; totalBytesRead++; } } } var buffer = readBuffer; if (readBuffer.Length != totalBytesRead) { buffer = new byte[totalBytesRead]; Buffer.BlockCopy(readBuffer, 0, buffer, 0, totalBytesRead); } return buffer; } finally { if (stream.CanSeek) stream.Position = originalPosititon; } } }
Index.cshtml
<div><video width="480" height="320" controls="controls" autoplay="autoplay"><source src="/api/video/initiate" type="video/mp4"></source></video></div>
In VideoController.cs, when I called
await stream.WriteAsync(data, 0, data.Length);
I got an exception which told me the stream has been disposed.
My question is :
- How can I keep the connection alive as long as the web browser opens, and close the stream after a long time of idling. (Stream on demand)
Thank you,
P/S; I've read some tutorials about streaming on ASP.NET, most of them are about streaming a static file back to client, but I want to stream from mobile devices.