gpt4 book ai didi

iphone - 从 ASP.NET MVC2 将视频文件提供给 iPhone

转载 作者:行者123 更新时间:2023-12-03 18:31:52 24 4
gpt4 key购买 nike

我正在尝试将视频文件从 ASP.NET MVC 提供给 iPhone 客户端。该视频的格式正确,如果我将其放在可公开访问的网络目录中,它就可以正常工作。

我读到的核心问题是,iPhone 要求您有一个可恢复的下载环境,让您可以通过 HTTP header 过滤字节范围。我认为这是为了让用户可以跳过视频。

当使用 MVC 提供文件时,这些 header 不存在。我试图模仿它,但没有运气。我们这里有 IIS6,我根本无法进行许多 header 操作。 ASP.NET 会向我提示“此操作需要 IIS 集成管道模式。

无法升级,而且我也无法将文件移动到公共(public)网络共享。我感到自己受到环境的限制,但我仍在寻找解决方案。

这里是我想要做的一些示例代码...

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 响应 header 示例:

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。它有点脏,因为它比我预期的要困难一些,而且现在它正在工作,我现在没有时间清理它。关键部分:

Action 过滤器:

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, 0, bytesRemaining);
else
count = FileStream.Read(buffer, 0, buffer.Length);

outputStream.Write(buffer, 0, count);
bytesRemaining -= count;
}
}
}
}

我的 MVC 操作:

[ByteRangeRequest("StartByte", "EndByte")]
public FileStreamResult NextSegment(int? StartByte, int? EndByte)
{
FileStream contentFileStream = System.IO.File.OpenRead(@"C:\temp\Gets.mp4");
var time = System.IO.File.GetLastWriteTime(@"C:\temp\Gets.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.Length, time, "video/x-m4v", contentFileStream);
}

我真的希望这有帮助。我在这上面花了很多时间!您可能想要尝试的一件事是移除碎片,直到它再次破裂。很高兴看到 ETag 内容、修改日期等是否可以被删除。我只是现在没有时间。

祝你编码愉快!

关于iphone - 从 ASP.NET MVC2 将视频文件提供给 iPhone,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4127756/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com