using ffmpeg in asp.net razor (C#) - c#

I know questions like this are all over the internet but I believe my case is different, I have a ASP.NET Webpage (Razor C#) and I have a whole video sharing website ready BUT I still don't understand, How can I convert videos to mp4 and webm using ffmpeg on the upload page and instead of having the original saved and added to the database i want the converted version added. heres my upload page code:
#{
WebSecurity.RequireAuthenticatedUser();
var db = Database.Open("PhotoGallery");
var fileName = "";
var uploader = WebSecurity.CurrentUserId;
var date = DateTime.Now.Date;
var extention = "";
if(IsPost){
var numFiles = Request.Files.Count;
if(numFiles <= 0){
ModelState.AddError("fileUpload", "Please specify at least one photo to upload.");
}
else{
var fileSavePath = "";
var uploadedFile = Request.Files[0];
fileName = Path.GetFileNameWithoutExtension(uploadedFile.FileName).Trim();
extention = Path.GetExtension(uploadedFile.FileName).Trim();
string ndom = Path.GetRandomFileName();
var none = ndom.Remove(ndom.Length - 4);
fileSavePath = Server.MapPath("~/Images/userpics/" +
none + extention);
uploadedFile.SaveAs(fileSavePath);
var insertCommand = "INSERT INTO Videos (FileTitle, UploadDate, UserId, ext, Name) Values(#0, #1, #2, #3, #4)";
db.Execute(insertCommand, fileName, date, uploader, extention, none + extention);
Response.Redirect(Href("~/Photo/View", db.GetLastInsertId()));
}
}
}
<h1>Upload Video</h1>
<form method="post" enctype="multipart/form-data">
#Html.ValidationSummary("Unable to upload:")
<fieldset class="no-legend">
<legend>Upload Photo</legend>
#FileUpload.GetHtml(addText: "Add more files", uploadText: "Upload", includeFormTag: false)
<p class="form-actions">
<input type="submit" value="Upload" title="Upload photo" />
</p>
</fieldset>
</form>
<p class="message info">
The maximum file size is 50MB.
</p>

I think your best bet will be to take the upload as-is, and have an offline application or service poll your table for new records and convert them then. When finished, it would update the table with the new file name and a flag indicating it was converted.
I had a similar project and this is what I did.
It's probably not a good idea to try converting these on the fly. If you a fair amount of simultaneous uploads/conversions, you could end up cratering your server.

Related

How to use file upload?

My fileupload isn't working. I get this error each time I try: Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index.
I'm doing all of this from the .cshtml file because, the previous web master deleted all of the source code when he was fired. So I only have the deployed files to work with and none of the controllers and models. I also cannot add any new functionality to the website.
I used this tutorial this tutorial following the single file upload.
Here is my code:
#using Microsoft.Web.Helpers;
#{
Layout="~/Views/Shared/_FUllWidthLayout.cshtml";
var message="";
if(IsPost){
if(Request.Files.Count > 0){ //<-- If more than 0 files, FAILS HERE
try{
var uploadedFile = Request.Files[0]; //<-- FAILS HERE
var fileName = Path.GetFileName(uploadedFile.FileName);
var fileSavePath = Server.MapPath("~/Documents/Jobs/" + fileName);
uploadedFile.SaveAs(fileSavePath);
message = Request.Files.Count + " files uploaded to " + fileSavePath;
}
catch(Exception e){
message = e.Message;
}
}else{
message = Request.Files.Count + " files uploaded.";
}
}
}
And my HTML:
<form id="uploadForm" method="post" enctype="multipart/form-data">
<h3>FileUpload - Single-File Example</h3>
<div class="inline-div">
#FileUpload.GetHtml(
initialNumberOfFiles:1,
allowMoreFilesToBeAdded:false,
includeFormTag:true,
uploadText:"Upload")
<small class="red">#message</small>
</div>
</form>
I also tried taking the FileUpload control out of the form like this:
<h3>FileUpload - Single-File Example</h3>
<div class="inline-div">
#FileUpload.GetHtml(
initialNumberOfFiles:1,
allowMoreFilesToBeAdded:false,
includeFormTag:true,
uploadText:"Upload")
<small class="red">#message</small>
</div>
Message says "0 files uploaded." as seen here:
Can anyone point out what I'm doing wrong and how I can fix it? Or is there another tool I can use to do the same work?

