i am trying to stream video over http to iphone without a streming server with .net. After some tests i found that if you just upload iphone compatible video to your server, iis7 works just fine and iphone startsplaying video after small buffer time and continues to download in the background.
My problem is, i am unable to do it with .net. I have tried with
public static void SmallFile(string filename, string filepath, string contentType)
{
try
{
FileStream MyFileStream = new FileStream(filepath, FileMode.Open, FileAccess.Read, FileShare.Read);
long FileSize;
FileSize = MyFileStream.Length;
byte[] Buffer = new byte[(int)FileSize];
MyFileStream.Read(Buffer, 0, (int)MyFileStream.Length);
MyFileStream.Close();
HttpContext.Current.Response.ContentType = contentType;
HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(filename, System.Text.Encoding.UTF8));
HttpContext.Current.Response.BinaryWrite(Buffer);
}
catch
{
HttpContext.Current.Response.ContentType = "text/html";
HttpContext.Current.Response.Write("Downloading Error! " + filename + " not found!");
}
HttpContext.Current.Resp开发者_运维技巧onse.End();
}
or with
public static void ResumableFile(string filename, string fullpath, string contentType)
{
try
{
FileStream myFile = new FileStream(fullpath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
BinaryReader br = new BinaryReader(myFile);
try
{
HttpContext.Current.Response.AddHeader("Accept-Ranges", "bytes");
HttpContext.Current.Response.Buffer = false;
long fileLength = myFile.Length;
long startBytes = 0;
//int pack = 10240; //10K bytes
int pack = 1048576; //1024K bytes
if (HttpContext.Current.Request.Headers["Range"] != null)
{
HttpContext.Current.Response.StatusCode = 206;
string[] range = HttpContext.Current.Request.Headers["Range"].Split(new char[] { '=', '-' });
startBytes = Convert.ToInt64(range[1]);
}
HttpContext.Current.Response.AddHeader("Content-Length", (fileLength - startBytes).ToString());
if (startBytes != 0)
{
HttpContext.Current.Response.AddHeader("Content-Range", string.Format(" bytes {0}-{1}/{2}", startBytes, fileLength - 1, fileLength));
}
HttpContext.Current.Response.AddHeader("Connection", "Keep-Alive");
HttpContext.Current.Response.ContentType = contentType;
HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(filename, System.Text.Encoding.UTF8));
br.BaseStream.Seek(startBytes, SeekOrigin.Begin);
int maxCount = (int)Math.Floor((double)((fileLength - startBytes) / pack)) + 1;
for (int i = 0; i < maxCount; i++)
{
if (HttpContext.Current.Response.IsClientConnected)
{
HttpContext.Current.Response.BinaryWrite(br.ReadBytes(pack));
}
else
{
i = maxCount;
}
}
}
catch
{
HttpContext.Current.Response.ContentType = "text/html";
HttpContext.Current.Response.Write("Downloading Error! " + filename + " not found!");
}
finally
{
br.Close();
myFile.Close();
}
}
catch
{
HttpContext.Current.Response.ContentType = "text/html";
HttpContext.Current.Response.Write("Downloading Error!" + filename + " not found!");
}
}
In both, i get error saying server is not configured properly. I then removed
HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=" + HttpUtility.UrlEncode(filename, System.Text.Encoding.UTF8));
part so it won't trigger full download but result was the same.
I have checked responses from server and there is no different/extra header coming from server when i directly download file.
What i am trying to findout what would be enabling iphone to buffer and start playing video when i directly download video file and how can i implemnet it with .net
If youwonder why i just don't use iis, i need to put some sort of leech protecttion due to bandwidth restrictions
Anyone have any exprience?
UPDATE
Here is the first request and response from iis
GET /test.mp4 HTTP/1.1
Host: 192.168.2.200
User-Agent: Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_1_2 like Mac OS X; tr-tr) AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0 Mobile/7D11 Safari/528.16
Cache-Control: max-age=0
Accept: application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: tr-tr
Accept-Encoding: gzip, deflate
Connection: keep-alive
HTTP/1.1 200 OK
Content-Type: video/mp4
Last-Modified: Wed, 23 Dec 2009 20:12:57 GMT
Accept-Ranges: bytes
ETag: "e6ad9151c84ca1:0"
Server: Microsoft-IIS/7.5
X-Powered-By: ASP.NET
Date: Wed, 23 Dec 2009 21:07:19 GMT
Content-Length: 2301438
And second request and response
GET /test.mp4 HTTP/1.1
Host: 192.168.2.200
Range: bytes=0-2269183
Connection: close
User-Agent: Apple iPhone OS v3.1.2 CoreMedia v1.0.0.7D11
Accept: */*
Accept-Encoding: identity
HTTP/1.1 206 Partial Content
Content-Type: video/mp4
Last-Modified: Wed, 23 Dec 2009 20:12:57 GMT
Accept-Ranges: bytes
ETag: "e6ad9151c84ca1:0"
Server: Microsoft-IIS/7.5
X-Powered-By: ASP.NET
Date: Wed, 23 Dec 2009 21:11:33 GMT
Connection: close
Content-Length: 2269184
Content-Range: bytes 0-2269183/2301438
As i understand iphone requests different bytes on second request and so on. Is there anyway getting c# to send those bytes range to the client?
I think i've found my solution at http://dotnetslackers.com/articles/aspnet/Range-Specific-Requests-in-ASP-NET.aspx
I'd perform some sort of message sniffing.
Basically, I'd set up something that you can stream video to iPhone with (like TVersity) and then set up something to intercept the traffic between TVersity and the iPhone so that you can inspect the HTTP request and response.
Here is a blog post on how to set up TVersity:
http://geeks.pirillo.com/profiles/blogs/2300301:BlogPost:38497
The relative url "/iPhone" is the one that you want to sniff traffic on. It should shed some light on the proper message exchange pattern to download video to the iPhone.
try this one http://code.google.com/p/talifun-web/wiki/StaticFileHandler
or link in my first reply has source code
精彩评论