当标头包含接受范围时,视频流出现问题

时间:2014-06-14 13:15:05

标签: c# asp.net-mvc video-streaming

我正在尝试使用accept-ranges从服务器流式传输视频,以允许用户更改客户端视频播放器(在我的情况下是jwplayer)中的位置

当包含accept-ranges代码时,客户端(jwplayer或仅在chrome中直接从url打开)正常播放约15s,并且在每个块询问新请求之后,实际上在15秒之后只通过方法只有一次,在Response.Flush()之内或之后连接中断,没有任何错误(有时Flush()获取错误代码0x800704CD0x800703E30x80070016约10%请求),之后是Response.IsClientConnected=false所以方法结束。

要求客户提供范围,例如123456-empty,没有指定范围的结束部分。

我猜这不是正确的行为,也许在Response上有错误的标题..或者是正常的,客户端视频播放器是否正在为每个块创建新的请求?实际上它占用了我的PC大约80%的CPU。

问题仅在于流媒体视频和何时同时创建了大量新请求,在通常情况下下载文件时,例如在建立损坏的下载时没有问题。

当缺少接受范围代码时,视频流中没有问题,所有服务器 - >客户端传输都在while循环中,并且仅在用户中断连接方法时结束。

This solution is running under ASP.NET MVC4

目前使用的代码:

    public void Method()
    {
        string path = @"filePath.mp4";
        FileInfo file = new FileInfo(path);
        long fileLength = file.Length;

        byte[] buffer = new byte[64 * 1024];
        long dataToRead = fileLength;
        long startbyte = 0;
        long location = 0;
        long readLength = 0;

        Response.AddHeader("Accept-Ranges", "bytes");
        Response.ContentType = "video/mp4";

        if (!String.IsNullOrEmpty(Request.Headers["Range"]))
        {
            string[] range = Request.Headers["Range"].Split(new char[] { '=', '-' });
            location = long.Parse(range[1]);
            if (location >= 0 && location <= fileLength)
            {
                Response.StatusCode = 206;
                Response.AddHeader("content-range", String.Format(" bytes {0}-{1}/{2}", location, fileLength - 1, fileLength));
                startbyte = location;
                dataToRead = fileLength - startbyte;
                Response.AppendHeader("content-length", dataToRead.ToString());
            }
        }
        else
        {
            Response.StatusCode = 200;
            Response.AddHeader("Content-Range", String.Format(" bytes {0}-{1}/{2}", 0, fileLength - 1, fileLength));
            Response.AppendHeader("content-length", fileLength.ToString());
        }

        try
        {
            using (Stream stream = System.IO.File.OpenRead(path))
            {
                if (startbyte > 0)
                {
                    stream.Seek(startbyte, SeekOrigin.Begin);
                }

                while (dataToRead > 0)
                {
                    if (Response.IsClientConnected)
                    {
                        readLength = stream.Read(buffer, 0, buffer.Length);

                        Response.OutputStream.Write(buffer, 0, (int)readLength);
                        Response.Flush();

                        dataToRead = dataToRead - readLength;
                    }
                    else
                    {
                        dataToRead = -1;
                    }
                }
            }
        }
        catch (EndOfStreamException endStream)
        {
            Log.Error(endStream.Message, endStream);
        }
        catch (TimeoutException timeout)
        {
            Log.Error(timeout.Message, timeout);
        }
        catch (Exception e)
        {
            Log.Error(e.Message, e);
        }
        finally
        {
            Response.End();
        }
    }

0 个答案:

没有答案