【问题标题】:How to implement video file streaming in ASP.Net MVC?如何在 ASP.Net MVC 中实现视频文件流式传输?
【发布时间】:2017-07-07 14:06:51
【问题描述】:

我想实现简单的视频文件流。 有我的 API 控制器:

[HttpGet]
[Route("api/VideoContent")]
public HttpResponseMessage GetVideoContent([FromUri] string fileName)
{
    if (fileName == null)
    {
        return new HttpResponseMessage(HttpStatusCode.BadRequest);
    }

    if (Request.Headers.Range != null)
    {
        try
        {
            //using (FileStream fileStream = _videoFileProvider.GetFileStream(fileName))
            //{
                HttpResponseMessage partialResponse = Request.CreateResponse(HttpStatusCode.PartialContent);
                FileStream fileStream = _videoFileProvider.GetFileStream(fileName);
                partialResponse.Content = new ByteRangeStreamContent(fileStream, Request.Headers.Range, new MediaTypeHeaderValue("video/mp4"));
                return partialResponse;
            //}

        }
        catch (Exception)
        {
            return new HttpResponseMessage(HttpStatusCode.InternalServerError);
        }
    }

    return new HttpResponseMessage(HttpStatusCode.RequestedRangeNotSatisfiable);
}

此代码正在运行,但如您所见,fileStream 未处理。我尝试使用 using 块(注释行),但此代码不起作用 - 在调试模式下方法运行无异常,但浏览器显示 500 错误代码的响应。

我的错误在哪里?为什么我收到 500 内部服务器错误?在我的情况下如何正确处理文件流?

【问题讨论】:

标签: c# asp.net-mvc stream dispose


【解决方案1】:

AFAIK,你在不处理文件流的情况下下载内容是正确的。

正如您一直在使用HttpResponseMessage 来返回响应,该响应在完成向客户端发送响应后由框架本身自动处理。

这已经被MSFT guycommentanother post 中指出

如果你看HttpResponseMessage in source code的dispose方法,

        protected virtual void Dispose(bool disposing)
        {
            // The reason for this type to implement IDisposable is 
            //that it contains instances of types that implement
            // IDisposable (content). 
            if (disposing && !_disposed)
            {
                _disposed = true;
                if (_content != null)
                {
                    _content.Dispose();
                }
            }
        }

您可以看到 _content 已被处置,其类型为 HttpContent,即在您的情况下,ByteRangeStreamContent 的对象设置在 HttpResponseMessageContent 属性中。

处理ByteRangeStreamContent对象的实现方式如下:

        protected override void Dispose(bool disposing)
        {
            Contract.Assert(_byteRangeContent != null);
            if (disposing)
            {
                if (!_disposed)
                {
                    _byteRangeContent.Dispose();
                    _content.Dispose();
                    _disposed = true;
                }
            }
            base.Dispose(disposing);
        }

在上面ByteRangeStreamContentDispose 方法中,您可以看到它正在处理自己并处理_content(在您的情况下为FileStream)以及用于创建ByteRangeStreamContent 对象的流。

我坚信,您在不处理文件流的情况下的实现是正确的,因为在完成向客户端发送响应后,处理是按顺序开始的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-08-22
    • 1970-01-01
    • 1970-01-01
    • 2010-10-25
    • 2020-06-25
    • 2011-02-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多