Background:对于音视频在线播放,一些小应用是靠nginx处理访问视频、音频文件的请求,对外应用的一般会托管至各种云上使用相关的服务。前者存在巨大的安全隐患,后者会有一定的成本。有的时候还是需要自己造个轮子。

step 1:先实现文件下载

[HttpGet]
public IActionResult Get()
{    
    var filePath = @"E:\test.wav";
    var name = @"tes1t.wav";
    FileStream fs = new FileStream(filePath, FileMode.Open);
    return  File(fs, "application/octet-stream", name);
}

前面的audio标签是可以播放和正常下载的,但是并不能实现进度控件的调整

step2:请求的区别

Nginx的处理是可以实现播放进度调整的。在前端请求相同的情况下,两者用nginx代理和刚才的下载的主要区别如下:

可以看出Content-Range对应的正是请求头中的Range

关于这几个头部信息可参考这篇文章:https://blog.csdn.net/thewindkee/article/details/80189434

这3个标签同时也是文件实现断点续传的关键。

step3:断点续传

这样进度的调整就转化为了断点续传功能。

.net可参考:https://www.cnblogs.com/Leo_wl/p/8467796.html

 1  public FileStreamResult Index(string auth,string filename)
 2         {
 3             if (auth != null && auth.Length >7)
 4             {
 5                  // 处理权限问题
 6             }
 7             else
 8             {
 9                 return null;
10             }
11             
12             int size, end, length = 0;
13             int start;
14 
15             MemoryStream Mstream;
16             using (FileStream reader = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read))
17             {
18                 byte[] bytes = new byte[reader.Length];
19                 //var strd = new StreamReader(reader);
20 
21                 size = bytes.Length;
22                 start = 0;
23                 end = size - 1;
24                 length = size;
25                 Response.Headers["Accept-Ranges"] = "0-" + size;
26                 if (!String.IsNullOrEmpty(Request.Headers["Range"]))
27                 {
28                     int anotherStart = start;
29                     int anotherEnd = end;
30                     var headerRange = Request.Headers["Range"];
31                     string[] arr_split = headerRange.FirstOrDefault().Split(new char[] { Convert.ToChar("=") });
32                     Debug.WriteLine(arr_split);
33                     string range = arr_split[1];
34                     if (range.IndexOf(",") > -1)
35                     {
36                         Response.Headers["Content-Range"] = "bytes " + start + "-" + end + "/" + size;
37 
38                         Response.StatusCode = 416;
39 
40                     }
41                     if (range.StartsWith("-"))
42                     {
43                         // The n-number of the last bytes is requested
44                         anotherStart = size - Convert.ToInt32(range.Substring(1));
45                     }
46                     else
47                     {
48                         arr_split = range.Split(new char[] { Convert.ToChar("-") });
49                         anotherStart = Convert.ToInt32(arr_split[0]);
50                         int temp = 0;
51                         anotherEnd = (arr_split.Length > 1 && Int32.TryParse(arr_split[1].ToString(), out temp)) ? Convert.ToInt32(arr_split[1]) : size;
52                     }
53                     anotherEnd = (anotherEnd > end) ? end : anotherEnd;
54                     if (anotherStart > anotherEnd || anotherStart > size - 1 || anotherEnd >= size)
55                     {
56                         Response.Headers["Content-Range"] = "bytes " + start + "-" + end + "/" + size;
57                         Response.StatusCode = 416;
58 
59                     }
60                     start = anotherStart;
61                     end = anotherEnd;
62                     length = end - start + 1; // Calculate new content length
63                     reader.Read(bytes, start, length);
64                     Response.StatusCode = 206;
65                 }
66                 else
67                 {
68                     reader.Read(bytes, 0, bytes.Length);
69                 }
70                 Mstream = new MemoryStream(bytes);
71             }
72             Response.Headers["Content-Range"] = "bytes " + start + "-" + end + "/" + size;
73             Response.Headers["Content-Length"] = length.ToString();
74             Response.Headers.Add("Content-Disposition", "attachment; filename=download.wav");
75             return new FileStreamResult(Mstream, "applicaton/octet-stream");
76         }
.netcore 2.2 修改版本