我正在尝试使用accept-ranges
从服务器流式传输视频,以允许用户更改客户端视频播放器(在我的情况下是jwplayer)中的位置
当包含accept-ranges
代码时,客户端(jwplayer或仅在chrome中直接从url打开)正常播放约15s
,并且在每个块询问新请求之后,实际上在15秒之后只通过方法只有一次,在Response.Flush()
之内或之后连接中断,没有任何错误(有时Flush()
获取错误代码0x800704CD
或0x800703E3
或0x80070016
约10%请求),之后是Response.IsClientConnected=false
所以方法结束。
要求客户提供范围,例如123456-empty
,没有指定范围的结束部分。
我猜这不是正确的行为,也许在Response上有错误的标题..或者是正常的,客户端视频播放器是否正在为每个块创建新的请求?实际上它占用了我的PC大约80%的CPU。
问题仅在于流媒体视频和何时同时创建了大量新请求,在通常情况下下载文件时,例如在建立损坏的下载时没有问题。
当缺少接受范围代码时,视频流中没有问题,所有服务器 - >客户端传输都在while循环中,并且仅在用户中断连接方法时结束。
(This solution is running under ASP.NET MVC4
)
目前使用的代码:
public void Method()
{
string path = @"filePath.mp4";
FileInfo file = new FileInfo(path);
long fileLength = file.Length;
byte[] buffer = new byte[64 * 1024];
long dataToRead = fileLength;
long startbyte = 0;
long location = 0;
long readLength = 0;
Response.AddHeader("Accept-Ranges", "bytes");
Response.ContentType = "video/mp4";
if (!String.IsNullOrEmpty(Request.Headers["Range"]))
{
string[] range = Request.Headers["Range"].Split(new char[] { '=', '-' });
location = long.Parse(range[1]);
if (location >= 0 && location <= fileLength)
{
Response.StatusCode = 206;
Response.AddHeader("content-range", String.Format(" bytes {0}-{1}/{2}", location, fileLength - 1, fileLength));
startbyte = location;
dataToRead = fileLength - startbyte;
Response.AppendHeader("content-length", dataToRead.ToString());
}
}
else
{
Response.StatusCode = 200;
Response.AddHeader("Content-Range", String.Format(" bytes {0}-{1}/{2}", 0, fileLength - 1, fileLength));
Response.AppendHeader("content-length", fileLength.ToString());
}
try
{
using (Stream stream = System.IO.File.OpenRead(path))
{
if (startbyte > 0)
{
stream.Seek(startbyte, SeekOrigin.Begin);
}
while (dataToRead > 0)
{
if (Response.IsClientConnected)
{
readLength = stream.Read(buffer, 0, buffer.Length);
Response.OutputStream.Write(buffer, 0, (int)readLength);
Response.Flush();
dataToRead = dataToRead - readLength;
}
else
{
dataToRead = -1;
}
}
}
}
catch (EndOfStreamException endStream)
{
Log.Error(endStream.Message, endStream);
}
catch (TimeoutException timeout)
{
Log.Error(timeout.Message, timeout);
}
catch (Exception e)
{
Log.Error(e.Message, e);
}
finally
{
Response.End();
}
}