检索在SQL Server Express数据库中存储为VarBinary的视频文件

时间:2013-11-24 10:24:03

标签: c# asp.net sql visual-studio-2010 sql-server-express

我被要求使用C#在Visual Studio 2010中创建一个网站,我需要上传,下载和播放视频文件,就像youtube一样。我已完成上传部分,但我无法从数据库部分下载和播放视频。这是代码,我一直在下载和播放的页面上使用:

表详情:

  

Vid_Id(int),   Video_Name(nvarchar),   视频(VarBinary),   Video_Size(BIGINT)   添加(nvarchar)

Default.aspx的

<asp:Panel ID="Panel1" runat="server" Height="363px">
                    <asp:DataList ID="Repeater1" runat="server" DataSourceID="dsvidz">
                        <ItemTemplate>
                            <video id="player" height="300" width="300" controls autoplay>
                            <source src='<%# "VideoHandler.ashx?id=" + Eval("Vid_Id") + "&type=mp4" %>' type='video/mp4'/>
                            </video>
                        </ItemTemplate>
                    </asp:DataList>
                </asp:Panel>
            <asp:Button ID="Button1" runat="server" Text="Download Video" 
                    onclick="Button1_Click" Enabled="False" />

Default.aspx.cs

    using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Collections;
using System.Configuration;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using System.Data;
using System.Web.Security;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls.WebParts;

    public partial class Default : System.Web.UI.Page
    {
        SqlConnection connection = new SqlConnection("Data Source=.\\SQLEXPRESS;AttachDbFilename=|DataDirectory|\\ASPNETDB.MDF;Integrated Security=True;User Instance=True");
        private int id = 0, index=0;
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
                BindData();
        }
        private DataTable GetSpecificVideo(object i)
        //pass the id of the video
        {
            SqlDataAdapter adapter = new SqlDataAdapter("SELECT Video, Vid_Id " + "FROM Vid_Dir WHERE Vid_Id = @id", connection);
            adapter.SelectCommand.Parameters.Add("@id", SqlDbType.Int).Value = (int)i;
            DataTable table = new DataTable();
            adapter.Fill(table);
            return table;

        }
                void BindData()
        {
            //hfSearchText has the search string returned from the grid.
            if (hfSearchText.Value != "")
                dsvidz.SelectCommand += " where " + hfSearchText.Value;
            DataView dv = (DataView)dsvidz.Select(new DataSourceSelectArguments());
            //hfSort has the sort string returned from the grid.
            if (hfSort.Value != "")
                dv.Sort = hfSort.Value;

            GridView1.DataSource = dv;
            try
            {
                GridView1.DataBind();
            }
            catch (Exception exp)
            {
                //If databinding threw exception bcoz current page index is > than available page index
                GridView1.PageIndex = 0;
                GridView1.DataBind();
            }
            finally
            {
                //Select the first row returned
                if (GridView1.Rows.Count > 0)
                    GridView1.SelectedIndex = 0;
            }
        }
        protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
        {
            if (e.CommandName == "play")
            {
                this.index = Convert.ToInt32(e.CommandArgument);
                GridViewRow row = GridView1.Rows[this.index];
                    SqlCommand cmd1 = new SqlCommand("SELECT Vid_Id FROM Vid_Dir WHERE Video_Name=@VN", connection);
                    SqlDataReader idRdr = null;
                    idRdr = cmd1.ExecuteReader();
                    while (idRdr.Read())
                    {
                        this.id = Convert.ToInt32(idRdr["Vid_Id"]);
                        Label1.Text = Convert.ToString(idRdr["Video_Name"]);
                        Label3.Text = Convert.ToString(idRdr["Added"]);
                        Label5.Text = Convert.ToString(idRdr["Description"]);
                    }
                    Repeater1.DataSource = GetSpecificVideo(this.id);
                    Repeater1.DataBind();
                    Button1.Enabled=true;
            }

        }
        protected void Button1_Click(object sender, EventArgs e)
        {
            DataTable file = GetAFile(this.id);
            DataRow row = file.Rows[this.index];
            string name = (string)row["Video_Name"];
            Byte[] data = (Byte[])row["Video"];

            // Send the file to the browser
            Response.AddHeader("Content-type", "video/mp4");
            Response.AddHeader("Content-Disposition", "attachment; filename=" + name);
            Response.BinaryWrite(data);
            Response.Flush();
            Response.End();
        }
        public static DataTable GetAFile(int i)
        {
            DataTable file = new DataTable();
            using (SqlConnection connection = new SqlConnection("Data Source=.\\SQLEXPRESS;AttachDbFilename=|DataDirectory|\\ASPNETDB.MDF;Integrated Security=True;User Instance=True"))
            {
                SqlCommand cmd = new SqlCommand();
                cmd.Connection = connection;
                cmd.CommandTimeout = 0;

                cmd.CommandText = "SELECT Vid_Id, Video_Name, Video_Size FROM Vid_Dir " + "WHERE Vid_Id=@ID";
                cmd.CommandType = CommandType.Text;
                SqlDataAdapter adapter = new SqlDataAdapter();
                cmd.Parameters.Add("@ID", SqlDbType.Int);
                cmd.Parameters["@ID"].Value = i;
                adapter.SelectCommand = cmd;
                adapter.Fill(file);
                connection.Close();
            }

            return file;
        }
}

VideoHandler.ashx

    <%@ WebHandler Language="C#" Class="VideoHandler" %>

using System;
using System.Web;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using System.Data;
public class VideoHandler : IHttpHandler
{
    public void ProcessRequest(HttpContext context)
    {
        SqlConnection connection = new SqlConnection("Data Source=.\\SQLEXPRESS;AttachDbFilename=|DataDirectory|\\ASPNETDB.MDF;Integrated Security=True;User Instance=True");
        SqlCommand cmd = new SqlCommand("SELECT Video, Video_Name" + " FROM Vid_Dir WHERE Vid_Id = @id", connection);
        cmd.Parameters.Add("@id", SqlDbType.Int).Value =context.Request.QueryString["id"];
        try
        {
            connection.Open();
            SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.Default);
            if (reader.HasRows)
            {
                while (reader.Read())
                {
                    context.Response.ContentType = reader["Video_Name"].ToString();
                    context.Response.BinaryWrite((byte[])reader["Video"]);
                }
            }
        }
        finally
        {
            connection.Close();
        }
    }
    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
}

此处使用的HTML5视频标记显示错误消息:

  

无效来源

但是,当我在播放器中通过右键单击它来复制网址时,然后将其粘贴到浏览器地址栏并按回车键,它就开始下载名为

的视频
  

Video Handler.mp4

此外,它显示的视频播放器数量与在数据库中上传的视频数量相同。 谁能帮帮我吗..? 谢谢

1 个答案:

答案 0 :(得分:0)

你快到了。这是GIST: 从SQL Server中获取字节并将其写入响应流。

您还应该设置响应的ContentType(假设您当然知道它是mp4):

context.Response.ContentType = "video/mp4";

此行告诉浏览器它是一个mp4文件,因此您可以将视频嵌入到html5的标签中或打开视频播放器等。

好吧,存储视频文件并在这样的数据库中检索它们并不是一个很好的做法,但是如果你的目的是做一个学校作业或类似的东西,那就可以了。