C# 来自数据库的视频流

C# 来自数据库的视频流,c#,asp.net,sql-server-2008,asp.net-mvc-4,video,C#,Asp.net,Sql Server 2008,Asp.net Mvc 4,Video,我正在尝试执行一个操作以显示数据库中的媒体(ASP.NET MVC4): 图片显示正常,但当我要在Chrome或Firefox中链接mysite/media/4时,视频(.avi)出现问题,它会显示: <embed width="100%" height="100%" name="plugin" src="http://mysite/media/4" type="video/x-msvideo"> 我做错了什么?我想有一个链接,可以在中使用,以便在页面上显示此视频 更新1: 如果我

我正在尝试执行一个操作以显示数据库中的媒体(ASP.NET MVC4):

图片显示正常,但当我要在Chrome或Firefox中链接mysite/media/4时,视频(.avi)出现问题,它会显示:

<embed width="100%" height="100%" name="plugin" src="http://mysite/media/4" type="video/x-msvideo">
我做错了什么?我想有一个链接,可以在
中使用,以便在页面上显示此视频

更新1: 如果我为物理视频文件键入url,则得到的响应没有任何意义:

HTTP/1.1 304 Not Modified
Last-Modified: Tue, 05 Nov 2013 17:07:56 GMT
Accept-Ranges: bytes
ETag: "5d50369249dace1:0"
Server: Microsoft-IIS/7.5
X-Powered-By: ASP.NET
Date: Wed, 06 Nov 2013 11:20:32 GMT
但它可以使用内置VLC播放器插件在浏览器中播放视频

更新2: 我尝试了不同的实现来返回视频,并尝试将链接放到
对象的
src

<object id="video-player" class="preview-container" type="video/x-msvideo" src="{link to video}" loop="true" controls="false" autoplay="true"></object>
而且它很有效。好啊然后,我使用与Handler相同的逻辑执行操作:

[HttpGet]
public void Media(int id)
{
    MediaContent mediaContent;
    //getting mediaContent

    Response.Clear();
    Response.Buffer = true;
    Response.AppendHeader("Content-Disposition", "inline; filename=" + mediaContent.File.Filename);
    Response.ContentType = MimeMapping.GetMimeMapping(mediaContent.File.Filename);
    Response.BinaryWrite(mediaContent.File.FileData.Data);
    Response.End();
}
但是这个动作仍然不适用于视频,我开始比较响应头

处理程序:

HTTP/1.1 200 OK
Cache-Control: private
Content-Type: video/x-msvideo
Server: Microsoft-IIS/7.5
Content-Disposition: inline; filename=Reebok_App_attract640L.avi
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Wed, 06 Nov 2013 17:02:45 GMT
Content-Length: 808680
行动:

HTTP/1.1 200 OK
Cache-Control: private, s-maxage=0
Content-Type: video/x-msvideo
Transfer-Encoding: chunked
Server: Microsoft-IIS/7.5
X-AspNetMvc-Version: 4.0
Content-Disposition: inline; filename=Reebok_App_attract640L.avi
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Wed, 06 Nov 2013 17:02:47 GMT
为了摆脱传输编码,我在操作中添加了内容长度:

Response.AddHeader("Content-Length", mediaContent.File.FileData.Data.Length.ToString());

我无法摆脱
s-maxage=0
,但现在头类似了(除了
s-maxage=0
X-AspNetMvc-Version:4.0
和头顺序)

您可以将存储在数据库中的文件位置放入字节缓冲区数组,并从数组中分块读取,而不是一次读取整个数组

WebRequest wreq = (HttpWebRequest)WebRequest.Create(url);
using (HttpWebResponse wresp = (HttpWebResponse)wreq.GetResponse())
using (Stream mystream = wresp.GetResponseStream())
{
  using (BinaryReader reader = new BinaryReader(mystream))
  {
    int length = Convert.ToInt32(wresp.ContentLength);
    byte[] buffer = new byte[length];
    buffer = reader.ReadBytes(length);

    Response.Clear();
    Response.Buffer = false;
    Response.ContentType = "video/mp4";
    while(true) {
    int bytesRead = myStream.Read(buffer, 0, buffer.Length);
    if (bytesRead == 0) break;
    Response.OutputStream.Write(buffer, 0, bytesRead);
}
    Response.End();
  }
}
您还可以查看给定的url,它有助于,


