How to request the half of the video? .net language - c#

I want to use .net to request a video.
If the video less than 5min, response the video.
If the video more than 5min, response the half the video.
My code is :
`var path = context.Request["video"];
string videoPath = context.Server.MapPath("~" + path);
// get video
System.IO.FileInfo video = new System.IO.FileInfo(videoPath);
// check the video exist
if (!video.Exists)
{
context.Response.StatusCode = 404;
context.Response.StatusDescription = "Video Not Found";
context.Response.End();
}
// get video length
TimeSpan videoLength = new TimeSpan();
var shell = new Shell32.Shell();
var folder = shell.NameSpace(System.IO.Path.GetDirectoryName(video.FullName));
var file = folder.ParseName(System.IO.Path.GetFileName(video.FullName));
var lengthProperty = folder.GetDetailsOf(file, 27);
var timesp = TimeSpan.Parse(lengthProperty);
videoLength = TimeSpan.FromSeconds(Convert.ToDouble(timesp.TotalSeconds));
var size = video.Length;//this is video's size
// if video less than 5min,response the video
if (videoLength.TotalMinutes <= 5)
{
context.Response.ContentType = "video/mp4";
context.Response.WriteFile(video.FullName);
}
else
{
//const Int64 a = 600000000;
context.Response.ContentType = "video/mp4";
context.Response.WriteFile(video.FullName, 0, size/2);//else response half video
context.Response.AppendHeader("Content-Range", "bytes=0-" + (size/2).ToString() + "/" + video.Length);
}`
but it is does not work.
Thanks everyone!I do not know how to solve the problem.

Related

Unable to download Excel file when call from Postman

