Cannot jump to new part of Silverlight video when using handler

  • Thread starter Thread starter Roger Martin
  • Start date Start date
R

Roger Martin

This is a follow-up to my post "Silverlight video doesn't work when file is
streamed from handler in ASP.net" at
http://www.microsoft.com/communitie...pnet&mid=e9a38d03-83a8-41fc-8950-5ee60d2a18a5.

I have a web site under .NET 2.0 that renders videos using the Silverlight
media player. When I stream the video file (.wmv) to the browser via a
hard-coded link to the file, all is well. And when I use an HTTP handler to
stream the video to the browser, it also plays. BUT... when I use the handler
the Silverlight player has a problem - I cannot jump to different portions of
the video by dragging the position indicator or clicking a new possition.
When I try, the center of the player turns into rotating circles and inside
it says "0". In other words, it is telling me to wait as it moves to the new
position, but it never does.

Furthermore, once I attempt to go to a new position, the Play button no
longer works and there is nothing I can do to get the video to play short of
reloading the page.

I set up two demonstration pages:
http://www.galleryserverpro.com/dev/webapp2/video2.aspx - This uses the
handler and demonstrates the issue. Notice that - for example - you cannot
move the cursor to the middle of the video and click Play.

http://www.galleryserverpro.com/dev/webapp2/video_nohandler.aspx - This is
identical to the first page, except instead of using the handler it
hard-codes a direct link to the .wmv file. You can jump around to different
sections without any trouble.

Using the first link above, I see the issue in these setups:

Win 2008 Server / FF3
Vista / FF3
Win XP / FF2
Win XP / IE6

Interestingly, the handler *does* work in IE7 (Win 2008 Server and Vista).

Below is the HTTP handler:

using System.IO;
using System.Web;

namespace WebApplication2.handler
{
[System.Web.Services.WebService(Namespace = "http://tempuri.org/")]
[System.Web.Services.WebServiceBinding(ConformsTo =
System.Web.Services.WsiProfiles.BasicProfile1_1)]
public class getmediaobject : IHttpHandler
{
#region IHttpHandler Members

public bool IsReusable
{
get { return true; }
}

public void ProcessRequest(HttpContext context)
{
ProcessMediaObject(context,
context.Server.MapPath("~/video/3StrikesChipmunk_56.wmv"));
}

#endregion

private void ProcessMediaObject(HttpContext context, string filePath)
{
FileStream fileStream = null;
try
{
context.Response.Clear();
context.Response.ContentType = "video/x-ms-wmv";
context.Response.Buffer = false;

HttpCachePolicy cachePolicy = context.Response.Cache;
cachePolicy.SetExpires(System.DateTime.Now.AddSeconds(2592000)); // 30
days
cachePolicy.SetCacheability(HttpCacheability.Public);
cachePolicy.SetValidUntilExpires(true);

const int bufferSize = 32768;
byte[] buffer = new byte[bufferSize];
long byteCount;
fileStream = File.OpenRead(filePath);
context.Response.AddHeader("Content-Length",
fileStream.Length.ToString());
while ((byteCount = fileStream.Read(buffer, 0, buffer.Length)) > 0)
{
if (context.Response.IsClientConnected)
{
context.Response.OutputStream.Write(buffer, 0, buffer.Length);
context.Response.Flush();
}
else
{
return;
}
}
}
finally
{
if (fileStream != null)
fileStream.Close();

context.Response.End();
}
}
}
}

Thanks for your help!
Roger Martin
Gallery Server Pro
 
