从ASP.NET MVC2向iPhone提供视频文件
|
我正在尝试从ASP.NET MVC向iPhone客户端提供视频文件.视频格式正确,如果我在一个可公开访问的网络目录中可以正常工作. 从我所看到的核心问题是,iPhone需要您有一个简易的下载环境,让您可以通过HTTP头过滤字节范围.我认为这是为了让用户可以通过视频跳过. 当使用MVC提供文件时,这些标题不存在.我试图效仿它,但没有运气.我们在这里有IIS6,我根本无法做许多标题操作. ASP.NET会抱怨说“这个操作需要IIS集成管道模式”. 升级不是一个选项,我不允许将文件移动到公共Web共享.我感觉到我们的环境受到限制,但我正在寻找解决方案. 以下是我正在努力做的一些示例代码 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 有任何想法吗?谢谢. 解决方法更新:现在是 project on CodePlex.好的,我在本地的测试台上工作,我可以将视频流传输到我的iPad.这有点肮脏,因为它比我预期的要困难得多,而且现在工作我没有时间来清理它.关键部件: 行动过滤器 public class ByteRangeRequest : FilterAttribute,IActionFilter
{
protected string RangeStart { get; set; }
protected string RangeEnd { get; set; }
public ByteRangeRequest(string RangeStartParameter,string RangeEndParameter)
{
RangeStart = RangeStartParameter;
RangeEnd = RangeEndParameter;
}
public void OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext == null)
throw new ArgumentNullException("filterContext");
if (!filterContext.ActionParameters.ContainsKey(RangeStart))
filterContext.ActionParameters.Add(RangeStart,null);
if (!filterContext.ActionParameters.ContainsKey(RangeEnd))
filterContext.ActionParameters.Add(RangeEnd,null);
var headerKeys = filterContext.RequestContext.HttpContext.Request.Headers.AllKeys.Where(key => key.Equals("Range",StringComparison.InvariantCultureIgnoreCase));
Regex rangeParser = new Regex(@"(d+)-(d+)",RegexOptions.Compiled);
foreach(string headerKey in headerKeys)
{
string value = filterContext.RequestContext.HttpContext.Request.Headers[headerKey];
if (!string.IsNullOrEmpty(value))
{
if (rangeParser.IsMatch(value))
{
Match match = rangeParser.Match(value);
filterContext.ActionParameters[RangeStart] = int.Parse(match.Groups[1].ToString());
filterContext.ActionParameters[RangeEnd] = int.Parse(match.Groups[2].ToString());
break;
}
}
}
}
public void OnActionExecuted(ActionExecutedContext filterContext)
{
}
}
基于FileStreamResult的自定义结果: public class ContentRangeResult : FileStreamResult
{
public int StartIndex { get; set; }
public int EndIndex { get; set; }
public long TotalSize { get; set; }
public DateTime LastModified { get; set; }
public FileStreamResult(int startIndex,int endIndex,long totalSize,DateTime lastModified,string contentType,Stream fileStream)
: base(fileStream,contentType)
{
StartIndex = startIndex;
EndIndex = endIndex;
TotalSize = totalSize;
LastModified = lastModified;
}
public override void ExecuteResult(ControllerContext context)
{
if (context == null)
throw new ArgumentNullException("context");
HttpResponseBase response = context.HttpContext.Response;
response.ContentType = this.ContentType;
response.AddHeader(HttpWorkerRequest.GetKnownResponseHeaderName(HttpWorkerRequest.HeaderContentRange),string.Format("bytes {0}-{1}/{2}",StartIndex,EndIndex,TotalSize));
response.StatusCode = 206;
WriteFile(response);
}
protected override void WriteFile(HttpResponseBase response)
{
Stream outputStream = response.OutputStream;
using (this.FileStream)
{
byte[] buffer = new byte[0x1000];
int totalToSend = EndIndex - StartIndex;
int bytesRemaining = totalToSend;
int count = 0;
FileStream.Seek(StartIndex,SeekOrigin.Begin);
while (bytesRemaining > 0)
{
if (bytesRemaining <= buffer.Length)
count = FileStream.Read(buffer,bytesRemaining);
else
count = FileStream.Read(buffer,buffer.Length);
outputStream.Write(buffer,count);
bytesRemaining -= count;
}
}
}
}
我的MVC动作: [ByteRangeRequest("StartByte","EndByte")]
public FileStreamResult NextSegment(int? StartByte,int? EndByte)
{
FileStream contentFileStream = System.IO.File.OpenRead(@"C:tempGets.mp4");
var time = System.IO.File.GetLastWriteTime(@"C:tempGets.mp4");
if (StartByte.HasValue && EndByte.HasValue)
return new ContentRangeResult(StartByte.Value,EndByte.Value,contentFileStream.Length,time,"video/x-m4v",contentFileStream);
return new ContentRangeResult(0,(int)contentFileStream.Length,contentFileStream);
}
我真的希望这有帮助.我花了大量的时间在这个!你可能想要尝试的一件事是删除碎片,直到它再次破裂.看看ETag的东西,修改的日期等是否可以被删除是很好的.我现在没有时间. 快乐编码! (编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- asp.net – 如何快速进行HTML渲染
- 禁用ASP.NET HttpHandler响应缓存
- asp.net-mvc – 更改项目URL Visual Studio
- asp.net-mvc-3 – MVC 3 $.ajax – 响应似乎是从部分视图缓
- asp.net – Web Api参数始终为null
- Asp.Net成员 – 实体框架4中的提供商
- ASP.NET 5,.NET Core和ASP.NET Core 5有什么区别?
- asp.net-mvc – asp.net mvc 3预选Html.DropDownListFor不能
- asp.net – 自定义Web字体在IE9中不起作用
- ASP.net会话状态服务信息
- asp.net-mvc – 使用Ninject.Web.Mvc 2.0和ASP.N
- 什么是ASP.Net相当于PHP的回声?
- asp.net+Ajax 文本文件静态分页实现代码
- asp.net – 如何在单独的dll项目中配置WCF
- asp.net – 在div点击执行serverside代码
- asp.net – 无法在应用程序级别下定义元素’buil
- asp.net-core – 如何使用Identity Server 4使用
- asp.net – 新的dotnet核心项目无法恢复
- 与asp.net mvc的dotnetopenauth证明太沮丧使用
- asp.net-mvc – 使用Html.RouteLink添加一个css类
