How do I stream a video file using ASP.NET MVC?

33,920

The File method of MvcController returns a FileContentResult. The latter does not stream the content. As far as I'm aware, MvcController does not support streaming at all.

You may want to try ApiController and PushStreamContent. The latter gives the possibility to asynchronously write to the output stream via a callback method. You'll need to work with actual streams in your solution for that. Working with byte[] will always load the whole file content into memory.

See a detailed tutorial here:Asynchronously streaming video with ASP.NET Web API

Share:
33,920
Avrohom Yisroel
Author by

Avrohom Yisroel

I'm a self-employed programmer with far too much interest in learning new things that I'll probably never have chance to use in real life. My day job consists of pulling data from a database, displaying it on a window, waiting for the user to make some edits and then saving the data back into the database. Sound familiar? If I'm lucky, I get to generate a report or send an email along the way. Pardon me while I yawn. My out-of-work activities involve trying to get my head around the sort of stuff I'd really like to do for a job, like machine learning, natural algorithms and so on. I dabble in these, occasionally post some ramblings on my blog (that no-one reads, so I can post what I like). I'm a huge fan of Linq, and have been trying to expand my horizons by learning some less C-like languages, such as Racket (LISP) and F#. Out of work hours, I like tickling my children (I have lots to tickle!), growing carnivorous plants and studying ancient legal texts.

Updated on September 14, 2020

Comments

  • Avrohom Yisroel
    Avrohom Yisroel over 3 years

    I am developing a web site where people can access audio and video files. I have the code for downloading the files, which consists of two action methods as follows...

    public ActionResult GetAudioFile(int id) {
      return GetFile(id, true);
    }
    
    public ActionResult GetVideoFile(int id) {
      return GetFile(id, false);
    }
    
    private ActionResult GetFile(int id, bool isAudio) {
      // Code to get info about the file, etc omitted for clarity
      string downloadFileName = // full path to audio/video file
      byte[] bytes = GetFileBytes(fileName); // also omitted
      return File(bytes, (isAudio ? "audio/mpeg" : "video/mp4"), downloadFileName + (isAudio ? ".mp3" : ".mp4"));
    }
    

    These both work fine, and I can download either type of file.

    I now want to add two Razor views, one for listening to the audio file, and one for viewing the video. I did the following on the audio view, and it works fine...

    <audio src='@Url.Action("GetAudioFile", "Search", new {ID = @Model.ID})'
                   controls preload="auto"></audio>
    

    I then tried to do the same for the video view...

    <video src='@Url.Action("GetVideoFile", "Search", new {ID = @Model.ID})' 
                   controls preload="auto" width="640" height="368"></video>
    

    However, this gives a System.OutOfMemoryException when I try to run it. The videos average around 400-500Mb each.

    I then tried using the Response.TransmitFile method as follows...

      Response.ContentType = "video/mp4";
      Response.AddHeader("content-disposition", "attachment; filename=myvideo.mp4"));
      Response.TransmitFile(fileName);
      Response.End();
      return null;
    

    ...but that doesn't work. In Chrome, I can see the message "Resource interpreted as Document but transferred with MIME type video/mp4" in the console, and in FireFox, I get the same message in the video control.

    Anyone any idea how I can fix this? Ideally, I would like to stream the file, so that it starts playing as soon as the first bytes reach the user, rather than having them wait until the file is completely downloaded.

    I've tried a couple of Javascript video players, but had any success with those either.

    Update I'm wondering if it's not the controller action that's the problem at all, as I tried pointing my web browser directly at the video file, and I got what looked like an audio player, but without a video pane, and nothing happens when I click the play button. Not sure if that helps.