my guess (if you would use a network sniffer as I suggested earlier
you'd know) is that silverlight use gets with a range when streaming
video (flash does). this is supported by iis, but your handler does not
support it. read the w3c http 1.1 spec to learn how to implement it.

-- bruce (sqlwork.com)

Roger said:
This is a follow-up to my post "Silverlight video doesn't work when file is
streamed from handler in ASP.net" at
http://www.microsoft.com/communitie...pnet&mid=e9a38d03-83a8-41fc-8950-5ee60d2a18a5.

I have a web site under .NET 2.0 that renders videos using the Silverlight
media player. When I stream the video file (.wmv) to the browser via a
hard-coded link to the file, all is well. And when I use an HTTP handler to
stream the video to the browser, it also plays. BUT... when I use the handler
the Silverlight player has a problem - I cannot jump to different portions of
the video by dragging the position indicator or clicking a new possition.
When I try, the center of the player turns into rotating circles and inside
it says "0". In other words, it is telling me to wait as it moves to the new
position, but it never does.

Furthermore, once I attempt to go to a new position, the Play button no
longer works and there is nothing I can do to get the video to play short of
reloading the page.

I set up two demonstration pages:
http://www.galleryserverpro.com/dev/webapp2/video2.aspx - This uses the
handler and demonstrates the issue. Notice that - for example - you cannot
move the cursor to the middle of the video and click Play.

http://www.galleryserverpro.com/dev/webapp2/video_nohandler.aspx - This is
identical to the first page, except instead of using the handler it
hard-codes a direct link to the .wmv file. You can jump around to different
sections without any trouble.

Using the first link above, I see the issue in these setups:

Win 2008 Server / FF3
Vista / FF3
Win XP / FF2
Win XP / IE6

Interestingly, the handler *does* work in IE7 (Win 2008 Server and Vista).

Below is the HTTP handler:

using System.IO;
using System.Web;

namespace WebApplication2.handler
{
[System.Web.Services.WebService(Namespace = "http://tempuri.org/")]
[System.Web.Services.WebServiceBinding(ConformsTo =
System.Web.Services.WsiProfiles.BasicProfile1_1)]
public class getmediaobject : IHttpHandler
{
#region IHttpHandler Members

public bool IsReusable
{
get { return true; }
}

public void ProcessRequest(HttpContext context)
{
ProcessMediaObject(context,
context.Server.MapPath("~/video/3StrikesChipmunk_56.wmv"));
}

#endregion

private void ProcessMediaObject(HttpContext context, string filePath)
{
FileStream fileStream = null;
try
{
context.Response.Clear();
context.Response.ContentType = "video/x-ms-wmv";
context.Response.Buffer = false;

HttpCachePolicy cachePolicy = context.Response.Cache;
cachePolicy.SetExpires(System.DateTime.Now.AddSeconds(2592000)); // 30
days
cachePolicy.SetCacheability(HttpCacheability.Public);
cachePolicy.SetValidUntilExpires(true);

const int bufferSize = 32768;
byte[] buffer = new byte[bufferSize];
long byteCount;
fileStream = File.OpenRead(filePath);
context.Response.AddHeader("Content-Length",
fileStream.Length.ToString());
while ((byteCount = fileStream.Read(buffer, 0, buffer.Length)) > 0)
{
if (context.Response.IsClientConnected)
{
context.Response.OutputStream.Write(buffer, 0, buffer.Length);
context.Response.Flush();
}
else
{
return;
}
}
}
finally
{
if (fileStream != null)
fileStream.Close();

context.Response.End();
}
}
}
}

Thanks for your help!
Roger Martin
Gallery Server Pro
 
Hi Roger,

I still cannot reproduce this problem on my side. As Bruce suggested, first
try to add following HTTP header in the response to see if it works:

context.Response.AddHeader("Accept-Ranges", "bytes");

Refer to Header Field Definitions:
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html

Please let me know if you made progress on this issue. I'll try to find a
mchine that can reproduce this issue.

Regards,
Allen Chen
Microsoft Online Support

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
(e-mail address removed).

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/en-us/subscriptions/aa948868.aspx#notifications.

Note: MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 2 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions. Issues of this
nature are best handled working with a dedicated Microsoft Support Engineer
by contacting Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/en-us/subscriptions/aa948874.aspx
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.

--------------------
| Thread-Topic: Cannot jump to new part of Silverlight video when using
handler
| thread-index: AclGCAbQg8ZDlearR8yLrR5iezrDyg==
| X-WBNR-Posting-Host: 207.46.193.207
| From: =?Utf-8?B?Um9nZXIgTWFydGlu?= <[email protected]>
| Subject: Cannot jump to new part of Silverlight video when using handler
| Date: Thu, 13 Nov 2008 19:21:04 -0800
| Lines: 112
| Message-ID: <[email protected]>
| MIME-Version: 1.0
| Content-Type: text/plain;
| charset="Utf-8"
| Content-Transfer-Encoding: 7bit
| X-Newsreader: Microsoft CDO for Windows 2000
| Content-Class: urn:content-classes:message
| Importance: normal
| Priority: normal
| X-MimeOLE: Produced By Microsoft MimeOLE V6.00.3790.3168
| Newsgroups: microsoft.public.dotnet.framework.aspnet
| Path: TK2MSFTNGHUB02.phx.gbl
| Xref: TK2MSFTNGHUB02.phx.gbl
microsoft.public.dotnet.framework.aspnet:79857
| NNTP-Posting-Host: tk2msftibfm01.phx.gbl 10.40.244.149
| X-Tomcat-NG: microsoft.public.dotnet.framework.aspnet
|
| This is a follow-up to my post "Silverlight video doesn't work when file
is
| streamed from handler in ASP.net" at
|
http://www.microsoft.com/communities/newsgroups/en-us/default.aspx?dg=micros
oft.public.dotnet.framework.aspnet&mid=e9a38d03-83a8-41fc-8950-5ee60d2a18a5.
|
| I have a web site under .NET 2.0 that renders videos using the Silverlight
| media player. When I stream the video file (.wmv) to the browser via a
| hard-coded link to the file, all is well. And when I use an HTTP handler
to
| stream the video to the browser, it also plays. BUT... when I use the
handler
| the Silverlight player has a problem - I cannot jump to different
portions of
| the video by dragging the position indicator or clicking a new possition.
| When I try, the center of the player turns into rotating circles and
inside
| it says "0". In other words, it is telling me to wait as it moves to the
new
| position, but it never does.
|
| Furthermore, once I attempt to go to a new position, the Play button no
| longer works and there is nothing I can do to get the video to play short
of
| reloading the page.
|
| I set up two demonstration pages:
| http://www.galleryserverpro.com/dev/webapp2/video2.aspx - This uses the
| handler and demonstrates the issue. Notice that - for example - you
cannot
| move the cursor to the middle of the video and click Play.
|
| http://www.galleryserverpro.com/dev/webapp2/video_nohandler.aspx - This
is
| identical to the first page, except instead of using the handler it
| hard-codes a direct link to the .wmv file. You can jump around to
different
| sections without any trouble.
|
| Using the first link above, I see the issue in these setups:
|
| Win 2008 Server / FF3
| Vista / FF3
| Win XP / FF2
| Win XP / IE6
|
| Interestingly, the handler *does* work in IE7 (Win 2008 Server and Vista).
|
| Below is the HTTP handler:
|
| using System.IO;
| using System.Web;
|
| namespace WebApplication2.handler
| {
| [System.Web.Services.WebService(Namespace = "http://tempuri.org/")]
| [System.Web.Services.WebServiceBinding(ConformsTo =
| System.Web.Services.WsiProfiles.BasicProfile1_1)]
| public class getmediaobject : IHttpHandler
| {
| #region IHttpHandler Members
|
| public bool IsReusable
| {
| get { return true; }
| }
|
| public void ProcessRequest(HttpContext context)
| {
| ProcessMediaObject(context,
| context.Server.MapPath("~/video/3StrikesChipmunk_56.wmv"));
| }
|
| #endregion
|
| private void ProcessMediaObject(HttpContext context, string filePath)
| {
| FileStream fileStream = null;
| try
| {
| context.Response.Clear();
| context.Response.ContentType = "video/x-ms-wmv";
| context.Response.Buffer = false;
|
| HttpCachePolicy cachePolicy = context.Response.Cache;
| cachePolicy.SetExpires(System.DateTime.Now.AddSeconds(2592000)); //
30
| days
| cachePolicy.SetCacheability(HttpCacheability.Public);
| cachePolicy.SetValidUntilExpires(true);
|
| const int bufferSize = 32768;
| byte[] buffer = new byte[bufferSize];
| long byteCount;
| fileStream = File.OpenRead(filePath);
| context.Response.AddHeader("Content-Length",
| fileStream.Length.ToString());
| while ((byteCount = fileStream.Read(buffer, 0, buffer.Length)) > 0)
| {
| if (context.Response.IsClientConnected)
| {
| context.Response.OutputStream.Write(buffer, 0, buffer.Length);
| context.Response.Flush();
| }
| else
| {
| return;
| }
| }
| }
| finally
| {
| if (fileStream != null)
| fileStream.Close();
|
| context.Response.End();
| }
| }
| }
| }
|
| Thanks for your help!
| Roger Martin
| Gallery Server Pro
|
 
Unfortunately, adding "Accept-Ranges" did not help; in fact, in made it
worse. When present, the video refuses to play at all, and no position
indicator appears to allow dragging or repositioning.

Here are the response headers after I added it:
Frame: Number = 434, Captured Frame Length = 1514, MediaType = ETHERNET
+ Ethernet: Etype = Internet IP
(IPv4),DestinationAddress:[00-16-E6-8F-5E-9E],SourceAddress:[00-06-25-7F-45-9D]
+ Ipv4: Src = 209.67.188.9, Dest = 192.168.1.102, Next Protocol = TCP,
Packet ID = 29397, Total IP Length = 1500
+ Tcp: Flags=...A...., SrcPort=HTTP(80), DstPort=63247, PayloadLen=1460,
Seq=3634901546 - 3634903006, Ack=233418134, Win=64240 (scale factor 0x0) =
64240
- Http: Response, HTTP/1.1, Status Code = 200, URL:
/dev/webapp2/handler/getmediaobject.ashx
ProtocolVersion: HTTP/1.1
StatusCode: 200, Ok
Reason: OK
Cache-Control: public
ContentLength: 449378
ContentType: video/x-ms-wmv
Expires: Sun, 14 Dec 2008 13:59:01 GMT
Accept-Ranges: bytes
Server: Microsoft-IIS/7.0
XAspNetVersion: 2.0.50727
XPoweredBy: ASP.NET
Date: Fri, 14 Nov 2008 13:59:00 GMT
Connection: close
HeaderEnd: CRLF
+ payload: HttpContentType = video/x-ms-wmv

It is odd you have such a hard time reproducing the issue. I have several
computers here with a total of 4 browsers (FF2, FF3, IE6, IE7) and the only
place it works is with IE7.

Roger
 
you actually have to add Range support to your handler, not just say you
have it and ignore the range requests. look at the request to see if
it has a range specified. a range specifies a offset and a length of
bytes to return. that is you don't stream the whole file per request,
just the bytes requested.

ie7 is probably precaching the video (maybe a bug).

-- bruce (sqlwork.com)
 
Thanks Bruce. I just discovered that if I modify my handler to use WriteFile,
it works:

FileInfo fi = new FileInfo(filePath);
context.Response.WriteFile(filePath, false);

However, this is not a long term solution because WriteFile has issues with
large files (http://support.microsoft.com/kb/812406). I need a reliable way
to send files to the user that won't overwhelm the server's memory; that's
why I was using a chunked approach.

There is nothing about a range in the request header:
Frame: Number = 433, Captured Frame Length = 1027, MediaType = ETHERNET
+ Ethernet: Etype = Internet IP
(IPv4),DestinationAddress:[00-06-25-7F-45-9D],SourceAddress:[00-16-E6-8F-5E-9E]
+ Ipv4: Src = 192.168.1.102, Dest = 209.67.188.9, Next Protocol = TCP,
Packet ID = 31490, Total IP Length = 1013
+ Tcp: [ReTransmit #430]Flags=...AP..., SrcPort=63247, DstPort=HTTP(80),
PayloadLen=973, Seq=233417161 - 233418134, Ack=3634901546, Win=65535 (scale
factor 0x0) = 65535
- Http: Request, GET /dev/webapp2/handler/getmediaobject.ashx
Command: GET
- URI: /dev/webapp2/handler/getmediaobject.ashx
Location: /dev/webapp2/handler/getmediaobject.ashx
ProtocolVersion: HTTP/1.1
Host: www.galleryserverpro.com
UserAgent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.4)
Gecko/2008102920 Firefox/3.0.4 (.NET CLR 3.5.30729)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,nl;q=0.8,en;q=0.5,de-ch;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Cookie:
__utma=5214629.4168526968000403000.1223864238.1226617001.1226628470.137;
__utmz=5214629.1226167175.107.5.utmcsr=linkedin.com|utmccn=(referral)|utmcmd=referral|utmcct=/myprofile;
..ASPXANONYMOUS=ZqP1ljp8yQEkAAAAYTU1MmI2ODktMGI1Yy00Zjg3LTkzYTItMDlhMjdkN
HeaderEnd: CRLF

Given that it works using WriteFile and that there is no range in the
request, do you think I still need to add range support? I am doubtful but I
admit I am at the limits of my knowledge. Perhaps there is just a problem
with my chunking algorithm (see earlier for the code). I did a quick search
on adding range support in a handler but couldn't find anything - I don't
have a clue how I might do this.

Roger
 
Roger, just now 9:35ish am CST I was able to begin playback by clicking into
the viewport...
http://www.galleryserverpro.com/dev/webapp2/video2.aspx



Roger Martin said:
Thanks Bruce. I just discovered that if I modify my handler to use
WriteFile,
it works:

FileInfo fi = new FileInfo(filePath);
context.Response.WriteFile(filePath, false);

However, this is not a long term solution because WriteFile has issues
with
large files (http://support.microsoft.com/kb/812406). I need a reliable
way
to send files to the user that won't overwhelm the server's memory; that's
why I was using a chunked approach.

There is nothing about a range in the request header:
Frame: Number = 433, Captured Frame Length = 1027, MediaType = ETHERNET
+ Ethernet: Etype = Internet IP
(IPv4),DestinationAddress:[00-06-25-7F-45-9D],SourceAddress:[00-16-E6-8F-5E-9E]
+ Ipv4: Src = 192.168.1.102, Dest = 209.67.188.9, Next Protocol = TCP,
Packet ID = 31490, Total IP Length = 1013
+ Tcp: [ReTransmit #430]Flags=...AP..., SrcPort=63247, DstPort=HTTP(80),
PayloadLen=973, Seq=233417161 - 233418134, Ack=3634901546, Win=65535
(scale
factor 0x0) = 65535
- Http: Request, GET /dev/webapp2/handler/getmediaobject.ashx
Command: GET
- URI: /dev/webapp2/handler/getmediaobject.ashx
Location: /dev/webapp2/handler/getmediaobject.ashx
ProtocolVersion: HTTP/1.1
Host: www.galleryserverpro.com
UserAgent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.4)
Gecko/2008102920 Firefox/3.0.4 (.NET CLR 3.5.30729)
Accept:
text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,nl;q=0.8,en;q=0.5,de-ch;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Cookie:
__utma=5214629.4168526968000403000.1223864238.1226617001.1226628470.137;
__utmz=5214629.1226167175.107.5.utmcsr=linkedin.com|utmccn=(referral)|utmcmd=referral|utmcct=/myprofile;
.ASPXANONYMOUS=ZqP1ljp8yQEkAAAAYTU1MmI2ODktMGI1Yy00Zjg3LTkzYTItMDlhMjdkN
HeaderEnd: CRLF

Given that it works using WriteFile and that there is no range in the
request, do you think I still need to add range support? I am doubtful but
I
admit I am at the limits of my knowledge. Perhaps there is just a problem
with my chunking algorithm (see earlier for the code). I did a quick
search
on adding range support in a handler but couldn't find anything - I don't
have a clue how I might do this.

Roger

bruce barker said:
you actually have to add Range support to your handler, not just say you
have it and ignore the range requests. look at the request to see if
it has a range specified. a range specifies a offset and a length of
bytes to return. that is you don't stream the whole file per request,
just the bytes requested.

ie7 is probably precaching the video (maybe a bug).
 
Yes, that works for me, too. The problem is when you try to reposition the
slider either before playing or anytime after. Doing so causes the video to
be unplayable.
 
adding range support is easy. see the w3c http 1.1 spec for particulars. I
don't see how any streaming service could work reliably without range
support.

also be sure to turn buffering off.

-- bruce (sqlwork.com)


Roger Martin said:
Thanks Bruce. I just discovered that if I modify my handler to use WriteFile,
it works:

FileInfo fi = new FileInfo(filePath);
context.Response.WriteFile(filePath, false);

However, this is not a long term solution because WriteFile has issues with
large files (http://support.microsoft.com/kb/812406). I need a reliable way
to send files to the user that won't overwhelm the server's memory; that's
why I was using a chunked approach.

There is nothing about a range in the request header:
Frame: Number = 433, Captured Frame Length = 1027, MediaType = ETHERNET
+ Ethernet: Etype = Internet IP
(IPv4),DestinationAddress:[00-06-25-7F-45-9D],SourceAddress:[00-16-E6-8F-5E-9E]
+ Ipv4: Src = 192.168.1.102, Dest = 209.67.188.9, Next Protocol = TCP,
Packet ID = 31490, Total IP Length = 1013
+ Tcp: [ReTransmit #430]Flags=...AP..., SrcPort=63247, DstPort=HTTP(80),
PayloadLen=973, Seq=233417161 - 233418134, Ack=3634901546, Win=65535 (scale
factor 0x0) = 65535
- Http: Request, GET /dev/webapp2/handler/getmediaobject.ashx
Command: GET
- URI: /dev/webapp2/handler/getmediaobject.ashx
Location: /dev/webapp2/handler/getmediaobject.ashx
ProtocolVersion: HTTP/1.1
Host: www.galleryserverpro.com
UserAgent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.4)
Gecko/2008102920 Firefox/3.0.4 (.NET CLR 3.5.30729)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,nl;q=0.8,en;q=0.5,de-ch;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Cookie:
__utma=5214629.4168526968000403000.1223864238.1226617001.1226628470.137;
__utmz=5214629.1226167175.107.5.utmcsr=linkedin.com|utmccn=(referral)|utmcmd=referral|utmcct=/myprofile;
.ASPXANONYMOUS=ZqP1ljp8yQEkAAAAYTU1MmI2ODktMGI1Yy00Zjg3LTkzYTItMDlhMjdkN
HeaderEnd: CRLF

Given that it works using WriteFile and that there is no range in the
request, do you think I still need to add range support? I am doubtful but I
admit I am at the limits of my knowledge. Perhaps there is just a problem
with my chunking algorithm (see earlier for the code). I did a quick search
on adding range support in a handler but couldn't find anything - I don't
have a clue how I might do this.

Roger

bruce barker said:
you actually have to add Range support to your handler, not just say you
have it and ignore the range requests. look at the request to see if
it has a range specified. a range specifies a offset and a length of
bytes to return. that is you don't stream the whole file per request,
just the bytes requested.

ie7 is probably precaching the video (maybe a bug).
 
Buffering is already turned off, as you can see in the code I posted.

I am pretty sure that adding range functionality won't solve the issue. Note
that I am not actually streaming the video, in the strict definition of
streaming. I am simply transmitting a file, and Silverlight has the
capability to begin playing the video when it has buffered enough of the
downloaded video. Ranges are not used anywhere in the request or response,
even in the examples that work.

As I said before, you can see for yourself by looking at my examples.

If knew how to easily add range functionality, I would do it just to see.
But it is not at all clear (at least to me) how to do it based on the spec
(http://www.w3.org/Protocols/rfc2616/rfc2616.html).

Roger
 
Hi Roger,

Today I tested this page
http://www.galleryserverpro.com/dev/webapp2/video2.aspx

on the following machines:

Windows Server 2008 Enterprise SP1 64 bit + FireFox 3.0.3
Windows XP SP2 + FireFox 2.0.0.18
Winodws Server 2003 Enterprise SP2 32 bit + FireFox 3.0.4
Windows Server 2008 Standard SP1 64 bit + FireFox 3.0.4
Windows XP SP3 + IE 6.0.2900.5512

However, I cannot reproduce this issue. Bruce, can you reproduce this issue
on your side?
I'll update here if I find a machine that can repro it.

Regards,
Allen Chen
Microsoft Online Support

--------------------
| Thread-Topic: Cannot jump to new part of Silverlight video when using
handle
| thread-index: AclGfp9QM5BIKWGVRvyn/OKGRjmjaw==
| From: =?Utf-8?B?Um9nZXIgTWFydGlu?= <[email protected]>
| References: <[email protected]>
<[email protected]>
<[email protected]>
<[email protected]>
<[email protected]>
<[email protected]>
| Subject: Re: Cannot jump to new part of Silverlight video when using
handle
| Date: Fri, 14 Nov 2008 09:30:01 -0800
| Lines: 24
| Message-ID: <[email protected]>
| MIME-Version: 1.0
| Content-Type: text/plain;
| charset="Utf-8"
| Content-Transfer-Encoding: 7bit
| X-Newsreader: Microsoft CDO for Windows 2000
| Content-Class: urn:content-classes:message
| Importance: normal
| Priority: normal
| X-MimeOLE: Produced By Microsoft MimeOLE V6.00.3790.3168
| Newsgroups: microsoft.public.dotnet.framework.aspnet
| Path: TK2MSFTNGHUB02.phx.gbl
| Xref: TK2MSFTNGHUB02.phx.gbl
microsoft.public.dotnet.framework.aspnet:79899
| NNTP-Posting-Host: tk2msftibfm01.phx.gbl 10.40.244.149
| X-Tomcat-NG: microsoft.public.dotnet.framework.aspnet
|
| Buffering is already turned off, as you can see in the code I posted.
|
| I am pretty sure that adding range functionality won't solve the issue.
Note
| that I am not actually streaming the video, in the strict definition of
| streaming. I am simply transmitting a file, and Silverlight has the
| capability to begin playing the video when it has buffered enough of the
| downloaded video. Ranges are not used anywhere in the request or
response,
| even in the examples that work.
|
| As I said before, you can see for yourself by looking at my examples.
|
| If knew how to easily add range functionality, I would do it just to see.
| But it is not at all clear (at least to me) how to do it based on the
spec
| (http://www.w3.org/Protocols/rfc2616/rfc2616.html).
|
| Roger
|
| "bruce barker" wrote:
|
| > adding range support is easy. see the w3c http 1.1 spec for
particulars. I
| > don't see how any streaming service could work reliably without range
| > support.
| >
| > also be sure to turn buffering off.
|
 
I appreciate your effort in trying to repro it. Just to be clear, here are
the steps:

1. Load the page http://www.galleryserverpro.com/dev/webapp2/video2.aspx.
2. Wait for the video to download (the progress bar goes all the way to the
right).
3. Using the mouse, click the position indicator and drag to a new position.
Release the mouse button.
4. A set of circles will rotate around the number zero in the center of the
video.

At this point the video will not run when you click play. (In my tests, the
only browser where it *does* work is IE7.)

Thanks for your persistence, Allen.

Roger
 
Hi Roger,

I followed exactly the same steps as you mentioned but still cannot
reproduce this issue. It's really strange. Could you outline all the
machines and browsers that you have tested? Maybe we can find some clues
from it. (Please provide the detailed information, such as Windows Server
2008 Enterprise SP1 64 bit + FireFox 3.0.3)

In addition, please run Network Monitor on the working machine and the
non-working machine. Then track the frame of the response of the ashx. Can
you find any differences?

Regards,
Allen Chen
Microsoft Online Community Support
 
Hi Roger,

Do you have any progress on this issue? Can you get any clues with the help
of Network Monitor?

Regards,
Allen Chen
Microsoft Online Community Support
 
I haven't seen a response in a while, so I polled my web site visitors to
determine the extent of the issue. I asked them to try the link
http://www.galleryserverpro.com/dev/webapp2/video2.aspx. Here are the results:

User 1: IE7, Vista SP1 32-bit and Win2008 x64 (works)
User 2: IE7, WinXP (works)
User 3: IE7, WinXP (works)
User 4: IE7, Vista (works)
User 4: Firefox 3.04, Vista (DOES NOT WORK)
User 5: IE7, Vista (works)
User 5: Firefox 3.04, Vista (DOES NOT WORK)

By not working, I am referring to the inability to reposition the video
timeline and subsequently play the video.

This pattern is consistent with my experience: IE7 works and Firefox does not.

The Firefox users reported their installed add-ons but there isn't a common
one between us all to be suspicious of.

Please let me know what else I can do to help solve the problem. I need to
figure it out. Thanks.

Roger
Gallery Server Pro
http://www.galleryserverpro.com
 
Hi Roger,

Thanks for your update.

Quote from Roger ==================================================
User 4: Firefox 3.04, Vista (DOES NOT WORK)
==================================================

Is it Vista SP1? 32 bit or 64 bit?

I tested Firefox 3.04, Vista SP1 64bit and it works fine.

Another possible reason I guess, are your users using proxy in FireFox?

To find the root cause I think it would be a good start if we can find a
working machine and a non-working one. On my side it seems every machine is
fine. I'll try to find a non-working one. On your side, could you try to
find a Firefox 3.04 + Vista machine that works? By comparing these two
machines we may get some clues.

Regards,
Allen Chen
Microsoft Online Support
 
I got it! It turns out that Firefox is not forgiving when the bytes sent is
different than the bytes specified in the Content-Length header. And the
reason why the bytes sent is different is because the handler sends the data
in blocks of 32768 bytes, even when the final block does not have a full
32768 bytes of data.

The solution was to modify the chunking loop so that the last chunk of bytes
is only big as the data it contains.

Every code sample I found on the internet - and there were dozens - had poor
performance or at least one bug that caused it to fail.

So, drum roll please, here is a proper algorithm for streaming data to a
browser in an HTTP handler. This works for any kind of data and is superior
to other methods (TransmitFile, WriteFile, etc) when streaming very large
files like video. (Of course you need to modify the ContentType to your MIME
type.) And it definitely works for streaming data to Silverlight in all the
supported browsers.

private void ProcessMediaObject(HttpContext context, string filePath)
{
FileStream fileStream = null;
try
{
context.Response.Clear();
context.Response.ContentType = "video/x-ms-wmv";
context.Response.Buffer = false;

HttpCachePolicy cachePolicy = context.Response.Cache;
cachePolicy.SetExpires(System.DateTime.Now.AddSeconds(2592000)); // 30 days
cachePolicy.SetCacheability(HttpCacheability.Public);
cachePolicy.SetValidUntilExpires(true);

const int bufferSize = 32768;
byte[] buffer = new byte[bufferSize];
fileStream = File.OpenRead(filePath);
context.Response.AddHeader("Content-Length", fileStream.Length.ToString());
int byteCount;
while ((byteCount = fileStream.Read(buffer, 0, buffer.Length)) > 0)
{
if (context.Response.IsClientConnected)
{
context.Response.OutputStream.Write(buffer, 0, byteCount);
context.Response.Flush();
}
else
{
return;
}
}
}
finally
{
if (fileStream != null)
fileStream.Close();

context.Response.End();
}
}

Cheers,
Roger Martin
Lead Developer, Gallery Server Pro
http://www.galleryserverpro.com
 
Hi Roger,

I'm happy to know that this issue has been solved. Thanks for sharing the
solution with us.

Regards,
Allen Chen
Microsoft Online Support
 
Back
Top