Hello!
The task is as follows:
- 1 - there is a video file on the server;
- 2 - the administrator starts it to play (the video broadcast starts);
- 3 - users connected to the server - should be given a stream of video that is currently playing. Live broadcast in real time.
To accomplish this task, I tried the option: http://www.strathweb.com/2013/01/asynchronously-streaming-video-with-asp-net-web-api/ It worked. Gave the video file stream independently and in parallel. I searched further.
Next, it was necessary to solve the problem of broadcasting to several clients (point 3 in the assignment). I took this article: http://gigi.nullneuron.net/gigilabs/streaming-data-with-asp-net-web-api-and-pushcontentstream/
Since I need to give the video data in byte - I replaced the class StreamWriter with Stream. This works for one first client.
I made the site Asp.Net WebForms + WebApi + HTML5. Web site - to run the video administrator and view users. WebApi gives to the player (HTML5) a video stream.
HTML5:
<video> <source src="http://localhost:8080/SiteVideoStreaming/api/live/?filename=nameFile" /> </video> WebApi:
public class LiveController : ApiController { private static ConcurrentBag<Stream> clients; // Список клиентов, которым надо одновременно отдавать видео данные static string fileName = ""; static LiveController() { clients = new ConcurrentBag<Stream>(); WriteToStream(); // Первое обращение - запуск видео файла на воспроизведение } [HttpGet] public HttpResponseMessage Subscribe(string filename) { fileName = HostingEnvironment.MapPath("~/Videos/") + filename; var response = Request.CreateResponse(); response.Content = new PushStreamContent((a, b, c) => { OnStreamAvailable(a, b, c); }, "video/mp4"); return response; } private void OnStreamAvailable(Stream stream, HttpContent content, TransportContext context) { clients.Add(stream); // Add new client } //Класс записи видео файла в поток public async static void WriteToStream() { var buffer = new byte[65536]; using (var video = File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.Read)) { var length = (int)video.Length; var bytesRead = 1; while (length > 0 && bytesRead > 0) { bytesRead = video.Read(buffer, 0, Math.Min(length, buffer.Length)); foreach (var client in clients)// Кажому клиенту отдаём видео данные { try { await client.WriteAsync(buffer, 0, bytesRead);// ERROR - здесь ошибка!!! await client.FlushAsync(); } catch (Exception ex) { Stream ignore; clients.TryTake(out ignore); } } length -= bytesRead; } } } } If the request first came from a single client - the video is given away, it works. If a second client connects - when you try to start sending a stream, an error occurs. At that, the connection of the first client drops.
The error is this:
[System.Web.HttpException] = {"The remote host terminated the connection. Error code: 0x800704CD."}
As I understand it after searching on the Internet is:
0x800704CD "An operation was attempted on a nonexistent network connection." An attempt was made to perform an operation for a non-existent network connection.
Assuming the browser or player breaks the connection, or does the PushStreamContent class itself support more than one connection?
Tell me what am I doing wrong? Thank.