问题
We're using a FileStreamResult to provide video data to a Silverlight MediaElement based video player:
public ActionResult Preview(Guid id) {
return new FileStreamResult(
Services.AssetStore.GetStream(id, ContentType.Preview),
"application/octet-stream");
}
Unfortunately, the Silverlight video player downloads the entire video file before it starts playing. This behavior is expected as our Preview
Action does not support downloading partial content.
(side note: if the file is hosted in an IIS virtual directory we can start playback at any location in the video while it is still downloading. however for security and auditing reasons we can't provide a direct download link. so this is not an option.)
How can we improve the Controller Action to support partial HTTP content?
I assume we first have to inform the client that we support it (adding an "Accept-Ranges:bytes" header to a HEAD request), then we have to evaluate the HTTP "Range" header and stream the requested file range with a response code of 206. Will that work with ASP.NET MVC hosted on IIS6? Is there already some code available?
Also see:
- http://en.wikipedia.org/wiki/List_of_HTTP_headers
- http://blogs.msdn.com/anilkumargupta/archive/2009/04/29/downloadprogress-downloadprogressoffset-and-bufferprogress-of-the-mediaelement.aspx
- http://benramsey.com/archives/206-partial-content-and-range-requests/
回答1:
There is a project on CodePlex which gives this exact functionality.
http://mediastreamingmvc.codeplex.com/
Take a look. It was created specifically for this scenario where you want to have an action representing a request for a virtual resource and return partial content if so requested without requiring the developer to do much to support it (an Action Filter and choice of Result types.)
回答2:
- You have to implement this by yourself. And yes, this will work on IIS6.
- If you can use IIS7 you probably better to leverage on IIS7 extensibility (example).
回答3:
Then you need to reimplement throttling module :)
The idea is to calculate bitrate of your video stream and then send as much as required to client. So you need (very briefly) to read a block from your stream and send it to client and sleep for a second.
Thread.Sleep(1000) is not really a good idea for handling IIS resources so you need to do stuff in async way. IAsyncResult will be your friend.
There is much room for all kinds of optimisations.
And the last thing... I made it working as plain httphandler, not as MVC ActionResult. If it's possible in your webiste, I'm recommending to do it as a handler.
来源:https://stackoverflow.com/questions/1158022/how-to-stream-partial-content-with-asp-net-mvc-filestreamresult