How to get video duration from mp4,m3u8 or any other file

I found the NReco.VideoInfo library to be the best option and simpler
1] Find the NReco.VideoInfo library in NuGet Package Manager and import it in your project
2] After that import the namespace "using NReco.VideoInfo"
3] Add the below line of code into the method.
var ffProbe = new FFProbe();
var videoInfo = ffProbe.GetMediaInfo(blob.Uri.AbsoluteUri);
return videoInfo.Duration.TotalMilliseconds;
here you can see some other option
Why don't you use the windows media player to solve this problem?
using WMPLib;
public Double getDuration(String path)
{
WindowsMediaPlayer wmp = new WindowsMediaPlayerClass();
IWMPMedia mediaInfo = wmp.newMedia(file);
return mediaInfo.duration;
}
If you mean from a local file, the following will show the duration without loading the entire video file (test on mp4):
var inputBox = document.getElementById("videoInput")
inputBox.onchange = function(files) {
alert("starting")
var video = document.createElement('video');
alert("video created")
video.preload = 'metadata';
video.onloadedmetadata = function() {
alert("metadata loaded")
var duration = video.duration;
alert("duration is " + duration)
}
var selectedVID = document.getElementById("videoInput").files[0];
video.src = URL.createObjectURL(selectedVID);
}
<div id="input-upload-file">
<p>
Video Upload Duration test
</p>
<input id="videoInput" type="file" class="upload" name="fileUpload">
</div>
The same approach will work on streamed videos also.

C# MVC HTML5 file upload control with multiple attribute duplicates images