谢谢

好吧,我已经尽力镜像了你的初始代码,除去数据库,我下面的代码对我来说很好。VS2012,MVC4,IIS Express local,IIS7.5 remote,适用于IE10 local,IE10 remote,IE9 remote。我使用的AVI文件是在windows\winsxs文件夹中找到的一些随机文件。我建议你有客户方面的问题(特别是)。比如cookie处理问题(),比如安全区域设置或者其他什么

顺便说一句,嵌入时高度=100%对我不起作用,需要像素

控制器

namespace MvcApplication4.Controllers
{
    public class HomeController : Controller
    {

        public ActionResult Index()
        {
            return new ViewResult();
        }

        public ActionResult Media(int id)
        {
            string fn = Server.MapPath("~/App_Data/boxed-delete.avi");
            var memoryStream = new MemoryStream(System.IO.File.ReadAllBytes(fn));
            return new FileStreamResult(memoryStream, MimeMapping.GetMimeMapping(System.IO.Path.GetFileName(fn)));
        }

    }
}
看法

@{
布局=空;
}
指数

您是否将http响应与同类型视频的工作实现进行了比较?(注意:这种方法仅适用于简单的静态视频;不适用于自适应流媒体)。我不知道这是否会有帮助,但您是否尝试过添加内联的内容配置?其他想法:avi(视频/x-msvideo)是一种伞形格式,可以在内部使用一系列编解码器;编解码器是否适用于浏览器?谢谢您的评论。我试图添加Response.AppendHeader(“内容处置”、“内联;文件名=“+mediaContent.File.filename”);但它不起作用,可能你需要一个自定义的控制器动作来只播放视频而不下载。检查此项我没有提供,但我尝试执行操作的控制器用AuthorizeAttribute标记,这是一个问题,用AllowAnonymousAttribute标记此操作可解决此问题。非常感谢-您提供的链接为我指明了正确的方向file.ReadAllBytes将整个文件加载到内存中。如果这对您有效,您根本不需要使用流,只需返回包含字节数组的FileContentResult即可。如果要在不将文件加载到内存的情况下对文件进行流式处理,则需要使用file.OpenRead。
Response.AddHeader("Content-Length", mediaContent.File.FileData.Data.Length.ToString());
WebRequest wreq = (HttpWebRequest)WebRequest.Create(url);
using (HttpWebResponse wresp = (HttpWebResponse)wreq.GetResponse())
using (Stream mystream = wresp.GetResponseStream())
{
  using (BinaryReader reader = new BinaryReader(mystream))
  {
    int length = Convert.ToInt32(wresp.ContentLength);
    byte[] buffer = new byte[length];
    buffer = reader.ReadBytes(length);

    Response.Clear();
    Response.Buffer = false;
    Response.ContentType = "video/mp4";
    while(true) {
    int bytesRead = myStream.Read(buffer, 0, buffer.Length);
    if (bytesRead == 0) break;
    Response.OutputStream.Write(buffer, 0, bytesRead);
}
    Response.End();
  }
}
namespace MvcApplication4.Controllers
{
    public class HomeController : Controller
    {

        public ActionResult Index()
        {
            return new ViewResult();
        }

        public ActionResult Media(int id)
        {
            string fn = Server.MapPath("~/App_Data/boxed-delete.avi");
            var memoryStream = new MemoryStream(System.IO.File.ReadAllBytes(fn));
            return new FileStreamResult(memoryStream, MimeMapping.GetMimeMapping(System.IO.Path.GetFileName(fn)));
        }

    }
}
@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
</head>
<body>
    <div>
        <!-- http://localhost:54941/Home/Media/3  -->
    <embed width="100%" height="500"  name="plugin" src="~/Home/Media/3" type="video/x-msvideo">     
    </div>
</body>
</html>