Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC Video streaming to mobile web browsers

I want to stream a video from my Azure blob via a ASP.NET MVC web application to users on desktop browsers and of course mobile browsers.

I have build so far is a ASP.NET MVC Application that serves the website and a WebApi service that would PushStreamContent. This works awesome on Chrome and Edge on the desktop. But when I try to open it on a mobile device Chrome, Safari, Firefox it just wont play.

My Code so far:

The view on the MVC project

<video id="vPlayer" class="video-js" autoplay controls playsinline preload="auto" data-setup='{"fluid": true}'poster="@ImgManager.GetVideoImgUrl(Model.ThumbnailUrl)">
<source src="//xyz.nl/api/Videos/Get?filename=340a85a3-ccea-4a2a-bab6-74def07e416c.webm&type=video%2Fwebm" type="video/webm">
<source src="//xyz.nl/api/Videos/Get?filename=340a85a3-ccea-4a2a-bab6-74def07e416c.mp4&type=video%2Fmp4" type="video/mp4">

The WebApi

public HttpResponseMessage Get(string filename, string type)
        {
            var video = new VideoStream(filename);
            var response = Request.CreateResponse();

            response.Content = new PushStreamContent(video.WriteToStream, new MediaTypeHeaderValue(type));

            return response;
        }

Helper on webAPI

public class VideoStream
    {
        private readonly string _filename;

        public VideoStream(string fileName)
        {
            _filename = fileName;
        }



        public async Task WriteToStream(Stream outputStream, HttpContent content, TransportContext context)
        {
            try
            {
                var storage = new AzureMainStorage("avideo");
                byte[] file = await storage.GetFileAsync(_filename);

                var buffer = new byte[65536];

                using (var video = new MemoryStream(file))
                {
                    var length = (int)video.Length;
                    var bytesRead = 1;

                    while (length > 0 && bytesRead > 0)
                    {
                        bytesRead = video.Read(buffer, 0, Math.Min(length, buffer.Length));
                        await outputStream.WriteAsync(buffer, 0, bytesRead);

                        length -= bytesRead;
                    }
                }
            }
            catch (HttpException ex)
            {
                Utilities.LogErrorToDb(ex);
                return;
            }
            finally
            {
                outputStream.Close();
            }

        }

    }
}
like image 734
Ivo Oostwegel Avatar asked Oct 30 '22 07:10

Ivo Oostwegel


1 Answers

So after some time trying different stuff i dumpt in to this article from Microsoft witch solved my problem perfectly. Link to article

Here is the code that worked for me:

public HttpResponseMessage Get(string filename, string type)
{
     MemoryStream stream = new MemoryStream(new AzureMainStorage("avideo").GetFile(filename));

     HttpResponseMessage partialResponse = Request.CreateResponse(HttpStatusCode.PartialContent);
     partialResponse.Content = new ByteRangeStreamContent(stream, Request.Headers.Range, "video/mp4");
     return partialResponse;  
}
like image 146
Ivo Oostwegel Avatar answered Nov 15 '22 07:11

Ivo Oostwegel