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 }