简体   繁体   中英

Streaming videos with ASP.NET Core 3

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 (eg 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?

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).

dont forget than pyshicalfile return too partial content look

link

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM