在asp.net core 2中流式传输视频文件

时间:2018-07-14 11:47:52

标签: asp.net-core-2.0 filestream memorystream

我想使用asp.net core在浏览器中播放视频

在html中,我有

<video width="320" height="240" controls>
 <source src="http://localhost:55193/api/VideoPlayer/Download" type="video/mp4">
 Your browser does not support the video tag.
</video>

和asp.net核心2

    [HttpGet]
    [Route("Download")]
    public async Task<IActionResult> Download()
    {
        var path = @"d:\test\somemovie.mp4";
        var memory = new MemoryStream();
        using (var stream = new FileStream(@"d:\test\somemovie.mp4", FileMode.Open, FileAccess.Read, FileShare.ReadWrite, 65536, FileOptions.Asynchronous | FileOptions.SequentialScan))
        {
            await stream.CopyToAsync(memory);
        }
        memory.Position = 0;
        return File(memory, "application/octet-stream", Path.GetFileName(path));
    }

此代码是否通过流播放文件(我的意思是逐块缓冲文件并播放)?

如果我想从用户设置播放器进度的任何位置播放文件,该怎么办?

3 个答案:

答案 0 :(得分:1)

只需在此处使用普通的return File

FileStreamResult

因为它支持范围标头,这对于流传输和恢复文件下载是必需的: enter image description here

VirtualFileResultpartial range requestsstatic files middleware也支持class MetaFileCompare(FileCompare): def compare_files(self, actual_file, ref_file): return super(FileCompare, self).compare_files(actual_file, ref_file, 0) 。甚至class MetaFileCompare(FileCompare): def compare_files(self, actual_file, ref_file): return super(MetaFileCompare, self).compare_files(actual_file, ref_file, 0) 也支持。

答案 1 :(得分:1)

出了点问题。我的示例不支持简历

    [HttpGet]
    [Route("Download2")]
    public IActionResult Download2()
    {
        return PhysicalFile(@"d:\test\somemovie.mp4", "application/octet-stream");
    }

enter image description here

并且响应标头中没有接受范围

enter image description here

但是当我使用

[HttpGet]
    [Route("Download")]
    public async Task<IActionResult> Download()
    {
        var path = @"d:\test\somemovie.mp4";
        var memory = new MemoryStream();
        using (var stream = new FileStream(@"d:\test\somemovie.mp4", FileMode.Open, FileAccess.Read, FileShare.ReadWrite, 65536, FileOptions.Asynchronous | FileOptions.SequentialScan))
        {
            await stream.CopyToAsync(memory);
        }
        memory.Position = 0;
        return File(memory, "application/octet-stream", Path.GetFileName(path),true); //enableRangeProcessing = true
    }

“ enableRangeProcessing”参数为true

enter image description here

您能否提供更多解释,说明为什么会这样? 我应该使用哪种解决方案?我很困惑。

答案 2 :(得分:-1)

  static MediaStream song = null;
        static byte[] SongArray = null;

song = await client.GetMediaStreamAsync(streamFilter).ConfigureAwait(false);
                        MemoryStream ms = new MemoryStream();
                        song.CopyTo(ms);
                        SongArray = ms.ToArray();

  long fSize = song.Length, startbyte = 0, endbyte = fSize - 1;
                int statusCode = 200;

                var rangeRequest = Request.Headers["Range"].ToString();
                if (!string.IsNullOrEmpty(rangeRequest))
                {
                    string[] range = Request.Headers["Range"].ToString().Split(new char[] { '=', '-' });
                    startbyte = Convert.ToInt64(range[1]);

                    if (range.Length > 2 && range[2] != "")
                    {
                        endbyte = Convert.ToInt64(range[2]);
                    }

                    if (startbyte != 0 || endbyte != fSize - 1 || range.Length > 2 && range[2] == "")
                    {
                        statusCode = 206;
                    }
                }

                long desSize = endbyte - startbyte + 1;
                Response.StatusCode = statusCode;
                //  Response.Headers.Add(ETag = new EntityTagHeaderValue(String.Format("\"{0}\"", _eTag));
                Response.ContentType = "video/" + streamFilter.Container.GetFileExtension();
                Response.Headers.Add("Content-Accept", Response.ContentType);
                Response.Headers.Add("Content-Length", desSize.ToString());
                Response.Headers.Add("Content-Range", string.Format("bytes {0}-{1}/{2}", startbyte, endbyte, fSize));
                return new FileStreamResult(new MemoryStream(SongArray, (int)startbyte, (int)desSize), Response.ContentType);