HTML5 视频 - 从 SQL 文件流中流式传输

Posted

技术标签:

【中文标题】HTML5 视频 - 从 SQL 文件流中流式传输【英文标题】:HTML5 Video - streaming from SQL File Stream 【发布时间】:2016-07-28 10:50:14 【问题描述】:

我正在编写一个 ASP.NET (C#) Web 应用程序,人们应该能够通过 FileStream 从我们的 SQL Server 加载视频。由于其简单性,我正在考虑使用 html5 视频控件。我已经设法让它适用于保存在项目中的 mp4 文件:

<video controls id="vidPlayer" runat="server" >
    <source src="Content/Video/video.mp4" type="video/mp4">
    Your browser does not support HTML5 video.
</video>

这在文件存在时有效,但是如果我想从 FileStream 提供视频,我最终会得到一个 Byte 数组,我不知道从那里如何处理它。我目前有代码:

            SqlConnection con = new SqlConnection(constr);
            con.Open();

            //Retrieve the FilePath() of the video file
            SqlCommand sqlCommand = new SqlCommand();
            sqlCommand.Connection = con;
            sqlCommand.CommandText = "SELECT EvidenceFS FROM [EP].[t_TraineeUploadedEvidence] WHERE ID = 'A5E262F8-6465-41C1-BD34-42EBCB492C87'";
            byte[] buffer = (byte[])sqlCommand.ExecuteScalar();


            MemoryStream ms = new MemoryStream(buffer);

            vidPlayer.Src = ????

            //Cleanup
            con.Close();

我不禁觉得我只是缺少一些简单的东西......我希望它很简单!我对这个领域比较陌生,所以任何帮助都将不胜感激!

如果您需要我提供更多信息,请告诉我!我也必须对音频做同样的事情,但我希望任何解决方案都能解决这两个问题。

【问题讨论】:

【参考方案1】:

这是我用的。

[HttpGet, Route("yourApi")]
public HttpResponseMessage grabMyStream(string fileName)

string mimeType = MimeMapping.GetMimeMapping(fileName);

        MediaTypeHeaderValue mediaType = MediaTypeHeaderValue.Parse(mimeType);

        Stream inputStream = getYourStream(); 

        var response = Request.CreateResponse();
        response.Content = new PushStreamContent(
            async (outputStream, httpContent, transportContext) =>
            
                byte[] buffer = new byte[65536];
                int read = 0;
                while ((read = inputStream.Read(buffer, 0, buffer.Length)) > 0)
                
                    await outputStream.WriteAsync(buffer, 0, buffer.Length);
                

            , mediaType);

        return response;


<video controls id="vidPlayer" runat="server" >
    <source src="yourApi?fileName=video.mp4" type="video/mp4">
    Your browser does not support HTML5 video.
</video>

在传递文件名时使用查询字符串,因为末尾有扩展名。

编辑: getYourStream() 方法是您从中返回 MemoryStream 的地方。当您的 HTML 加载时,HTML5 视频将向 src 发送一个 GET 请求。所以 src 需要指向你的 API 方法。这是假设您使用的是 Asp.Net Web Api。

注意:如果您从某处逐段提取流,那么您将直接将其写入 outputStream。这是以允许您一次拥有整个流然后逐个流式传输的方式编写的。它效率低下,但这些是我项目的要求。如果您不必一次流一点,并且一次拥有整个流(看起来像),那么我将改为从您的 Api 方法返回整个流。

【讨论】:

谢谢 BobbyJ - 我不确定我是如何将你所拥有的内容转换到我的代码中的?我不禁认为我错过了对您正在发生的其他事情的一些核心理解......这是一个功能吗?什么是'getYourStream()'?等等…… 感谢您的回复,因此您可能拥有的任何其他信息都会有所帮助! 好的,这开始变得更有意义了..但是我的问题涉及更多一点,因为我基本上想要一个列出视频的网格视图,然后单击 Gridview 中的链接按钮将在视频控件中打开视频。我试图让你的建议来适应这一点,但没有太多运气将选定的 ID 传递到 Web API(加上我遇到了 Request.CreateResponse() 的问题 - 需要一个类型为“HttpRequestMessage”的接收器。不确定是否您可以按照我的要求做很多事情吗?? ... 我应该补充一点,网格视图显示有关 SQL 文件流中存在的视频文件的元数据。单击该行将收集该元数据的 ID,然后我可以为所选视频返回正确的 Byte[] 数组。 1.在前端。单击链接按钮 - Javascipt 需要添加 DOM 视频元素(或仅显示它) 2. 然后设置 src 标签。然后用 javascript 调用 element.load() 中的 DOM 元素。【参考方案2】:

我认为像 BobbyJ 一样,您需要创建一个外部 url,您的视频控件将从中加载 mp4 文件。 例如 - 这是一个简单的视频控件(来自这里 -https://www.w3.org/wiki/HTML/Elements/video)。

<video controls
  src="http://media.w3.org/2010/05/bunny/movie.ogv">
Your user agent does not support the HTML5 Video element.
</video>

除了“http://media.w3.org/2010/05/bunny/movie.ogv”网址,您还可以使用 web 服务(WCF 或 web api 或任何您想要的),网址将返回一个文件。

【讨论】:

【参考方案3】:

我最终得到了我真正需要的东西。以下是我这样做的方式 - 对上述回复表示敬意,因为它们确实帮助我指明了正确的方向!所以,视频播放器控件存在于无源的aspx文件中:

        <video controls id="vidPlayer" runat="server"  style="display:none" >
            Your browser does not support HTML5 video.
        </video>

以及用于从 SQL 文件流中检索数据的以下 Web 处理程序:

public class FileStreamHandler1 : IHttpHandler


    public void ProcessRequest(HttpContext context)
    
        int id = int.Parse(context.Request.QueryString["id"]);
        byte[] bytes;
        string contentType;
        string strConnString = ConfigurationManager.ConnectionStrings["conString"].ConnectionString;
        string name;

        using (SqlConnection con = new SqlConnection(strConnString))
        

            using (SqlCommand cmd = new SqlCommand("[EPORTAL].[LearnerLoginGetEvidenceFile]"))
            
                using (SqlDataAdapter sda = new SqlDataAdapter())
                
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.AddWithValue("@EvidenceID", id);
                    cmd.Connection = con;

                    con.Open();
                    SqlDataReader sdr = cmd.ExecuteReader();
                    sdr.Read();
                    bytes = (byte[])sdr["Data"];
                    contentType = sdr["ContentType"].ToString();
                    name = sdr["Name"].ToString();
                    con.Close();
                

            
            context.Response.Clear();
            context.Response.Buffer = true;
            context.Response.AppendHeader("Content-Disposition", "attachment; filename=" + name);
            context.Response.ContentType = contentType;
            context.Response.BinaryWrite(bytes);
            context.Response.End();
        
    

    public bool IsReusable
    
        get
        
            return false;
        
    

我要查找的记录 id 是通过查询字符串传递的。这只是在后面的代码中调用:

vidPlayer.Src = "FileStreamHandler.ashx?Id=" + SelectedEvID.ToString();

SelectedEvID 取自 Gridview 中的选定行。

我希望这可以帮助其他希望实现相同功能的人。

【讨论】:

以上是关于HTML5 视频 - 从 SQL 文件流中流式传输的主要内容,如果未能解决你的问题,请参考以下文章

如何将视频从 Play 2 框架流式传输到 HTML5 播放器

用于 chrome 中 html5 视频的 Servlet 流式传输 mp4

HTML5 - 如何流式传输大型 .mp4 文件?

使用 gst-rtsp-server 流式传输 H264 文件

如何使用 html 5 视频元素流式传输视频

使用 PHP Html5 流式传输视频