I am trying to download Excel file using web API but I am unable to download file in postman where as I am able to download Excel file when I enter URL in browser though while opening file I get warning message like below :
When i hit endpoint using POSTMAN then file get corrupted and it is showing junk characters.
Code :
protected virtual byte[] ExportToXlsx<T>(IEnumerable<T> itemsToExport)
{
using (var stream = new MemoryStream())
{
using (var xlPackage = new ExcelPackage())
{
// get handles to the worksheets
var worksheet = xlPackage.Workbook.Worksheets.Add(typeof(T).Name);
//create Headers and format them
var manager = new PropertyManager<T>(itemsToExport.First());
manager.WriteCaption(worksheet, SetCaptionStyle);
var row = 2;
foreach (var items in itemsToExport)
{
manager.CurrentObject = items;
manager.WriteToXlsx(worksheet, row++, false);
}
xlPackage.Save();
}
return stream.ToArray();
}
}
private readonly IServiceContext ctx;
public void Download(string guid)
{
var bytes = ExportToXlsx(list);
ctx.reqobj.HttpContext.Response.Headers.Add("Content-Disposition", "attachment; filename=\"demo.xlsx\"");
ctx.reqobj.HttpContext.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
ctx.reqobj.HttpContext.Response.Body.Write(bytes, 0, bytes.Length);
}
Note : I am using OfficeOpenXml for Excel file creation.
I will appreciate any help.
Update :
Try using "Send and download" instead of "Send"
https://www.getpostman.com/docs/v6/postman/sending_api_requests/responses
Postman doesn't download any file just return you the data that the server or your service provides. i have a project that download an excel to with the OpenXML here is an example with which you can guide with some styles to.
[HttpGet]
public void DownloadTable(int id)
{
List<Employee> all = db.Employees.Where(x => x.ManagerId == id).ToList();
String file = "Example.xlsx";
String path = Path.Combine(HttpContext.Current.Server.MapPath("~/App_Data"), file);
List<string[]> headerRow = new List<string[]>() { new string[] { "EmployeeId", "Name", "Shift", "Timestamp" } };
string headerRange = "A2:" + Char.ConvertFromUtf32(headerRow[0].Length + 64) + "2";
ExcelPackage excel = new ExcelPackage();
excel.Workbook.Worksheets.Add("Employees");
var page = excel.Workbook.Worksheets["Employees"];
page.Cells["A1:D1"].Merge = true;
page.Cells["A1:D1"].Value = "Supervisor: " + all.FirstOrDefault().Manager + " - " + id;
page.Cells["A1:D1"].Style.Font.Bold = true;
page.Cells[headerRange].LoadFromArrays(headerRow);
int z = 3;
foreach (Reporte r in all)
{
page.Cells["A" + z].Value = r.Id;
page.Cells["B" + z].Value = r.Name;
page.Cells["C" + z].Value = r.Shift;
page.Cells["D" + z].Value = r.Timestamp;
z++;
}
page.Cells["D3:D" + z].Style.Numberformat.Format = "dddd dd MMMM YYYY";
page.Cells["A2:D2"].AutoFilter = true;
page.Cells["A1:D" + z].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
page.Cells["A1:D" + z].Style.VerticalAlignment = ExcelVerticalAlignment.Center;
page.Cells["A2:D" + z].AutoFitColumns();
page.Cells["A1:D1"].Style.Fill.PatternType = ExcelFillStyle.Solid;
page.Cells["A1:D1"].Style.Fill.BackgroundColor.SetColor(Color.FromArgb(1, 183, 222, 232));
FileInfo excelFile = new FileInfo(path);
excel.SaveAs(excelFile);
System.Web.HttpResponse response = System.Web.HttpContext.Current.Response;
response.ClearContent();
response.Clear();
response.ContentType = "text/plain";
response.AddHeader("Content-Disposition",
"attachment; filename=" + file + ";");
response.TransmitFile(path);
response.Flush();
response.End();
File.Delete(path);
}
The stream needs to be passed to the package.
Right now nothing is being given to the package,
//...
using (var xlPackage = new ExcelPackage())
//...
So nothing is being saved to the stream, which is why the error is shown when trying to open the file.
There is no need to convert the memory stream to an array. Return the stream and pass that along for the response.
protected virtual Stream ExportToXlsx<T>(IEnumerable<T> itemsToExport) {
var stream = new MemoryStream();
using (var xlPackage = new ExcelPackage(stream)) { //<<< pass stream
// get handles to the worksheets
var worksheet = xlPackage.Workbook.Worksheets.Add(typeof(T).Name);
//create Headers and format them
var manager = new PropertyManager<T>(itemsToExport.First());
manager.WriteCaption(worksheet, SetCaptionStyle);
var row = 2;
foreach (var items in itemsToExport) {
manager.CurrentObject = items;
manager.WriteToXlsx(worksheet, row++, false);
}
xlPackage.Save();
}
return stream;
}
A controller action to return the file would look like this
public IActionResult Download(string guid) {
//...get list
var file = ExportToXlsx(list);
var contentType = "application/vnd.openxmlformats";
var fileName = "demo.xlsx";
return File(file, contentType, fileName); //returns a FileStreamResult
}
It was indicated in comments that the above is done in a support method.
Using the same approach
private readonly IServiceContext ctx;
//...
public void Download(string guid) {
//...get list
using(var fileStream = ExportToXlsx(list)) {
if (fileStream.CanSeek && fileStream.Position != 0) {
fileStream.Seek(0, SeekOrigin.Begin);
}
var contentType = "application/vnd.openxmlformats";
var fileName = "demo.xlsx";
var response = ctx.reqobj.HttpContext.Response;
response.Headers.Add("Content-Disposition", $"attachment; filename=\"{fileName}\"");
response.Headers.Add("Content-Length", fileStream.Length.ToString());
response.ContentType = contentType;
fileStream.CopyTo(response.Body);
}
}
the generated file is copied over to the body of the response.
As for postman, the tool is simply showing the content return in the response. It does not try to download the actual file as an attachment.

Server not allowing multiple connections to Internet Download Manager

I have written a code for enabling multiple connection download(Range-Requests) through Internet Download Manager and it works fine in my local system(it is able to create multiple connections and download a file.) but it's not able to create more than one connection in my server (Windows 2012 R2).
Also, when I keep a file on download and try to open another webpage of my application, it shows loading and does not open(until I cancel the download or let the download to complete.)
Below is my downloader code:
public ActionResult getFile()
{
System.IO.FileStream iStream = null;
var response = System.Web.HttpContext.Current.Response;
var request = System.Web.HttpContext.Current.Request;
// Buffer to read 10K bytes in chunk:
byte[] buffer = new Byte[10000];
int length1;
long dataToRead;
try
{
//File path.
string finalPath = #"C:\myfiles\abc.txt";
long size, start, end, length, fp = 0;
using (StreamReader reader = new StreamReader(finalPath))
{
size = new System.IO.FileInfo(finalPath).Length;
start = 0;
end = size - 1;
length = size;
response.AddHeader("Accept-Ranges", "0-" + size);
if (!String.IsNullOrEmpty(request.Headers["Range"]))
{
long anotherStart = start;
long anotherEnd = end;
string[] arr_split = request.Headers["Range"].Split(new char[] { Convert.ToChar("=") });
string range = arr_split[1];
// Make sure the client hasn't sent us a multibyte range
if (range.IndexOf(",") > -1)
{
// (?) Shoud this be issued here, or should the first
// range be used? Or should the header be ignored and
// we output the whole content?
response.AddHeader("Content-Range", "bytes " + start + "-" + end + "/" + size);
throw new HttpException(416, "Requested Range Not Satisfiable");
}
// If the range starts with an '-' we start from the beginning
// If not, we forward the file pointer
// And make sure to get the end byte if spesified
if (range.StartsWith("-"))
{
// The n-number of the last bytes is requested
anotherStart = size - Convert.ToInt64(range.Substring(1));
}
else
{
arr_split = range.Split(new char[] { Convert.ToChar("-") });
anotherStart = Convert.ToInt64(arr_split[0]);
long temp = 0;
anotherEnd = (arr_split.Length > 1 && Int64.TryParse(arr_split[1].ToString(), out temp)) ? Convert.ToInt64(arr_split[1]) : size;
}
/* Check the range and make sure it's treated according to the specs.
* http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
*/
// End bytes can not be larger than $end.
anotherEnd = (anotherEnd > end) ? end : anotherEnd;
// Validate the requested range and return an error if it's not correct.
if (anotherStart > anotherEnd || anotherStart > size - 1 || anotherEnd >= size)
{
response.AddHeader("Content-Range", "bytes " + start + "-" + end + "/" + size);
throw new HttpException(416, "Requested Range Not Satisfiable");
}
start = anotherStart;
end = anotherEnd;
fp = reader.BaseStream.Seek(start, SeekOrigin.Begin);
length = end - start + 1; // Calculate new content length
response.StatusCode = 206;
}
}
var fileName1 = Path.GetFileName(finalPath);
var fileNameUrlEncoded = HttpUtility.UrlEncode(fileName1, System.Text.Encoding.UTF8);
// Notify the client the byte range we'll be outputting
response.ContentType = "application/octet-stream";
response.AddHeader("Content-Disposition", "attachment;filename=" +
fileNameUrlEncoded.Replace("+", "%20"));
response.AddHeader("Connection", "Keep-Alive");
response.AddHeader("Content-Range", "bytes " + start + "-" + end + "/" + size);
response.AddHeader("Content-Length", length.ToString());
//response.WriteFile(finalPath, fp, length);
//response.End();
//As WriteFile() method does not work for huge files, thus using
//Chunk downloading below.
string filename = System.IO.Path.GetFileName(finalPath);
iStream = new FileStream(finalPath, System.IO.FileMode.Open,
System.IO.FileAccess.Read, System.IO.FileShare.Read,4096,true);
// Total bytes to read:
dataToRead = length;
iStream.Position = start;
while (dataToRead > 0)
{
// Verify that the client is connected.
if (Response.IsClientConnected)
{
// Read the data in buffer.
length1 = iStream.Read(buffer, 0, 10000);
// Write the data to the current output stream.
Response.OutputStream.Write(buffer, 0, length1);
// Flush the data to the HTML output.
Response.Flush();
buffer = new Byte[10000];
dataToRead = dataToRead - length1;
}
else
{
//prevent infinite loop if user disconnects
dataToRead = -1;
}
}
}
catch (Exception e)
{
TempData["Message"] = "error: " + e.Message;
return View();
}
finally
{
if (iStream != null)
{
//Close the file.
iStream.Close();
}
response.Close();
}
return View();
}
I am suspecting some server configuration issues that is causing the above issue. Can anyone help me to know what configuration changes might cause this issue.
Thanks in Advance.

FTP in C# in a WinForms app times out

I have an FTP server from which I pull and parse data and download images. I've never had an issue pulling text files (my data) but there are 2 directories that I pull images from and one works without a hitch using code identical to below (though obviously with a different Uri and image name array). In order to get a list of the images I have a function which pulls another file and returns an array of the image names and then I put this array of image names sequentially on the end of a base URI in a loop to download all images.
The code at the bottom is my function for pulling the text file with the image names. It has it's own URI and comes from a different part of the directory structure. The interesting thing is that if I manually create an array of images in a known location and feed my image pull code, it works fine but if I run this array building FTP function my image pulls timeout in the GetResponse() line. I've shortened the timeout so I don't have to wait so long for it to fail but it's not too short since as I said it works fine with a hard coded list of image URIs. I've searched here and tried several things thinking I wasn't releasing resources correctly but I cannot figure out what's happening.
Sorry I'm not an expert at this but I have lots of similar code in this app and this is the first time I've had trouble with FTPing.
One note, I have an earlier version of this app which works fine but I must admit I have been very lax in my source version control and don't have the old code (doh!). I changed something that is now killing it.
//Open a web request based on the URI just built from user selections
FtpWebRequest imageRequest = (FtpWebRequest)WebRequest.Create(imageUri);
imageRequest.UsePassive = false;
imageRequest.UseBinary = true;
imageRequest.KeepAlive = false;
imageRequest.Timeout = 2000;
//Act on that webrequest based on what the user wants to do (i.e. list a directory, list file, download, etc)
imageRequest.Method = WebRequestMethods.Ftp.DownloadFile;
try
{
//Now get the response from the tool as a stream.
FtpWebResponse imageResponse = (FtpWebResponse)imageRequest.GetResponse();
//Thread.Sleep(1000);
Stream imageResponseStream = imageResponse.GetResponseStream();
byte[] buffer = new byte[2048];
FileStream fs = new FileStream(newPath + #"\" + templateImageArray2[x].Split(' ')[0], FileMode.Create);
int ReadCount = imageResponseStream.Read(buffer, 0, buffer.Length);
while (ReadCount > 0)
{
fs.Write(buffer, 0, ReadCount);
ReadCount = imageResponseStream.Read(buffer, 0, buffer.Length);
}
fs.Close();
imageResponseStream.Close();
}
catch (WebException r)
{
if (r.Status == WebExceptionStatus.Timeout)
{
//Obtain more detail on error:
var response = (FtpWebResponse)r.Response;
FtpStatusCode errorCode = response.StatusCode;
string errorMessage = response.StatusDescription;
MessageBox.Show(errorMessage);
//goto RETRY;
}
MessageBox.Show(r.Message);
break;
}
string[] tempIDPText = new string[0];
Uri fileUriLocal = new Uri("ftp://srvrname:password#" + tempIpAddress + "/%2fROOT/DEVICE/HD/" + comboClass.Text + "/data/" + dirName1 + "/" + dirName2 + ".img");
//Open a web request based on the URI just built from user selections
FtpWebRequest requestLocal = (FtpWebRequest)WebRequest.Create(fileUriLocal);
requestLocal.UsePassive = false;
requestLocal.UseBinary = true;
requestLocal.KeepAlive = false;
//Act on that webrequest based on what the user wants to do (i.e. list a directory, list file, download, etc)
requestLocal.Method = WebRequestMethods.Ftp.DownloadFile;
try
{
//Now get the response from the tool as a stream.
FtpWebResponse responseLocal = (FtpWebResponse)requestLocal.GetResponse();
Stream responseStream = responseLocal.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
//Now read an individual file and fill the array with the chamber status
int y = 0;
while (!reader.EndOfStream)
{
if (reader.EndOfStream)
break;
else
{
Array.Resize(ref tempIDPText, tempIDPText.Length + 1);
tempIDPText[tempIDPText.Length - 1] = reader.ReadLine();
}
}
reader.Close();
responseStream.Close();
responseLocal.Close();
ServicePoint srvrPoint = ServicePointManager.FindServicePoint(fileUriLocal);
MethodInfo ReleaseConns = srvrPoint.GetType().GetMethod
("ReleaseAllConnectionGroups",
BindingFlags.Instance | BindingFlags.NonPublic);
ReleaseConns.Invoke(srvrPoint, null);
}
catch (WebException r)
{
//Obtain more detail on the error;
var response = (FtpWebResponse)r.Response;
FtpStatusCode errorCode = response.StatusCode;
string errorMessage = response.StatusDescription;
MessageBox.Show(errorCode.ToString());
MessageBox.Show("When getting file Dates: " + errorMessage.ToString());
}
return tempIDPText;

Images in Windows Phone 8.1 livetiles aren't sharp

I create livetiles with the following code:
// wide 310x150
var tileXml = TileUpdateManager.GetTemplateContent(TileTemplateType.TileWide310x150PeekImage03);
tileXml.GetElementsByTagName(textElementName).LastOrDefault().InnerText = string.Format(artist + " - " + trackname);
var image = tileXml.GetElementsByTagName(imageElementName).FirstOrDefault();
if (image != null)
{
var src = tileXml.CreateAttribute("src");
if (albumart == String.Empty)
src.Value = "Assets/onemusic_logo_wide.scale-240.png";
else
src.Value = albumart;
image.Attributes.SetNamedItem(src);
}
// square 150x150
var squaredTileXml = TileUpdateManager.GetTemplateContent(TileTemplateType.TileSquare150x150PeekImageAndText01);
squaredTileXml.GetElementsByTagName(textElementName).FirstOrDefault().InnerText = string.Format(artist + " - " + trackname);
image = squaredTileXml.GetElementsByTagName(imageElementName).LastOrDefault();
if (image != null)
{
var src = squaredTileXml.CreateAttribute("src");
if (albumart == String.Empty)
src.Value = "Assets/onemusic_logo_square.scale-240.png";
else
src.Value = albumart;
image.Attributes.SetNamedItem(src);
}
updater.Update(new TileNotification(tileXml));
updater.Update(new TileNotification(squaredTileXml));
The problem I face is that the images shown on the livetile aren't sharp (in the app they are). I think this is because of the 310x150 pixels size of the template. I looked at the templates, there aren't any higher resolution ones. Is there a way to make the images sharper?
I noticed that providing an image with a resolution of exactly 744x360 pixels solves the problem. So I wrote this function to resize my albumarts (maybe it will come in handy for someone);
private async static Task<string> CropAndSaveImage(string filePath)
{
const string croppedimage = "cropped_albumart.jpg";
// read file
StorageFile file = await StorageFile.GetFileFromPathAsync(filePath);
if (file == null)
return String.Empty;
// create a stream from the file and decode the image
var fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read);
BitmapDecoder decoder = await BitmapDecoder.CreateAsync(fileStream);
// create a new stream and encoder for the new image
using (InMemoryRandomAccessStream writeStream = new InMemoryRandomAccessStream())
{
// create encoder
BitmapEncoder enc = await BitmapEncoder.CreateForTranscodingAsync(writeStream, decoder);
enc.BitmapTransform.InterpolationMode = BitmapInterpolationMode.Linear;
// convert the entire bitmap to a 744px by 744px bitmap
enc.BitmapTransform.ScaledHeight = 744;
enc.BitmapTransform.ScaledWidth = 744;
enc.BitmapTransform.Bounds = new BitmapBounds()
{
Height = 360,
Width = 744,
X = 0,
Y = 192
};
await enc.FlushAsync();
StorageFile albumartfile = await ApplicationData.Current.LocalFolder.CreateFileAsync(croppedimage, CreationCollisionOption.ReplaceExisting);
using (var stream = await albumartfile.OpenAsync(FileAccessMode.ReadWrite))
{
await RandomAccessStream.CopyAndCloseAsync(writeStream.GetInputStreamAt(0), stream.GetOutputStreamAt(0));
}
// return image path
return albumartfile.Path;
}
}

ASP.NET uploading a file to Amazon S3

I am in the process of uploading images to Amazon S3, however i keep getting the error "Please specify either a Filename, provide a FileStream or provide a ContentBody to PUT an object into S3."
Basically i am uploading an image from a fileupload control and then hitting the code below. It uploads locally fine, but not to Amazon. The Credentials are alright so it only errors when it comes to uplaoding.
Can anyone see why this is happening please?
protected void uploadImg(int prodId, int prodFormat)
{
if (imgPack.HasFile)
{
string fileExt = Path.GetExtension(imgPack.PostedFile.FileName);
string filename = "img" + prodId + ".jpg";
// Specify the upload directory
string directory = Server.MapPath(#"\images\packshots\");
if (fileExt == ".jpeg" || fileExt == ".jpg" || fileExt == ".png")
{
if (packUK.PostedFile.ContentLength < 716800)
{
// Create a bitmap of the content of the fileUpload control in memory
Bitmap originalBMP = new Bitmap(packUK.FileContent);
// Calculate the new image dimensions
decimal origWidth = originalBMP.Width;
decimal origHeight = originalBMP.Height;
decimal sngRatio = origHeight / origWidth;
int newHeight = 354; //hight in pixels
decimal newWidth_temp = newHeight / sngRatio;
int newWidth = Convert.ToInt16(newWidth_temp);
// Create a new bitmap which will hold the previous resized bitmap
Bitmap newBMP = new Bitmap(originalBMP, newWidth, newHeight);
// Create a graphic based on the new bitmap
Graphics oGraphics = Graphics.FromImage(newBMP);
// Set the properties for the new graphic file
oGraphics.SmoothingMode = SmoothingMode.AntiAlias;
oGraphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
// Draw the new graphic based on the resized bitmap
oGraphics.DrawImage(originalBMP, 0, 0, newWidth, newHeight);
// Save the new graphic file to the server
string accessKey = "KEY HERE";
string secretKey = "KEY HERE";
AmazonS3 client;
using (client = Amazon.AWSClientFactory.CreateAmazonS3Client(accessKey, secretKey))
{
PutObjectRequest request = new PutObjectRequest();
request.BucketName="MyBucket";
request.CannedACL = S3CannedACL.PublicRead;
request.Key = "images/" + filename;
S3Response response = client.PutObject(request);
}
//newBMP.Save(directory + filename);
// Once finished with the bitmap objects, we deallocate them.
originalBMP.Dispose();
newBMP.Dispose();
oGraphics.Dispose();
}
}
else
{
notifybar.Attributes.Add("style", "display:block;");
notifybar.Attributes.Add("class", "failed");
notifyText.Text = "Error Text Here";
}
}
else
{
notifybar.Attributes.Add("style", "display:block;");
notifybar.Attributes.Add("class", "failed");
notifyText.Text = "Error Text Here";
}
}
You need to assign File or InputStream property of PutObjectRequest object. The code fragment should look like this one:
using (client = Amazon.AWSClientFactory.CreateAmazonS3Client(accessKey, secretKey))
{
var stream = new System.IO.MemoryStream();
originalBMP.Save(stream, ImageFormat.Bmp);
stream.Position = 0;
PutObjectRequest request = new PutObjectRequest();
request.InputStream = stream;
request.BucketName="MyBucket";
request.CannedACL = S3CannedACL.PublicRead;
request.Key = "images/" + filename;
S3Response response = client.PutObject(request);
}

Categories