我正在尝试在ASP.NET C#(v4.5)中编写一个通用处理程序( Stream.ashx )来支持206个部分内容响应,以便在流式传输视频时提供更好的用户体验,例如增加对寻求的支持。该页面的使用方式与/Stream.ashx?relative%5cto%5cvideo.mp4
类似。
我编写了下面的代码,但是浏览器的HTML5视频播放器无法加载视频,右键单击视频占位符并保存视频,导致视频的精确下载(SHA1哈希匹配)。
为了了解错误,我针对请求和响应运行了 WireShark ,据我所知,一切似乎都有效。初始(200)响应具有accept-ranges:bytes头,然后第二(206)响应具有Accept-Ranges:bytes
,Cache-Control:private
,Content-Length:183618615
,Content-Range:0-183618614/183618615
& Content-Type:video/mp4
标题。
我一直试图让这个工作几天,但是无法解决这个问题,我确信当有人指出它为什么不起作用时我会踢自己......
到目前为止我所拥有的:
public void ProcessRequest(HttpContext context)
{
HttpRequest request = context.Request;
HttpResponse response = context.Response;
response.ClearHeaders();
response.ClearContent();
// request sanity checks (e.g. is rootPath accessible, is there a QueryString etc.)
string requestedFilePath = rootPath + request.QueryString[0];
if (!File.Exists(requestedFilePath))
{
response.StatusCode = 404;
response.Flush();
response.End();
return;
}
try
{
FileStream test = File.OpenRead(requestedFilePath);
test.Close();
test.Dispose();
}
catch (UnauthorizedAccessException)
{
response.StatusCode = 403;
response.Flush();
response.End();
return;
}
response.Headers.Add("Accept-Ranges", "bytes");
FileInfo aboutFile = new FileInfo(requestedFilePath);
int length = (int)aboutFile.Length;
int fullLength = length;
int startAt = 0;
int endAt = length - 1;
if (request.Headers["Range"] != null)
{
response.StatusCode = 206;
response.StatusDescription = "Partial Content";
string rangeString = request.Headers["Range"];
rangeString = rangeString.Substring(6);
string[] rangeParts = rangeString.Split('-');
startAt = Convert.ToInt32(rangeParts[0]);
if (rangeString.EndsWith("-"))
{
length = fullLength - startAt;
}
else
{
endAt = Convert.ToInt32(rangeParts[1]);
length = (endAt - startAt) + 1;
}
response.Headers.Add("Content-Range", startAt + "-" + endAt + "/" + fullLength);
}
response.Headers.Add("Content-Length", length.ToString());
response.ContentType = Multimedia.DetectMIMEType(requestedFilePath);
FileStream fileReader = new FileStream(requestedFilePath, FileMode.Open, FileAccess.Read);
CreatePartialContent(fileReader, response.OutputStream, startAt, endAt);
fileReader.Close();
fileReader.Dispose();
response.OutputStream.Close();
try
{
response.Flush();
}
catch (HttpException) { }
try
{
response.Close();
}
catch (HttpException) { }
}
private static void CreatePartialContent(FileStream inputStream, System.IO.Stream outputStream, long start, long end)
{
int count = 0;
// 50MiB buffer
int bufferSize = 52428800;
long remainingBytes = end - start + 1;
long position = start;
byte[] buffer = new byte[bufferSize];
inputStream.Position = position;
while (position <= end)
{
try
{
if (remainingBytes > bufferSize)
{
count = inputStream.Read(buffer, 0, bufferSize);
}
else
{
count = inputStream.Read(buffer, 0, (int)remainingBytes);
}
outputStream.Write(buffer, 0, count);
}
catch (Exception ex)
{
break;
}
position = inputStream.Position;
remainingBytes = (end - position) + 1;
}
}
提前感谢任何提示!