Retrieve video file stored as VarBinary in SQL Server Express database

て烟熏妆下的殇ゞ 提交于 2021-01-29 07:28:10

问题


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:

Table details:

Vid_Id (int), Video_Name (nvarchar), Video (VarBinary), Video_Size(bigint), Added (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:

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

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:


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

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

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.

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.



来源:https://stackoverflow.com/questions/20173448/retrieve-video-file-stored-as-varbinary-in-sql-server-express-database

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!