Streaming videos with ASP.NET Core 3

24,652

If you want to stream the video in the browser, your server should support HTTP range requests. In such case, the server is able to send just a small portion of a content requested by the client. As you want to stream video in the browser, you can use video html tag that requests for a content using range headers. Therefore you can also skip some time and immediately play the movie from that position, before it is completely downloaded.

ASP.NET Core 3 already has support for HTTP range requests, it is implemented in PhysicalFile method which has attribute enableRangeProcessing. As documentation says:

Returns the file specified by physicalPath (Status200OK), the specified contentType as the Content-Type, and the specified fileDownloadName as the suggested file name. This supports range requests (Status206PartialContent or Status416RangeNotSatisfiable if the range is not satisfiable).

[Route("getFileById")]
public FileResult getFileById(int fileId)
{
    ...
    return PhysicalFile($"C:/movies/{file.Name}", "application/octet-stream", enableRangeProcessing: true);
}

Note that the path have to be absolute (not relative).

Share:
24,652

Related videos on Youtube

Lukas Köhler
Author by

Lukas Köhler

Updated on May 28, 2020

Comments

  • Lukas Köhler
    Lukas Köhler almost 4 years

    I'm currently building a API in ASP.NET Core 3 as my first project with .NET Core.

    I'm currently trying to send a video to my React.js frontend to watch it in the browser. Uploading files and videos does work without a problem and the method you see down below also already sends a file to the client but if the video is longer than a few seconds, the video player is really slow and it also takes a long time to skip a few seconds of the video. I think that's because the file is first completely downloaded and than played.

    [Route("getFileById")]
    public FileResult getFileById(int fileId)
    {
    
        var context = new DbContext();
    
        var file = context.File.Find(fileId);
    
        if (file == null)
        {
            Console.WriteLine("file " + fileId + " not found");
            return null;
        }
    
        var content  = new FileStream(file.Name, FileMode.Open, FileAccess.Read, FileShare.Read);
        var response = File(content, "application/octet-stream");
        return response;
    }
    

    I think the way to solve my problem is to stream the file and not to send it as a whole. I've already googled on how to stream videos with ASP.NET Core 3 but I only find websites explaining it for ASP.NET Core 2 (e.g. http://anthonygiretti.com/2018/01/16/streaming-video-asynchronously-in-asp-net-core-2-with-web-api/)

    I've already tried to use the code on these websites but the way they've done it is not compatible to ASP.NET Core 3.

    How can I stream files in ASP.NET Core 3?

    • Guilherme Meinlschmiedt Abdo
      Guilherme Meinlschmiedt Abdo over 4 years
      If it is not really necessary to transfer and store those video files in your app, you could use some cloud solution like Azure Blob Storage or Azure Media Services (if you need some specific media/streaming capabilities). With Azure Blob, you could upload/download files fast and without overheading your application.
  • Lukas Köhler
    Lukas Köhler over 4 years
    I'll try that, thank your very much for your response!
  • CJH
    CJH about 3 years
    Bit late but was wondering if someone would be able to show how the stream might be consumed in the front end <video> tag?
  • Avinash Reddy
    Avinash Reddy about 3 years
    @CJH I was wondering the same . did you find anything?
  • Avinash Reddy
    Avinash Reddy about 3 years
    @Mayo How can use it in a video tag?
  • Mayo
    Mayo about 3 years
    @AvinashReddy You should add <source> tag with src attribute that points to that endpoint, e.g. <source src="api/[controllerName]/getFileById" type="video/mp4" />
  • Avinash Reddy
    Avinash Reddy about 3 years
    @mayo how can we pass jwt token? .the video api is secured by token
  • Mohan Raj Raja
    Mohan Raj Raja about 2 years
    but when we returning the file stream to controller from several business layers, what could be the return type of those methods
  • Mayo
    Mayo about 2 years
    @MohanRajRaja You can use PhysicalFileResult