Reputation: 1594
I am writting an ASP.NET (C#) web application where people should be able to load a video from our SQL Server via FileStream. I am looking at using the HTML5 video control due to its simplicity. I have managed to get it working for an mp4 file that is saved in the project:
<video controls id="vidPlayer" runat="server" width="420">
<source src="Content/Video/video.mp4" type="video/mp4">
Your browser does not support HTML5 video.
</video>
This works as the file is there, however if I am looking at supplying the video from a FileStream, I end up with a Byte array and I dont knwo what to do with it from there. I currently have the code:
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();
I cant help but feel I am just missing something simple...I hope it is simple! I am relatively new to this area so any help would be appreciated!
Please let me know if you need more info from me! I have to do the same with audio as well but I am hoping that any solution should hopefully address both issues.
Upvotes: 1
Views: 3916
Reputation: 1594
I managed to get exactly what I needed in the end. The following is how I went about doing so - kudos to the above responses as they certainly helped point me in the right direction! So, the video player control exists in the aspx file with no source:
<video controls id="vidPlayer" runat="server" width="500" style="display:none" >
Your browser does not support HTML5 video.
</video>
and the following web handler for retrieving the data from the SQL Filestream:
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;
}
}
}
where the record id I am looking for is passed over through the query string. This is simply called in code behind with the following:
vidPlayer.Src = "FileStreamHandler.ashx?Id=" + SelectedEvID.ToString();
where the SelectedEvID is taken from the selected row in the Gridview.
I hope this helps anyone else looking to implement the same.
Upvotes: 1
Reputation: 972
I think like BobbyJ, you need to make an external url that your video control will load the mp4 file from. For example - this is a simple video control (from here-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>
Instead of the "http://media.w3.org/2010/05/bunny/movie.ogv" url you can use webservice (WCF or web api or whatever you want) with a url that will return you a file.
Upvotes: 1
Reputation: 88
This is what I use.
[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" width="420">
<source src="yourApi?fileName=video.mp4" type="video/mp4">
Your browser does not support HTML5 video.
</video>
use the query string on passing the file name because there is an extension on the end.
EDIT: The getYourStream() method is where you are returning your MemoryStream from. When your HTML loads the HTML5 video will send a GET request to the src. So the src needs to point to your API method. This is assuming you're using Asp.Net Web Api.
Note: if you were pulling a stream piece by piece from somewhere then you would write it directly to the outputStream. This is written in a way that allows you to have the entire stream at once then stream it piece by piece. It is inefficient but those were the requirements for my project. If you don't have to stream a little at a time and you have the entire stream at once (as it looks like) then I would instead just return the entire stream from your Api method.
Upvotes: 1