I am having a strange issue with HTML5 file upload control with multiple attribute. I have no clue about how to fix it. I am trying to explain the problem below:
When uploading multiple images on the server, the images are uploading but some of them are getting duplicated, not by name, but by image itself.
Means if I select say 10 images, I can see 10 images are uploaded with different names (names are generated dynamically) but say 4 images are exactly the same. Means, 6 out of 10 selected images uploaded perfectly, but 4 original images got disappeared completely! But these 4 images are using contents from 6 images uploaded correctly. Moreover, this is happening in random. There is no order or sequence from what I can understand what will disappear and what will re-uploaded with a different name.
In short:
Selected 10 different images for upload
Number of images uploaded is 10
6 images (say) uploaded with correct content
4 images (say) uploaded with correct file name, but content is wrong. They are using contents of 6 images and original content of these images simply disappeared.
This is happening when I am selecting more than 5 images for upload. Anything less than 6 has no problem.
Now when I test the same code at local development environment this is not happening at all! I checked folder permission on the server and there is no restriction imposed.
I am not sure whether I could explain the issue correctly because it is really a typical one and I never encountered similar thing before !!
Markup:
<div class="row gapp-10 medium">
<div class="col-md-9">
Upload Photos <span class="small-font gray-text">(Optional)</span> <span class="small-font red-text">
(Combined upload size can't exceed 10mb.)</span>
<%:Html.TextBoxFor(model => model.VehicleImages, new {#type="file", #id="fUpload", #multiple="multiple", #class="btn btn-clc-theme-orange"}) %>
</div>
<div class="clearfix"></div>
</div>
Controller Action method:
[Authorize]
[HttpPost]
public ActionResult Upload(VehicleViewModel model)
{
if (ModelState.IsValid)
{
_service = new VehicleService();
model.SellerId = CommonMethods.LoggedInUser.SellerId;
var newVehicle = _service.Save(model);
newVehicleId = newVehicle.VehilceId;
for (var i = 0; i < Request.Files.Count; i++)
{
var fl = Request.Files[i];
if (fl == null || fl.ContentLength <= 0) continue;
var filename = System.IO.Path.GetFileName(fl.FileName.Trim());
if (string.IsNullOrEmpty(filename)) continue;
var fileExtension = System.IO.Path.GetExtension(filename);
var newFileName = String.Concat(DateTime.Now.Ticks.ToString(CultureInfo.InvariantCulture), fileExtension);
System.IO.Directory.CreateDirectory(Server.MapPath("~/VehiclePhoto/" + newVehicleId));
var photoPath = System.IO.Path.Combine(Server.MapPath("~/VehiclePhoto/" + newVehicleId + "/"), newFileName);
fl.SaveAs(photoPath);
}
}
return RedirectToAction("VehicleUploaded");
}
Edit
This is how the upload control is placed inside the form element and the method is being called. Nothing fancy, just the simple and classical way.
<% using(Html.BeginForm("Upload", "VehicleUpload", FormMethod.Post, new {enctype = "multipart/form-data"}))
{ %>
...
<div class="row gapp-10 medium">
<div class="col-md-9">
Upload Photos <span class="small-font gray-text">(Optional)</span>
<span class="small-font red-text">(Combined upload size can't exceed 10mb.)</span>
<%:Html.TextBoxFor(model => model.VehicleImages, new {#type="file", #id="fUpload", #multiple="multiple", #class="btn btn-clc-theme-orange"}) %>
</div>
<div class="clearfix"></div>
</div>
...
<input type="submit" value="Upload Vehicle" class="btn btn-primary" />
<% } %>

How to upload multiple files into C# and loop through them in MVC

I'm having a problem with uploading multiple files to C# and loop through them. I found a question with a similar problem but nobody answered it.
I upload multiple files through an html input. The file count passes through to my controller with the correct amount relative to the amount of files I selected. However when I try to loop through each of my files it loops through the first file relative to the file count. For example if I upload 3 files it loops through the first file 3 times or if I upload 5 files it loops through the first file 5 times. It should not do this. I want it to loop through each file individually. Please help!!! here is my code:
Razor View(I'm using a bootstrap library for fileinputs called bootstrap-filestyle):
#using (Html.BeginForm("Initial", "DataCapture", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div class="form-group">
<h4>Select files</h4>
<input type="file" multiple="multiple" id="fileToUpload" name="file">
</div>
<div>
<input type="submit" value="Capture" class="btn btn-default" />
</div>
}
Controller:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Initial(ClaimModel claimModel)
{
if (ModelState.IsValid)
{
//OtherCode
handleFile(Request.Files, c.ClaimID);
return RedirectToAction("Index", "ClaimFiles", new { id = c.ClaimID });
}
//OtherCode
}
private void handleFile(HttpFileCollectionBase Files, int ClaimID)
{
foreach (string fileName in Files)
{
HttpPostedFileBase file = Request.Files[fileName];
//OtherCode
}
//OtherCode
}
I put break points on handleFile(Request.Files, c.ClaimID); and inside foreach (string fileName in Files){...}. As I said it correctly passes through the file count if I upload 3, 4, 5 or any amount of files however it only loops through the first file that amount of times and returns the first file multiple times as well. I need it to loop through and return each file individually. How do I do this correctly?
Use Request from server, here is one example:
for (int i = 0; i < Request.Files.Count; i++)
{
var fileDoc = Request.Files[i];
}
Or you can try something like this:
HttpPostedFileBase hpf = null;
foreach (string file in Request.Files)
{
hpf = Request.Files[file] as HttpPostedFileBase;
}

How can I obtain selected filenames clientside using a fileupload control without submitting?

I can't find an existing answer so far, but here is my goal:
I'd like to use the asp.net fileupload control(or some other control you might suggest) to select a series of files. WITHOUT submitting a form, i'd like the selected files to be displayed in a concatenated list of some sort.
Is this possible with the Fileupload control or do I have to use something else? I've seen many answers involving submission then grabbing the filenames, but I don't want to take a trip to the server for that. Just looking to grab the filenames when they're selected, all clientside.
Thank you for your time!
Using files property. See the code below:
function onInputChange(e) {
var res = "";
for (var i = 0; i < $("#customInput").get(0).files.length; i++) {
res += $("#customInput").get(0).files[i].name + "<br />";
}
$('#result').html(res);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="customInput" type="file" accept="image/*" multiple onchange="onInputChange(event)" />
<br /><br />
<div style="color:blue" id='result'></div>
try this -
Javascript
function showFile() {
var file = document.getElementById("<%=FileUpload1.ClientID%>");
var path = file.value;
alert(path);
}
File Upload Control
<asp:FileUpload ID="FileUpload1" runat="server" onchange="showFile()" />

Categories