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

时间:2022-12-16 09:25:24

I have been asked to create a web site in Visual Studio 2010 using C#, where I need to upload, download and play video files, a lot like youtube. I have done the uploading part, but I just can't get the downloading and playing the video from the database part. Here is the code, I have been using on the page where download and playing will take place:

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

Table details:

Vid_Id (int), Video_Name (nvarchar), Video (VarBinary), Video_Size(bigint), Added (nvarchar)

Vid_Id(int),Video_Name(nvarchar),Video(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;
        }
    }
}

The HTML5 Video tag which got used here is showing error message that is:

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

Invalid Source

But when, I'm copying the url from the player by right-clicking on it during runtime, then pasting it on the browser address bar and pressing enter, it's starting to download the video with the name

但是,当我在运行时通过右键单击它来复制播放器中的url,然后将其粘贴到浏览器地址栏并按Enter键时,它开始下载带有名称的视频

Video Handler.mp4

Plus it's showing the same number of video players as many videos are uploaded in the database. Can anyone please help me..? Thank you

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

1 个解决方案

#1


0  

You're almost there. Here is the GIST: Grab the bytes from SQL Server and write it to the response stream.

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

You should also set the ContentType of the response (assuming that you know it's mp4 of course):

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

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

This line tells the browser that it is a mp4 file, so you can embed the video in a tag in html5 or open a video player etc.

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

Well, storing video files and retrieving them in a DB like this is not a really good practice, but if your purpose is to do a school assignment or something like that, it will work.

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

#1


0  

You're almost there. Here is the GIST: Grab the bytes from SQL Server and write it to the response stream.

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

You should also set the ContentType of the response (assuming that you know it's mp4 of course):

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

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

This line tells the browser that it is a mp4 file, so you can embed the video in a tag in html5 or open a video player etc.

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

Well, storing video files and retrieving them in a DB like this is not a really good practice, but if your purpose is to do a school assignment or something like that, it will work.

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