从ASP.NET MVC2向iPhone提供视频文件

前端之家收集整理的这篇文章主要介绍了从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:\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);
}

我真的希望这有帮助.我花了大量的时间在这个!你可能想要尝试的一件事是删除碎片,直到它再次破裂.看看ETag的东西,修改的日期等是否可以被删除是很好的.我现在没有时间.

快乐编码!

原文链接:https://www.f2er.com/aspnet/246358.html

猜你在找的asp.Net相关文章