.NET Core 2.0 Web API 用于来自 FileStream 的视频流

.NET Core 2.0 Web API for Video Streaming from FileStream

我发现了一堆示例,这些示例使用了我在我的应用程序中不可用的对象,并且似乎与我的 .NET Core web 版本不匹配 API。本质上,我正在开发一个项目,该项目将在网页上具有 <video> 标签,并希望使用来自服务器的流加载视频,而不是直接通过路径提供文件。原因之一是文件的来源可能会改变,通过路径提供服务并不是我的客户想要的。所以我需要能够打开流并异步写入视频文件。

出于某种原因,这会产生 JSON 数据,所以这是错误的。但我只是不明白我需要做什么才能将流式视频文件发送到 HTML 中的 <video> 标签。

当前代码:

[HttpGet]
public HttpResponseMessage GetVideoContent()
{
    if (Program.TryOpenFile("BigBuckBunny.mp4", FileMode.Open, out FileStream fs))
    {
        using (var file = fs)
        {
            var range = Request.Headers.GetCommaSeparatedValues("Range").FirstOrDefault();
            if (range != null)
            {
                var msg = new HttpResponseMessage(HttpStatusCode.PartialContent);
                var body = GetRange(file, range);
                msg.Content = new StreamContent(body);
                msg.Content.Headers.Add("Content-Type", "video/mp4");
                //msg.Content.Headers.Add("Content-Range", $"0-0/{fs.Length}");
                return msg;
            }
            else
            {
                var msg = new HttpResponseMessage(HttpStatusCode.OK);
                msg.Content = new StreamContent(file);
                msg.Content.Headers.Add("Content-Type", "video/mp4");
                return msg;
            }
        }
    }
    else
    {
        return new HttpResponseMessage(HttpStatusCode.BadRequest);
    }
}

HttpResponseMessage 未用作 asp.net-core 中的 return 类型,它将读取为 object 模型并在设计响应中将其序列化,就像您一样已经观察了

幸运的是,在 ASP.NET Core 2.0 中,您有

Enhanced HTTP header support

If an application visitor requests content with a Range Request header, ASP.NET will recognize that and handle that header. If the requested content can be partially delivered, ASP.NET will appropriately skip and return just the requested set of bytes. You don't need to write any special handlers into your methods to adapt or handle this feature; it's automatically handled for you.

所以现在你所要做的就是return文件流

[HttpGet]
public IActionResult GetVideoContent() {
    if (Program.TryOpenFile("BigBuckBunny.mp4", FileMode.Open, out FileStream fs)) {        
        FileStreamResult result = File(
            fileStream: fs, 
            contentType: new MediaTypeHeaderValue("video/mp4").MediaType, 
            enableRangeProcessing: true //<-- enable range requests processing
        );
        return result;
    }
     
    return BadRequest();
}

确保启用范围请求处理。但是,如文档中所述,应根据请求 headers 以及是否可以部分交付该数据来处理。

从那里开始,现在只需从视频客户端指向端点并让它施展魔法