流式传输大型视频文件 .net [英] Streaming large video files .net

查看:38
本文介绍了流式传输大型视频文件 .net的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从 HttpHandler 以 webforms 流式传输一个大文件.它似乎不起作用,因为它没有流式传输文件.相反,它将文件读入内存,然后将其发送回客户端.我四处寻找解决方案,解决方案告诉我他们在做同样的事情时流式传输文件.我的流解决方案是这样的:

I am trying to stream a large file in webforms from an HttpHandler. It doesn't seem to work because its not streaming the file. Instead its reading the file into memory then sends it back to the client. I look all over for a solution and the solution are telling me that they stream the file when they are doing the same thing. My solution that stream is this:

using (Stream fileStream = File.OpenRead(path))
{
    context.Response.Cache.SetExpires(DateTime.UtcNow.AddMinutes(360.0));
    context.Response.Cache.SetCacheability(HttpCacheability.Public);
    context.Response.AppendHeader("Content-Type", "video/mp4");
    context.Response.AppendHeader("content-length", file.Length);
    byte[] buffer = new byte[1024];
    while (true)
    {
      if (context.Response.IsClientConnected)
     {
       int bytesRead = fileStream.Read(buffer, 0, buffer.Length);
       if (bytesRead == 0) break;
       context.Response.OutputStream.Write(buffer, 0, bytesRead);
       context.Response.Flush();
     }
     else
     {
       break;
     }

   }
   context.Response.End();
}

如果我调试代码,发生的是小文件,它会播放视频,但直到它到达 context.Respond.End() 行.但是对于大文件,这不起作用,因为它将整个文件存储在内存中,这会带来问题.

What is happening is for small files if I debug the code, it will play the video but not until it reaches the context.Respond.End() line. But for large files this will not work because it is storing the whole file in memory which will bring issues.

推荐答案

我遇到了类似的问题,视频必须完全下载才能播放.

I had a similar issue, where the video had to be downloaded completely before playing.

我可以看出您想要流式传输视频,更具体地说.你必须小心编码(确保它是可流式传输的),不要只依赖扩展名,因为创建文件的人可能会以一种奇怪的方式构建视频,但是 99% 的时间你应该好.我使用 mediainfo.在你的情况下应该是 H.264.

I can see you want to stream videos, to be more specific. You have to be careful about the encoding (make sure it is streamable), don't rely on the extension only, because the person who created the file could have build the video in a wierd way, but 99% of the time you should be good. I use mediainfo. In your case should be H.264.

它还取决于浏览器和您用于流式传输的内容(后端代码除外).就我而言,我使用了 Chrome/Html5 和 .webm (VP8/Ogg Vorbis).它适用于超过 1G 的文件.没有测试大于4G...

It also depends on browser and what you use to stream (other than backend code). For my case, I used Chrome/Html5 and .webm (VP8/Ogg Vorbis). It is working for files over 1G. Didn't test for bigger than 4G...

我用于下载视频的代码:

The code I use for download of the video:

    public void Video(string folder, string name) {
        string filepath = Server.MapPath(String.Format("{0}{1}", HttpUtility.UrlDecode(folder), name));
        string filename = name;

        System.IO.Stream iStream = null;
        byte[] buffer = new Byte[4096];
        int length;
        long dataToRead;

        try {
            // Open the file.
            iStream = new System.IO.FileStream(filepath, System.IO.FileMode.Open,
                        System.IO.FileAccess.Read, System.IO.FileShare.Read);


            // Total bytes to read:
            dataToRead = iStream.Length;

            Response.AddHeader("Accept-Ranges", "bytes");
            Response.ContentType = MimeType.GetMIMEType(name);

            int startbyte = 0;

            if (!String.IsNullOrEmpty(Request.Headers["Range"])) {
                string[] range = Request.Headers["Range"].Split(new char[] { '=', '-' });
                startbyte = Int32.Parse(range[1]);
                iStream.Seek(startbyte, SeekOrigin.Begin);

                Response.StatusCode = 206;
                Response.AddHeader("Content-Range", String.Format(" bytes {0}-{1}/{2}", startbyte, dataToRead - 1, dataToRead));
            }

            while (dataToRead > 0) {
                // Verify that the client is connected.
                if (Response.IsClientConnected) {
                    // Read the data in buffer.
                    length = iStream.Read(buffer, 0, buffer.Length);

                    // Write the data to the current output stream.
                    Response.OutputStream.Write(buffer, 0, buffer.Length);
                    // Flush the data to the HTML output.
                    Response.Flush();

                    buffer = new Byte[buffer.Length];
                    dataToRead = dataToRead - buffer.Length;
                } else {
                    //prevent infinite loop if user disconnects
                    dataToRead = -1;
                }
            }
        } catch (Exception ex) {
            // Trap the error, if any.
            Response.Write("Error : " + ex.Message);
        } finally {
            if (iStream != null) {
                //Close the file.
                iStream.Close();
            }
            Response.Close();
        }
    }

确保您的响应标头包含您需要的所有内容.

Make sure your response header contains everything you need.

这篇关于流式传输大型视频文件 .net的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