从 ASP.NET MVC2 将视频文件提供给 iPhone
我正在尝试将视频文件从 ASP.NET MVC 提供给 iPhone 客户端。该视频的格式正确,如果我将其放在可公开访问的网络目录中,它就可以正常工作。
我读到的核心问题是 iPhone 要求您有一个可恢复的下载环境,让您可以通过 HTTP 标头过滤字节范围。我认为这是为了让用户可以跳过视频。
当使用 MVC 提供文件时,这些标头不存在。我试图模仿它,但没有运气。我们这里有 IIS6,我根本无法进行许多标头操作。 ASP.NET 会向我抱怨说“此操作需要 IIS 集成管道模式。”
升级不是一个选项,并且我不允许将文件移动到公共网络共享。我感到受到我们的环境的限制,但我仍在寻找解决方案。
简而言之,这里是我想要做的一些示例代码...
public ActionResult Mobile(string guid = "x")
{
guid = Path.GetFileNameWithoutExtension(guid);
apMedia media = DB.apMedia_GetMediaByFilename(guid);
string mediaPath = Path.Combine(Transcode.Swap_MobileDirectory, guid + ".m4v");
if (!Directory.Exists(Transcode.Swap_MobileDirectory)) //Make sure it's there...
Directory.CreateDirectory(Transcode.Swap_MobileDirectory);
if(System.IO.File.Exists(mediaPath))
return base.File(mediaPath, "video/x-m4v");
return Redirect("~/Error/404");
}
我知道我需要做这样的事情,但是我无法在 .NET MVC 中做到这一点。 http://dotnetslackers.com/articles/aspnet/Range -Specific-Requests-in-ASP-NET.aspx
下面是一个有效的 HTTP 响应头示例:
Date Mon, 08 Nov 2010 17:02:38 GMT
Server Apache
Last-Modified Mon, 08 Nov 2010 17:02:13 GMT
Etag "14e78b2-295eff-4cd82d15"
Accept-Ranges bytes
Content-Length 2711295
Content-Range bytes 0-2711294/2711295
Keep-Alive timeout=15, max=100
Connection Keep-Alive
Content-Type text/plain
这是一个无效的示例(来自 .NET)
Server ASP.NET Development Server/10.0.0.0
Date Mon, 08 Nov 2010 18:26:17 GMT
X-AspNet-Version 4.0.30319
X-AspNetMvc-Version 2.0
Content-Range bytes 0-2711294/2711295
Cache-Control private
Content-Type video/x-m4v
Content-Length 2711295
Connection Close
有什么想法吗?谢谢。
I'm attempting to serve video files from ASP.NET MVC to iPhone clients. The video is formatted properly, and if I have it in a publicly accessible web directory it works fine.
The core issue from what I've read is that the iPhone requires you to have a resume-ready download environment that lets you filter your byte ranges through HTTP headers. I assume this is so that users can skip forward through videos.
When serving files with MVC, these headers do not exist. I've tried to emulate it, but with no luck. We have IIS6 here and I'm unable to do many header manipulations at all. ASP.NET will complain at me saying "This operation requires IIS integrated pipeline mode."
Upgrading isn't an option, and I'm not allowed to move the files to a public web share. I feel limited by our environment but I'm looking for solutions nonetheless.
Here is some sample code of what I'm trying to do in short...
public ActionResult Mobile(string guid = "x")
{
guid = Path.GetFileNameWithoutExtension(guid);
apMedia media = DB.apMedia_GetMediaByFilename(guid);
string mediaPath = Path.Combine(Transcode.Swap_MobileDirectory, guid + ".m4v");
if (!Directory.Exists(Transcode.Swap_MobileDirectory)) //Make sure it's there...
Directory.CreateDirectory(Transcode.Swap_MobileDirectory);
if(System.IO.File.Exists(mediaPath))
return base.File(mediaPath, "video/x-m4v");
return Redirect("~/Error/404");
}
I know that I need to do something like this, however I'm unable to do it in .NET MVC. http://dotnetslackers.com/articles/aspnet/Range-Specific-Requests-in-ASP-NET.aspx
Here is an example of an HTTP response header that works:
Date Mon, 08 Nov 2010 17:02:38 GMT
Server Apache
Last-Modified Mon, 08 Nov 2010 17:02:13 GMT
Etag "14e78b2-295eff-4cd82d15"
Accept-Ranges bytes
Content-Length 2711295
Content-Range bytes 0-2711294/2711295
Keep-Alive timeout=15, max=100
Connection Keep-Alive
Content-Type text/plain
And here is an example of one that doesn't (this is from .NET)
Server ASP.NET Development Server/10.0.0.0
Date Mon, 08 Nov 2010 18:26:17 GMT
X-AspNet-Version 4.0.30319
X-AspNetMvc-Version 2.0
Content-Range bytes 0-2711294/2711295
Cache-Control private
Content-Type video/x-m4v
Content-Length 2711295
Connection Close
Any ideas? Thank you.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
更新:这现在是 CodePlex 上的一个 项目。
好的,我已经在本地测试站上运行了,并且可以将视频传输到我的 iPad 上。它有点脏,因为它比我预期的要困难一些,而且现在它正在工作,我现在没有时间清理它。关键部分:
操作过滤器:
基于 FileStreamResult 的自定义结果:
我的 MVC 操作:
我真的希望这会有所帮助。我在这上面花了很多时间!您可能想要尝试的一件事是移除碎片,直到它再次破裂。很高兴看到 ETag 内容、修改日期等是否可以被删除。我只是现在没有时间。
快乐编码!
UPDATE: This is now a project on CodePlex.
Okay, I got it working on my local testing station and I can stream videos to my iPad. It's a bit dirty because it was a little more difficult than I expected and now that it's working I don't have the time to clean it up at the moment. Key parts:
Action Filter:
Custom Result based on FileStreamResult:
My MVC action:
I really hope this helps. I spent a LOT of time on this! One thing you might want to try is removing pieces until it breaks again. It would be nice to see if the ETag stuff, modified date, etc. could be removed. I just don't have the time at the moment.
Happy coding!
我尝试寻找现有的扩展,但我没有立即找到一个(也许我的搜索功能很弱。)
我立即想到的是,您需要创建两个新类。
首先,创建一个继承自
ActionMethodSelectorAttribute
的类。这与HttpGet
、HttpPost
等的基类相同。在此类中,您将重写IsValidForRequest
。在该方法中,检查标头以查看是否请求了范围。现在,您可以使用此属性来装饰控制器中的一个方法,当有人请求流的一部分(iOS、Silverlight 等)时,该方法将被调用。其次,创建一个继承自
ActionResult
或也许是FileResult
并重写ExecuteResult
方法来添加您为要返回的字节范围确定的标头。像返回 JSON 对象一样返回它,其中包含字节范围开始、结束、总大小的参数,以便它可以正确生成响应标头。查看
FileContentResult
的实现方式,了解如何访问上下文的HttpResponse
对象来更改标头。查看
HttpGet
以了解它如何实现对IsValidForRequest
的检查。源代码可以在 CodePlex 上找到,或者您也可以像我刚才那样使用 Reflector。您可以使用此信息进行更多搜索,看看是否有人已经创建了此自定义
ActionResult
。作为参考,AcceptVerbs 属性如下所示:
FileResult 如下所示。请注意 AddHeader 的使用:
我只是将其拼凑在一起。我不知道它是否适合您的需求(或工作)。
像这样使用它:
I tried looking for an existing extension but I didn't immediately find one (maybe my search-fu is weak.)
My immediate thought is that you'll need to make two new classes.
First, create a class inheriting from
ActionMethodSelectorAttribute
. This is the same base class forHttpGet
,HttpPost
, etc. In this class you'll overrideIsValidForRequest
. In that method, examine the headers to see if a range was requested. You can now use this attribute to decorate a method in your controller which will get called when someone is requested part of a stream (iOS, Silverlight, etc.)Second, create a class inheriting from either
ActionResult
or maybeFileResult
and override theExecuteResult
method to add the headers you identified for the byte range that you'll be returning. Return it like you would a JSON object with parameters for the byte range start, end, total size so it can generate the response headers correctly.Take a look at the way
FileContentResult
is implemented to see how you access the context'sHttpResponse
object to alter the headers.Take a look at
HttpGet
to see how it implements the check forIsValidForRequest
. The source is available on CodePlex or you can use Reflector like I just did.You might use this info to do a little more searching and see if anyone has already created this custom
ActionResult
already.For reference, here is what the AcceptVerbs attribute looks like:
And here is what FileResult looks like. Notice the use of AddHeader:
I just pieced this together. I don't know if it will suit your needs (or works).
Use it like this:
您可以移出 MVC 吗?在这种情况下,系统抽象会搬起石头砸你的脚,但是一个简单的 IHttpHandler 应该有更多的选择。
话虽如此,在实现自己的流媒体服务器之前,您最好购买或租用一台。 。 。
Can you move outside of MVC? This is a case where the system abstractions are shooting you in the foot, but a plain jane IHttpHandler should have alot more options.
All that said, before you implement your own streaming server, you are probably better off buying or renting one . . .
有效的标头将内容类型设置为文本/纯文本,这是正确的还是拼写错误?
任何人,您都可以尝试使用以下方法在操作上设置此标头:
The header that work have the Content-type set to text/plain, is that correct or is a typo?.
Anyone, you can try to set this headers on the Action with: