从数据库中流式传输asp.net web api中的视频

时间:2018-02-05 13:33:06

标签: c# asp.net html5

我想通过asp.net web api控制器从数据库中流式传输视频。我已经从我的服务器中的静态文件(代码下面)完成了,但我无法完成数据库模式。 这是我的代码(我通过网络搜索得到的)

public class VideosController : ApiController
{
    // GET api/values
    public HttpResponseMessage Get(string filename)
    {
        var filePath = HttpContext.Current.Server.MapPath("~") + filename;
        if (!File.Exists(filePath))
            return new HttpResponseMessage(HttpStatusCode.NotFound);

        var response = Request.CreateResponse();
        response.Headers.AcceptRanges.Add("bytes");

        var streamer = new FileStreamer();
        streamer.FileInfo = new FileInfo(filePath);
        response.Content = new PushStreamContent(streamer.WriteToStream, "video/mp4");

        RangeHeaderValue rangeHeader = Request.Headers.Range;
        if (rangeHeader != null)
        {
            long totalLength = streamer.FileInfo.Length;
            var range = rangeHeader.Ranges.First();
            streamer.Start = range.From ?? 0;
            streamer.End = range.To ?? totalLength - 1;

            response.Content.Headers.ContentLength = streamer.End - streamer.Start + 1;
            response.Content.Headers.ContentRange = new ContentRangeHeaderValue(streamer.Start, streamer.End,
                totalLength);
            response.StatusCode = HttpStatusCode.PartialContent;
        }
        else
        {
            response.StatusCode = HttpStatusCode.OK;
        }
        return response;
    }


    class FileStreamer
    {
        public FileInfo FileInfo { get; set; }
        public long Start { get; set; }
        public long End { get; set; }

        public async Task WriteToStream(Stream outputStream, HttpContent content, TransportContext context)
        {
            try
            {
                var buffer = new byte[65536];
                using (var video = FileInfo.OpenRead())
                {
                    if (End == -1)
                    {
                        End = video.Length;
                    }
                    var position = Start;
                    var bytesLeft = End - Start + 1;
                    video.Position = Start;
                    while (position <= End)
                    {
                        // what should i do here?
                        var bytesRead = video.Read(buffer, 0, (int)Math.Min(bytesLeft, buffer.Length));
                        await outputStream.WriteAsync(buffer, 0, bytesRead);
                        position += bytesRead;
                        bytesLeft = End - position + 1;
                    }
                }
            }
            catch (Exception ex)
            {
                // fail silently
            }
            finally
            {
                outputStream.Close();
            }
        }
    }
}

这是我的HTML代码:

    <video width="640" height="480" controls="controls">
        <source src="/api/Videos/?filename=sample.mp4" type="video/mp4">
    </video>

有一种方法可供我(由其他人编写)从引擎(数据库)获取一系列文件,其代码如下:

public byte[] Engine.DownloadStreamFile(Guid fileId, long from, long length)

我试图从这个方法读取并写入响应输出流,但我不能。似乎我无法处理从谷歌浏览器接收的。有什么想法吗?

1 个答案:

答案 0 :(得分:1)

根据您提供的信息,并假设您的Engine类中的方法执行人们认为它通过名称和签名执行的操作,您应该尝试使用您的Engine.DownloadStreamFile方法替换文件系统内容:

// what should i do here?
var bytesRead = video.Read(buffer, 0, (int)Math.Min(bytesLeft, buffer.Length));
// becomes
var bytesRead = Engine.DownloadStreamFile(this.fileId, this.Start, this.End);

您显然需要向您的类添加fileId字段/属性,而不是今天的FileInfo。