Progressive streaming of video in asp.net - asp.net

I want to do progressive streaming of video in asp.net. I have written a code for that but still its not loading properly. Does any have idea about it.
Please have look into my code or suggest me the best way to do it. I don't want player to wait for downloading whole video and then start playing. I want to start playing right now.
Following is my code.
string path = "Test.mp4";
string rootpath = Server.MapPath(Request.ApplicationPath);
string file = string.Format(#"{0}\\{1}", rootpath, path);
if (File.Exists(file) && file.Contains("mp4"))
{
FileStream filestream = new FileStream(file, FileMode.Open, FileAccess.Read);
long length = filestream.Length;
Response.AppendHeader("Content-Type", "video/mp4");
Response.AddHeader("Content-Disposition", "attachment; filename=" + path + "");
Response.AppendHeader("Content-Length", length.ToString());
const int buffersize = 16384;
byte[] buffer = new byte[buffersize];
int count = filestream.Read(buffer, 0, buffersize);
while (count > 0)
{
if (!Response.IsClientConnected)
count = -1;
else
{
Response.OutputStream.Write(buffer, 0, count);
Response.Flush();
count = filestream.Read(buffer, 0, buffersize);
}
}
}
Best Regards,
Jalpesh

I had the same problem and ended up implementing 'Range-Specific Request'. Check this article on dotNetSlackers. It has sample code for streaming of MP4 files. This solution works great on iPad, iPhone and Chrome!

The Content-Disposition header is used to instruct the browser to offer a Save As dialog for the attached file. probably not the behavior you want. Did you try removing it?

Related

Run JavaScript after an "Attachment Response" in ASP?

So here is my problem: I have a code that use response to ExportFile, but the problem is after the response code. the succeeding code no longer executes or it is like being read but ignored. sorry for being noob. so here is my code:
fullFilePath = "" + rootPath + "" + Filename + ".xlsx";
string fileName = fullFilePath.Substring(fullFilePath.LastIndexOf('\\') + 1);
byte[] buffer;
using (FileStream fileStream = new FileStream(fullFilePath, FileMode.Open))
{
int fileSize = (int)fileStream.Length;
buffer = new byte[fileSize];
// Read file into buffer
fileStream.Read(buffer, 0, (int)fileSize);
}
Response.Clear();
Response.Buffer = true;
Response.BufferOutput = true;
Response.ContentType = "application/x-download";
Response.AddHeader("Content-Disposition", "attachment; filename=" + fileName);
Response.CacheControl = "public";
// writes buffer to OutputStream
Response.OutputStream.Write(buffer, 0, buffer.Length);
newFile.Delete();
ClientScript.RegisterStartupScript(GetType(), "id", "EnableCtrl()", true);
after this has been executed the javascript "EnableCtrl()" is not being fired or triggered. And when I delete the part of code which is related to response and change it to something else the javascript is being triggered. So how could i run a javascript after a response code?
The script won't/can't be triggered this method because the browser has already been sent the response: which is the file, and not the markup from a post-back. One request. One response. And it wasn't the post-back markup.
Instead, I would suggest either:
Handling the "Client Click" of the initiating control in the browser as well (the action could be delayed with setTimeout). Browser won't actually refresh the page/DOM because of the attachment disposition in the response, which is why this works. However, there are no client-side events for if a download was accepted, has started, or has completed1
Change the design so the "download" is a separate action with no other side-effect.
Happy coding.
1 It's possible to contrive server-assisted setups that allow the client to query the progress of a download, much like an upload progress indicator. However, this is not trivial or standard and may still not accurately reflect the state.

Present a PDF Document on a Specific Page in ASP.NET

I am opening PDF documents using the following ASP.NET code,
Response.BufferOutput = true;
Response.Clear();
Response.ContentType = "application/pdf";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(documentURL);
using (HttpWebResponse responseDDRINT = (HttpWebResponse)request.GetResponse())
{
using (Stream stream = responseDDRINT.GetResponseStream())
{
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
int bytesRead;
while ((bytesRead = stream.Read(buffer, 0, bufferSize)) > 0)
{
Response.OutputStream.Write(buffer, 0, bytesRead);
}
Response.Flush();
}
}
My question is does anyone know how to present the PDF starting at a specifice page. For example, if the PDF document is 15 pages, we would like it to open with page 10 initially showing instead of opening at page 1.
I experimented with the "#page=" open parameter by adding this header, but it did nothing.
Response.AddHeader("content-disposition", "inline; filename=test.pdf#page=3");
You'll have to manipulate the PDF file on the fly.
Use something like http://pdfsharp.com/PDFsharp/ to stream out a copy of the file starting at a certain page.
Current versions of Adobe ready no longer support the page syntax, but they do support the bookmark syntax.
Why don't you make your document reachable through a regular link or through an HTTPHandler?
you may use a PDF manipulation library like ItextSharp to get your work done.

How to get file size of multiple file download

I am writing an ASP.NET web application.
I calculate the total size of my PDF file which is mentioned below. What does this return? When I download a 2KB file, it returns a size of 2KB, which is correct. But when I download 2 files each of size 2KB, then the total size it returns is 2.16KB. Is that correct? Should it return 4KB?
StringReader reader = new StringReader(content);
MemoryStream ms = new MemoryStream();
Document doc = new Document(PageSize.A4, 50, 50, 30, 30);
HTMLWorker parser = new HTMLWorker(doc);
PdfWriter.GetInstance(doc, ms);
doc.Open();
try
{
parser.Parse(reader);
}
catch (Exception ex)
{
Paragraph paragraph = new Paragraph("Error! " + ex.Message);
paragraph.SetAlignment("center");
Chunk text = paragraph.Chunks[0] as Chunk;
if (text != null)
{
//text.Font.Color = iTextSharp.text.BaseColor.RED;
}
doc.Add(paragraph);
}
finally
{
doc.SetMargins(10, 10, 10, 10);
doc.Close();
}
Byte[] buffer = ms.GetBuffer();
if (buffer != null)
{
Response.ContentType = "application/pdf";
Response.AppendHeader("content-disposition", "attachment;filename=FileName.pdf");
//Response.AddHeader("content-length", buffer.Length.ToString());
Response.BinaryWrite(buffer);
}
Sounds like you're opening two files into the same buffer and expecting them to be appended one to the other. Instead, the second is replacing the first.
Try all this stand-alone in a simple C# program. If it doesn't work there, it clearly won't work in an ASP page. OTOH, if it does work there, but not in ASP, then its an ASP issue, not a problem with iTextSharp.
PS: I thought doc.close would close the stream used by PdfWriter as well. Looking at the code, it will by default (protected boolean closeStream = true; from the java source). Something might have called setCloseStream(false) somewhere along the line.
PPS: Stacking two PDFs into the same binary stream is Not A Good Idea. You need to write them out as separate attachments... at which point this whole issue is moot.

asp.net ashx handler prompting download instead of displaying file

I implemented a generic handler in my application which works great for images, but when I manually type the handler URL in the browser with the image's querystring it prompts download instead of displaying. Here is my code:
public void ProcessRequest(HttpContext context)
{
if (this.FileName != null)
{
string path = Path.Combine(ConfigurationManager.UploadsDirectory, this.FileName);
if (File.Exists(path) == true)
{
FileStream file = new FileStream(path, FileMode.Open);
byte[] buffer = new byte[(int)file.Length];
file.Read(buffer, 0, (int)file.Length);
file.Close();
context.Response.ContentType = "application/octet-stream";
context.Response.AddHeader("content-disposition", "attachment; filename=\"" + this.FileName + "\"");
context.Response.BinaryWrite(buffer);
context.Response.End();
}
}
}
I am using the octet-stream because I'm dealing with more than just images and I don't always know the content type of the file. Thanks in advance!
The only way is to specify correct ContentType so the browser know what to do with receiving file, depending on installed plugins (for example, view pdf files in browser frame) and system assosiations (for example, offer to open document in MS Office instead of simple download)
You can try to specify Content Type depending on file extension, i.e.:
if(Path.GetExtension(path) == ".jpg")
context.Response.ContentType = "image/jpeg";
else
context.Response.ContentType = "application/octet-stream";
If you store the ContentType as part of the files metadata, when you pull it back down your could use it.
theFile = GetFile(id)
context.Response.ContentType = theFile.Type;
The content-disposition header is the one that causes your browser to show the download dialog. Remove that line and it will show in the browser.

Zipping Files and Downloading them Using SaveAs Dialog

I have the following code to zip all the files and then save it to the harddisk. I want zip all the files (this is done) and then attach the zip file to the Response stream so that the user have the option to save it!
protected void DownloadSelectedFiles_Click(object sender, EventArgs e)
{
string path = String.Empty;
string zipFilePath = #"C:\MyZipFile.zip";
ZipOutputStream zipStream = new ZipOutputStream(File.Create(zipFilePath));
byte[] buffer = new byte[4096];
foreach (GridViewRow row in gvFiles.Rows)
{
bool isSelected = (row.FindControl("chkSelect") as CheckBox).Checked;
if (isSelected)
{
path = (row.FindControl("lblUrl") as Label).Text;
ZipEntry entry = new ZipEntry(Path.GetFileName(path));
entry.DateTime = DateTime.Now;
zipStream.PutNextEntry(entry);
using (FileStream fs = File.OpenRead(path))
{
int sourceBytes;
do
{
sourceBytes = fs.Read(buffer, 0, buffer.Length);
zipStream.Write(buffer, 0, sourceBytes);
} while (sourceBytes > 0);
}
}
}
zipStream.Finish();
zipStream.Close();
Response.ContentType = "application/x-zip-compressed";
Response.AppendHeader("Content-Disposition", "attachment; filename=SS.zip");
Response.WriteFile(zipFilePath);
Response.End();
}
I blogged about sending files like this a while ago. You might find something usefull in there.
http://absolutecobblers.blogspot.com/2008/02/downloading-and-deleting-temporary.html
If you are using IE, check that its not the old "cache is full"-bug that is showing its ugly face.
And if you have IE set to refresh cashe Automatically or on IE-start and have downloaded that zip-file broken the first time, then it could be that it uses the cached version of that zip-file after you fixed your routine and got a good zip.
Try to add:
Response.Buffer = true;
Response.Clear();
Response.ClearContent();
Response.ClearHeaders();
before your Response.ContentType
and add this:
Response.Flush()
Response.Close()
before response.end, and see if that changes anything.
So the result is this:
Response.Buffer = true;
Response.Clear();
Response.ClearContent();
Response.ClearHeaders();
Response.ContentType = "application/x-zip-compressed";
Response.AppendHeader("Content-Disposition", "attachment; filename=SS.zip");
Response.WriteFile(zipFilePath);
Response.Flush()
Response.Close()
Response.End();
Just some tips just from the top of the mind.
I also tried to save the zip file to the server folder and then giving a link to the user to download it but it says the same "The file is corrupted". This is very strange since I can open the same folder if I visit my server folder and manually open it!
Here is another thing I found. If I save the zip file in the Server's folder and then reference it using the url: http://localhost/MyApplication/ServerFolder/MyZipFile.zip.
If I go to the url and download the zip file I get the same error "File is corrupted". But if I manually go to the folder using file explorer and open the file then it works as expected.
Why and How?
And a long shot, try set the mime type to application/unknown, in this post there seems to be part of the solution to the posters problem:
http://jamesewelch.com/2008/12/03/sharpziplib-and-windows-extraction-wizard-errors/

Resources