我使用文件表将视频文件存储在我的sql server中,我想在Web浏览器中观看它们。 aspx Web服务器正在处理请求。 VideoHandler.ashx处理程序类用于处理请求并将数据发送到浏览器。这是用于流式传输视频文件的代码:
$ProductDetailObject = new OrderDetail;
$product_detail = $ProductDetailObject->getlist($order->id);
foreach ($product_detail as $product)
{
$items_table2 .=
''.$product['product_name'].'-('.(int)$product['product_quantity'].')';
}
只要视频文件不是太大,代码就可以正常工作。例如,当流式传输大小为72MB的视频时,一切正常。当我想要流式传输大小为612MB的视频时,会出现此问题。然后应用程序抛出异常:
long size, start, end, length, fp = 0;
using (StreamReader reader = new StreamReader(fullpath))
{
size = reader.BaseStream.Length;
start = 0;
end = size - 1;
length = size;
context.Response.AddHeader("Accept-Ranges", "0-" + size);
if (!String.IsNullOrEmpty(context.Request.ServerVariables["HTTP_RANGE"]))
{
long anotherStart = start;
long anotherEnd = end;
string[] arr_split = context.Request.ServerVariables["HTTP_RANGE"].Split(new char[] { Convert.ToChar("=") });
string range = arr_split[1];
// Make sure the client hasn't sent us a multibyte range
if (range.IndexOf(",") > -1)
{
context.Response.AddHeader("Content-Range", "bytes " + start + "-" + end + "/" + size);
throw new HttpException(416, "Requested Range Not Satisfiable");
}
// If the range starts with an '-' we start from the beginning
// If not, we forward the file pointer
// And make sure to get the end byte if spesified
if (range.StartsWith("-"))
{
// The n-number of the last bytes is requested
anotherStart = size - Convert.ToInt64(range.Substring(1));
}
else
{
arr_split = range.Split(new char[] { Convert.ToChar("-") });
anotherStart = Convert.ToInt64(arr_split[0]);
long temp = 0;
anotherEnd = (arr_split.Length > 1 && Int64.TryParse(arr_split[1].ToString(), out temp)) ? Convert.ToInt64(arr_split[1]) : size;
}
// End bytes can not be larger than $end.
anotherEnd = (anotherEnd > end) ? end : anotherEnd;
// Validate the requested range and return an error if it's not correct.
if (anotherStart > anotherEnd || anotherStart > size - 1 || anotherEnd >= size)
{
context.Response.AddHeader("Content-Range", "bytes " + start + "-" + end + "/" + size);
throw new HttpException(416, "Requested Range Not Satisfiable");
}
start = anotherStart;
end = anotherEnd;
length = end - start + 1; // Calculate new content length
fp = reader.BaseStream.Seek(start, SeekOrigin.Begin);
context.Response.StatusCode = 206;
reader.Dispose();
reader.Close();
}
}
// Notify the client the byte range we'll be outputting
context.Response.AddHeader("Content-Range", "bytes " + start + "-" + end + "/" + size);
context.Response.AddHeader("Content-Length", length.ToString());
// Start buffered download
context.Response.WriteFile(fullpath, fp, length);
context.Response.End();
}
这是堆栈跟踪:
"System.OutOfMemoryException"
Operation: GET/VideoHandler.ashx
不幸的是我无法弄清楚问题出在哪里以及导致异常的原因......我在观察诊断工具时观察到的是,当请求到来时,进程内存不会增加但抛出异常。 此外,服务器/应用程序没有崩溃。
答案 0 :(得分:1)
由于Clontea先生的链接,我能够找到一个正在运行的解决方案。我所要做的就是将StreamReader更改为FileStream。使用此代码,您可以在浏览器中流式传输视频并进行搜索。
long size, start, end, length, fp = 0;
byte[] buffer = new byte[10000];
int ilength = 0;
using (Stream reader = new FileStream(fullpath, FileMode.Open, FileAccess.Read, FileShare.Read))
{
size = reader.Length;
start = 0;
end = size - 1;
length = size;
context.Response.AddHeader("Accept-Ranges", "0-" + size);
if (!String.IsNullOrEmpty(context.Request.ServerVariables["HTTP_RANGE"]))
{
long anotherStart = start;
long anotherEnd = end;
string[] arr_split = context.Request.ServerVariables["HTTP_RANGE"].Split(new char[] { Convert.ToChar("=") });
string range = arr_split[1];
// Make sure the client hasn't sent us a multibyte range
if (range.IndexOf(",") > -1)
{
context.Response.AddHeader("Content-Range", "bytes " + start + "-" + end + "/" + size);
throw new HttpException(416, "Requested Range Not Satisfiable");
}
// If the range starts with an '-' we start from the beginning
// If not, we forward the file pointer
// And make sure to get the end byte if spesified
if (range.StartsWith("-"))
{
// The n-number of the last bytes is requested
anotherStart = size - Convert.ToInt64(range.Substring(1));
}
else
{
arr_split = range.Split(new char[] { Convert.ToChar("-") });
anotherStart = Convert.ToInt64(arr_split[0]);
long temp = 0;
anotherEnd = (arr_split.Length > 1 && Int64.TryParse(arr_split[1].ToString(), out temp)) ? Convert.ToInt64(arr_split[1]) : size;
}
// End bytes can not be larger than $end.
anotherEnd = (anotherEnd > end) ? end : anotherEnd;
// Validate the requested range and return an error if it's not correct.
if (anotherStart > anotherEnd || anotherStart > size - 1 || anotherEnd >= size)
{
context.Response.AddHeader("Content-Range", "bytes " + start + "-" + end + "/" + size);
throw new HttpException(416, "Requested Range Not Satisfiable");
}
start = anotherStart;
end = anotherEnd;
length = end - start + 1; // Calculate new content length
fp = reader.Seek(start, SeekOrigin.Begin);
context.Response.StatusCode = 206;
ilength = reader.Read(buffer, 0, 10000);
reader.Dispose();
reader.Close();
}
}
// Notify the client the byte range we'll be outputting
context.Response.AddHeader("Content-Range", "bytes " + start + "-" + end + "/" + size);
context.Response.AddHeader("Content-Length", length.ToString());
// Start buffered download
context.Response.OutputStream.Write(buffer, 0, ilength);
HttpContext.Current.ApplicationInstance.CompleteRequest();
}