Reputation: 23
I am developing a web application with which user can view files in the iPad (Safari browser). I am able to download and view .pdf, .doc,.ppt files. But i am unable to download and view MP4 and 3GP files. I have added correct mime type in the IIS. I am getting following error in Safari (iPad) "BYTE_RANGE_ERROR_MESSAGE". I am using IIS 7.0 in Windows Server 2008.
Note:I am able to download all the files in PC using IE, Mozilla and Safari.
Upvotes: 1
Views: 1843
Reputation: 6571
Sample code below will help you to stream mp4 video via asp.net handler.
private void RangeDownload(string fullpath,HttpContext context)
{
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 (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;
}
anotherEnd = (anotherEnd > end) ? end : anotherEnd;
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;
}
}
// 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();
}
Sample use of function under ProcessRequest method
string mimetype = "video/mp4";
if (System.IO.File.Exists(file))
{
context.Response.ContentType = mimetype;
if (!String.IsNullOrEmpty(context.Request.ServerVariables["HTTP_RANGE"]))
{
//request for chunk
RangeDownload(file, context);
}
else
{
//ask for all
long fileLength = File.OpenRead(file).Length;
context.Response.AddHeader("Content-Length", fileLength.ToString());
context.Response.WriteFile(file);
}
}
else
{
throw new HttpException(404, "Video Not Found Path:" + file);
}
Hope this code will help you.
Upvotes: 1