多文件断点续传,上传视频自动转MP4和截图,图片格式转换
生活随笔
收集整理的這篇文章主要介紹了
多文件断点续传,上传视频自动转MP4和截图,图片格式转换
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
功能:自己寫的一個組件,根據調用傳過來的的fileType判斷是上傳視頻還是圖片還是音頻。可以選擇多文件上傳,同時也可以暫停,繼續,取消,斷網重連續傳。如果上傳的是視頻,會自動轉為mp4,自動截取一幀圖片。如果上傳的是.tif格式圖片則轉換為png格式(用的ffmpeg插件)。
界面:
前端代碼:
@{ViewBag.Title = "Index";<link rel="stylesheet" href="/Content/gdsm/vendor/bootstrap-3.3.7/css/bootstrap.min.css"><link rel="stylesheet" href="/Content/gdsm/vendor/bootstrap-datepicker-1.6.4-dist/css/bootstrap-datepicker3.min.css"><link rel="stylesheet" href="/Content/gdsm/css/common.css"><link rel="stylesheet" href="/Content/gdsm/css/admin.css"><script src="/Content/gdsm/vendor/jquery-3.3.1/jquery-3.3.1.min.js"></script><script src="/Content/gdsm/vendor/bootstrap-3.3.7/js/bootstrap.min.js"></script><script src="/Content/gdsm/vendor/layer-v3.1.1/layer/layer.js"></script><script src="/Content/gdsm/vendor/jquery.nicescroll-3.7.6/jquery.nicescroll.min.js"></script><script type="text/javascript" src="~/Content/gdsm/vendor/bootstrap-datepicker-1.6.4-dist/js/bootstrap-datepicker.min.js"></script><script type="text/javascript" src="~/Content/gdsm/vendor/bootstrap-datepicker-1.6.4-dist/locales/bootstrap-datepicker.zh-CN.min.js"></script><script src="/Content/gdsm/js/common.js"></script>ViewData["datacategory"] = ViewContext.RouteData.Values["categoryData"];string fileType = ViewContext.RouteData.Values["categroy"].ToString(); }<div id="addShapeContent"><div class="panel"><div class="panel-heading"><h3 class="panel-title">文件上傳</h3></div><div class="panel-body shape-upload p30"><div class="upload-box item">@switch (fileType){case "image":<div class="upload-btn"><input type="file" name="uploadFile" multiple="multiple" accept=".jpg,.jpeg,.png,.gif,.bmp,.tif">選擇文件</div><p class="file-desc">(圖片支持jpg, jpeg, png, gif, bmp, tif;大小不超過5M,推薦尺寸:4:3,16:9)</p>break;case "media":<div class="upload-btn"><input type="file" name="uploadFile" multiple="multiple" accept=".mp4,.flv,.avi,.wmv">選擇文件</div><p class="file-desc">(視頻支持mp4, flv, wmv, avi;大小不超過20M)</p>break;case "music":<div class="upload-btn"><input type="file" name="uploadFile" multiple="multiple" accept=".mp3">選擇文件</div><p class="file-desc">(音頻支持mp3大小不超過20M)</p>break;case "shape":<div class="upload-btn"><input type="file" name="uploadFile" multiple="multiple" accept=".jpg,.jpeg,.png,.gif,.bmp,.tif">選擇文件</div><p class="file-desc">(圖片支持jpg, jpeg, png, gif, bmp, tif;大小不超過5M,推薦尺寸:4:3,16:9)</p>break;}</div><div class="item"><div class="control-label">添加至</div><div class="control"><select id="sltcategory" class="form-control">@if (ViewData["datacategory"] != null){foreach (var item in ViewData["datacategory"] as List<GDSMModel.JHResCategory>){<option value="@item.res_category_id">@item.res_category_name</option>}}</select></div></div><div class="item"><div id="prolabel" class="control-label" style="display:none">正在上傳中</div><div class="control"><ul id="proul" class="progress-lists mt34" style="height:135px; overflow-y:auto;"></ul></div></div></div><div class="panel-footer"><button type="button" class="btn btn-lucency js-cancle pull-right ml20">關閉</button></div></div></div><div id="progressbar" style="display:none"><li class="progress-detail" id="****"><span class="name" title="####" style="height:30px;">####</span><div class="progress progress-striped active"><div class="progress-bar progress-bar-success" role="progressbar"aria-valuenow="60" aria-valuemin="0" aria-valuemax="100"style="width:0%;"></div></div><span class="num" style="width:30px;">0%</span><label class="currIndex" style="display:none">0</label><button class="btn btn-blue btn-sm" onclick="PauseAndContinue(this);" style="margin-right:10px">暫停</button><button class="btn btn-blue btn-sm" onclick="Cancle(this);">取消</button></li></div><script type="text/javascript">//用于存儲file信息var filearr = new Array();//離線狀態下的fileIDvar offlinefileids = new Array();$(function () {//數組加個刪除功能Array.prototype.remove = function (val) {var index = this.indexOf(val);if (index > -1) {this.splice(index, 1);}};//監聽網絡已連接事件window.addEventListener('online', Online);//上傳功能$("input[type='file']").change(function () {var filelists = this.files;//切換下標簽類型,防止上傳同一文件OnChange觸發不了$(this).attr("type", "text");$(this).attr("type", "file");for (var i = 0; i < filelists.length; i++) {if (filelists == undefined) {layer.open({title: '錯誤提示', content: '您的瀏覽器暫不支持上傳文件,建議使用IE9以上、FireFox、Chrome、360極速模式等瀏覽器。'});return;}if (filelists.length < 1) {layer.open({title: '錯誤提示', content: '請選擇文件。'});return;}//驗證格式類型var fileSplit = filelists[i].name.toLowerCase().split(".");var fileFormat = fileSplit[fileSplit.length - 1]; //獲得文件結尾的類型如 zip rar 這種寫法確保是最后的if (validate(fileFormat, filelists[i].name)) {$("#prolabel").show();var fileid = uuid();//生成一個文件IDvar file = filelists[i];var totalSize = filelists[i].size;//文件大小var blockSize = 1024 * 1024;//塊大小var blockCount = Math.ceil(totalSize / blockSize);//總塊數//存儲file信息var data = new fileData(file, totalSize, blockCount, blockSize);filearr[fileid] = data;//存儲執行上傳中的文件idofflinefileids.push(fileid);//獲取服務器上最近上傳的文件塊序號//currIndex = 0;//生成進度條var progressbar = $("#progressbar").html();//替換名稱progressbar = progressbar.replace(new RegExp("####", 'g'), file.name);//替換IDprogressbar = progressbar.replace("****", fileid);$("ul.progress-lists").append(progressbar);//開始分塊上傳文件UploadPost(fileid, file, totalSize, blockCount, blockSize);}}});});//上傳文件function UploadPost(fileid, file, totalSize, blockCount, blockSize) {var queryid = "#" + fileid;var state = $(queryid).find("button[style]").html();//獲取暫停繼續的狀態var currIndex = parseInt($(queryid).find("label.currIndex").html());//獲取文件塊數var category = $("#sltcategory").val();if (!(state == "暫停")) {if ($(queryid).find("label.currIndex").html() == "-1") {//取消上傳,刪除文件塊CancleAjax(queryid, fileid);}return; //暫停}try {var start = currIndex * blockSize; //文件流開始位置var end = Math.min(totalSize, start + blockSize); //文件流結束位置var block = file.slice(start, end); //截取下來的文件流塊信息//組裝提交表單信息var formDataBlock = new FormData();formDataBlock.append('fileName', file.name);//文件名formDataBlock.append('blockCount', blockCount);//總塊數formDataBlock.append('currIndex', currIndex);//當前上傳的塊下標formDataBlock.append('uploadId', fileid);//上傳編號formDataBlock.append('fileType', "@fileType");//文件類別formDataBlock.append('categoryType', category)//分類formDataBlock.append('totalSize', totalSize)//文件大小,用于驗證formDataBlock.append('data', block);//提交服務器$.ajax({url: '/Admin/FileUpload/Upload',type: 'post',data: formDataBlock,processData: false,contentType: false,success: function (res) {block = null;if ($(queryid).find("label.currIndex").html() == "-1") {//取消上傳,刪除文件塊CancleAjax(queryid, fileid);}else if (res.Code === 1) {//設置進度條currIndex++;var num = Math.round((currIndex) / blockCount * 100) + "%";$(queryid).find("span.num").html(num);$(queryid).find("div.progress-bar").css("width", num);//如果當前文件塊不是最后一個,遞歸上傳其他文件塊信息if (currIndex < blockCount) {$(queryid).find("label.currIndex").html(currIndex);UploadPost(fileid, file, totalSize, blockCount, blockSize);}else {//上傳成功$(queryid).fadeOut(2000, function () {$(this).remove();if ($("#proul").children().length <= 1)$("#prolabel").fadeOut("fast");});offlinefileids.remove(fileid);filearr[fileid] = "";}}else {layer.open({title: '錯誤提示', content: res.Msg});}}, error: function (e) {if (!navigator.onLine) {layer.open({title: '錯誤提示', content: '網絡連接已斷開。'});}else if (e.status == 0) {UploadPost(fileid, file, totalSize, blockCount, blockSize);}else {layer.open({title: '錯誤提示', content: e.responseText});}}});} catch (e) {alert(e);}}//暫停function PauseAndContinue(obj) {var fileid = $(obj).parent().attr("id");if ($(obj).html() == "暫停") {$(obj).html("繼續");offlinefileids.remove(fileid);}else {$(obj).html("暫停");var fdata = filearr[fileid];offlinefileids.push(fileid);UploadPost(fileid, fdata.file, fdata.totalSize, fdata.blockCount, fdata.blockSize);}}//取消function Cancle(obj) {$(obj).parent().find("label.currIndex").html("-1");}//取消上傳,刪除文件塊function CancleAjax(queryid, fileid) {$.ajax({url: '/Admin/FileUpload/Cancle?id=' + fileid,datatype: "json",type: "GET",async: false,success: function () {$(queryid).find("span.num").html("0%");$(queryid).find("div.progress-bar").css("width", 0);$(queryid).fadeOut(2000, function () {$(this).remove();if ($("#proul").children().length <= 1)$("#prolabel").fadeOut("fast");});}});}//網絡連接上繼續執行上傳function Online() {for (var i = 0; i < offlinefileids.length; i++) {var fileid = offlinefileids[i];var fdata = filearr[fileid];UploadPost(fileid, fdata.file, fdata.totalSize, fdata.blockCount, fdata.blockSize);}}//驗證function validate(fileType,filename){var type = "@fileType";var result = true;switch (type) {case "image":if (fileType != "jpg" && fileType != "jpeg" && fileType != "png" && fileType != "gif" && fileType != "bmp" && fileType != "tif" && fileType != "") {layer.open({title: '格式錯誤', content: filename + '的格式錯誤'}); result = false;}break;case "shape":if (fileType != "jpg" && fileType != "jpeg" && fileType != "png" && fileType != "gif" && fileType != "bmp" && fileType != "tif" && fileType != "") {layer.open({title: '格式錯誤', content: filename + '的格式錯誤'});result = false;}break;case "music":if (fileType != "mp3") {layer.open({title: '格式錯誤', content: filename + '的格式錯誤'});result = false;}break;case "media":if (fileType != "mp4" && fileType != "flv" && fileType != "avi" && fileType != "wmv") {layer.open({title: '格式錯誤', content: filename + '的格式錯誤'});result = false;}break;}return result;}//生成GUIDfunction uuid() {var s = [];var hexDigits = "0123456789abcdef";for (var i = 0; i < 36; i++) {s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);}s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01s[8] = s[13] = s[18] = s[23] = "-";var uuid = s.join("");//return uuid;return uuid.replace(new RegExp("-", 'g'), "");}//用于存儲file信息function fileData(file, totalSize, blockCount, blockSize) {this.file = file;this.totalSize = totalSize;this.blockCount = blockCount;this.blockSize = blockSize;}</script>后端代碼:
using GDSMBLL; using GDSMCommon; using GDSMModel; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Security.Cryptography; using System.Text; using System.Web; using System.Web.Mvc;namespace GDSMPlateForm.Areas.Admin.Controllers {public class FileUploadController : Controller{public string oriVideoPathc = "";public string outVideoPathc = "";public string ffmpegPathc = System.Web.Hosting.HostingEnvironment.MapPath("~/Content/ffmpeg/ffmpeg.exe");// GET: Admin/FileUploadpublic ActionResult Index(){return View();}[Route][HttpPost]public ActionResult Upload(string uploadId, int blockCount, int currIndex, string fileName,string fileType,string categoryType,int totalSize){try{var file = Request.Files[0];//文件格式string format = Path.GetExtension(fileName);//路徑MD5 md5 = new MD5CryptoServiceProvider();string cryptStr = "";#region 校驗ValidateHelper vh = new ValidateHelper();if (file == null)return Json(new UploadResult { Msg = "請選擇文件" }, JsonRequestBehavior.AllowGet);if (blockCount < 1)return Json(new UploadResult { Msg = "塊數量不能小于1" }, JsonRequestBehavior.AllowGet);if (currIndex < 0)return Json(new UploadResult { Msg = "塊數量小于0" }, JsonRequestBehavior.AllowGet);if (string.IsNullOrWhiteSpace(uploadId))return Json(new UploadResult { Msg = "上傳編號為空" }, JsonRequestBehavior.AllowGet);if (!vh.IsValidateFileExtension(fileName)){return Json(new UploadResult { Msg = "文件格式不支持" }, JsonRequestBehavior.AllowGet);}if (totalSize > vh.GetResTypeSize(fileType)){return Json(new UploadResult { Msg = "文件超過指定大小" }, JsonRequestBehavior.AllowGet);}var result = new UploadResult { Code = 1, Msg = "上傳成功~" };result.UploadID = uploadId;#endregion#region ==塊處理==string relativePath = "/upload";if (!string.IsNullOrEmpty(fileType) && !string.IsNullOrEmpty(categoryType)){relativePath = "/Content/resource/" + fileType + "/" + categoryType + "/" + uploadId;}string dir = System.Web.HttpContext.Current.Server.MapPath("~" + relativePath);if (Directory.Exists(dir) == false){Directory.CreateDirectory(dir);}//塊文件名稱var blockName = $"{uploadId}_{currIndex}.block";//塊文件目錄路徑var blockPath = Path.Combine(dir, "block");//塊文件目錄對象DirectoryInfo blockDirectoryInfo = Directory.Exists(blockPath) ? new DirectoryInfo(blockPath) : Directory.CreateDirectory(blockPath);//塊文件完整路徑var blockFullPath = Path.Combine(blockPath, blockName);if (System.IO.File.Exists(blockFullPath)){//塊已上傳,不做失敗處理return Json(new UploadResult { Code = 1, Msg = "該文件塊已上傳~" }, JsonRequestBehavior.AllowGet);}file.SaveAs(blockFullPath);#endregion#region ==塊合并處理==//判斷塊文件是否已將上傳完,上傳完合并文件if (blockDirectoryInfo.GetFiles().Count().Equals(blockCount)){//var timestamp = DateTime.Now.ToString("yyyMMdd");string fileOldNmae = fileName;fileName = uploadId + format;//var filePath = Path.Combine(dir, timestamp);var filePath = dir;if (!Directory.Exists(filePath)){Directory.CreateDirectory(filePath);}//完整文件存儲路徑var fileFullPath = Path.Combine(filePath, fileName);//讀取每個文件塊寫入文件流using (var fs = new FileStream(fileFullPath, FileMode.Create)){for (var i = 0; i < blockCount; i++){var path = Path.Combine(blockPath, $"{uploadId}_{i}.block");var bytes = System.IO.File.ReadAllBytes(path);fs.Write(bytes, 0, bytes.Length);}//刪除所有文件塊路徑Directory.Delete(blockPath, true);}#region md5加密FileStream fileStream = new FileStream(fileFullPath, FileMode.Open);//對面文件流進行md5加密byte[] cryptBytes = md5.ComputeHash(fileStream);//加密的二進制轉為string類型cryptStr = Convert.ToBase64String(cryptBytes);fileStream.Close();#endregionresult.FileInfo = new UploadFileInfo{FileName = fileName,FilePath = fileFullPath};if (fileType == "media"){outVideoPathc = filePath + "\\" + uploadId + ".mp4";//轉mp4格式路徑oriVideoPathc = fileFullPath;//原視頻路徑string thubHeight = "150";string frameIndex = "1";string thubWidth = "200";string thubImagePath = filePath + "\\" + uploadId + ".png";FileConvertUtil.MediaExstractImage(ffmpegPathc, oriVideoPathc, thubHeight, frameIndex, thubWidth, thubImagePath);format = ".mp4";fileName = uploadId + format;System.Threading.Thread thread = new System.Threading.Thread(new System.Threading.ThreadStart(ConvertMp4WithoutTxt));thread.Start();}else if (fileType == "image" || fileType == "shape"){if (format == ".tif" || format == ".TIF"){format = ".png";fileName = uploadId + format;outVideoPathc = filePath + "\\" + uploadId + ".png";//轉mp4格式路徑oriVideoPathc = fileFullPath;//原視頻路徑System.Threading.Thread thread = new System.Threading.Thread(new System.Threading.ThreadStart(ConvertImageFormat));thread.Start();}}#region 信息存入數據庫JHResouce jhResouce = new JHResouce();jhResouce.file_id = Guid.NewGuid().ToString();jhResouce.file_name = fileName;jhResouce.file_oldname = fileOldNmae;jhResouce.file_path = Path.Combine(relativePath, fileName).Replace("\\", "/");jhResouce.res_category_id = categoryType;jhResouce.create_user_id = "";jhResouce.create_time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");jhResouce.md5 = cryptStr;if (fileType == "media"){jhResouce.file_type = Path.Combine(relativePath, uploadId + ".png").Replace("\\", "/");}else{jhResouce.file_type = format;}HttpCookie cookieid = Request.Cookies["user_id"];if (cookieid != null){if (cookieid.Value != ""){jhResouce.create_user_id = cookieid.Value;}}JHResouceBL hResouceBL = new JHResouceBL();hResouceBL.Insert(jhResouce, GetTableName(fileType));new JHLogBL().Insert(LogType.add, fileType + "添加操作,文件上傳");#endregion}#endregionreturn Json(result);}catch (Exception ex){throw;}}/// <summary>/// 上傳過程中取消上傳,刪除相應文件塊/// </summary>/// <param name="id"></param>/// <returns></returns>[HttpGet]public int Cancle(string id){try{//獲取文件塊路徑,刪除文件塊string dir = System.Web.HttpContext.Current.Server.MapPath("~/upload");var blockPath = Path.Combine(dir, id);Directory.Delete(blockPath, true);return 1;}catch{return 0;}}/// <summary>/// 視頻轉換為mp4/// </summary>public void ConvertMp4WithoutTxt(){Process p = new Process();//建立外部調用線程p.StartInfo.FileName = ffmpegPathc; //System.Windows.Forms.Application.StartupPath + "\\ffmpeg.exe";//要調用外部程序的絕對路徑// string StrArg = "-i concat:\"" + StrMP4A + "|" + StrMP4B + "\" -vcodec copy -acodec copy " + StrOutMp4Path + " -y";//string StrArg = "- i concat: \"" + StrMP4A + "|" + StrMP4B + "\" - vcodec copy - acodec copy "+ StrOutMp4Path + " -y";// string StrArg = "-i D:\\123.flv -i D:\\water.png -filter_complex \"overlay=10:10\" -b 1024k -acodec copy";// string StrArg = "-i "+StrMP4A+" -acodec copy -vcodec copy -f flv C:\\dis\\test1.mp4";// string StrArg = "-i \"" + StrMP4A + "\" -qscale 6 \"" + StrOutMp4Path + "\"";// "-i " + StrMP4A + " -y -vcodec h264 -b 1500 "+StrOutMp4Path ;string StrArg = "-i " + oriVideoPathc + " -c:v libx264 -strict -2 " + outVideoPathc;p.StartInfo.Arguments = StrArg;p.StartInfo.UseShellExecute = false;//不使用操作系統外殼程序啟動線程(一定為FALSE,詳細的請看MSDN)p.StartInfo.RedirectStandardError = true;//把外部程序錯誤輸出寫到StandardError流中(這個一定要注意,FFMPEG的所有輸出信息,都為錯誤輸出流,用StandardOutput是捕獲不到任何消息的...這是我耗費了2個多月得出來的經驗...mencoder就是用standardOutput來捕獲的)p.StartInfo.CreateNoWindow = true;//不創建進程窗口p.ErrorDataReceived += new DataReceivedEventHandler(Output);//外部程序(這里是FFMPEG)輸出流時候產生的事件,這里是把流的處理過程轉移到下面的方法中,詳細請查閱MSDNp.Start();//啟動線程p.BeginErrorReadLine();//開始異步讀取p.WaitForExit();//阻塞等待進程結束p.Close();//關閉進程p.Dispose();//釋放資源LogHelper.WriteLog("視頻轉換成功:" + outVideoPathc);LogHelper.WriteLog("開始刪除原文件:" + oriVideoPathc);System.IO.File.Delete(oriVideoPathc);LogHelper.WriteLog("原文件刪除成功");}/// <summary>/// 圖片格式轉換/// </summary>public void ConvertImageFormat(){Process p = new Process();//建立外部調用線程p.StartInfo.FileName = ffmpegPathc; //System.Windows.Forms.Application.StartupPath + "\\ffmpeg.exe";//要調用外部程序的絕對路徑// string StrArg = "-i concat:\"" + StrMP4A + "|" + StrMP4B + "\" -vcodec copy -acodec copy " + StrOutMp4Path + " -y";//string StrArg = "- i concat: \"" + StrMP4A + "|" + StrMP4B + "\" - vcodec copy - acodec copy "+ StrOutMp4Path + " -y";// string StrArg = "-i D:\\123.flv -i D:\\water.png -filter_complex \"overlay=10:10\" -b 1024k -acodec copy";// string StrArg = "-i "+StrMP4A+" -acodec copy -vcodec copy -f flv C:\\dis\\test1.mp4";// string StrArg = "-i \"" + StrMP4A + "\" -qscale 6 \"" + StrOutMp4Path + "\"";// "-i " + StrMP4A + " -y -vcodec h264 -b 1500 "+StrOutMp4Path ;string StrArg = "-i " + oriVideoPathc + " " + outVideoPathc;p.StartInfo.Arguments = StrArg;p.StartInfo.UseShellExecute = false;//不使用操作系統外殼程序啟動線程(一定為FALSE,詳細的請看MSDN)p.StartInfo.RedirectStandardError = true;//把外部程序錯誤輸出寫到StandardError流中(這個一定要注意,FFMPEG的所有輸出信息,都為錯誤輸出流,用StandardOutput是捕獲不到任何消息的...這是我耗費了2個多月得出來的經驗...mencoder就是用standardOutput來捕獲的)p.StartInfo.CreateNoWindow = true;//不創建進程窗口p.ErrorDataReceived += new DataReceivedEventHandler(Output);//外部程序(這里是FFMPEG)輸出流時候產生的事件,這里是把流的處理過程轉移到下面的方法中,詳細請查閱MSDNp.Start();//啟動線程p.BeginErrorReadLine();//開始異步讀取p.WaitForExit();//阻塞等待進程結束p.Close();//關閉進程p.Dispose();//釋放資源LogHelper.WriteLog("圖片轉換成功:" + outVideoPathc);LogHelper.WriteLog("開始刪除原文件:" + oriVideoPathc);System.IO.File.Delete(oriVideoPathc);LogHelper.WriteLog("原文件刪除成功");}private void Output(object sendProcess, DataReceivedEventArgs output){if (!String.IsNullOrEmpty(output.Data)){}else{//MessageBox.Show("視頻合成失敗");}}/// <summary>/// 根據類型獲取表名/// </summary>/// <param name="stype"></param>/// <returns></returns>private string GetTableName(string stype){string tableName = "";if (stype == "image"){tableName = "h_res_image";}else if (stype == "shape"){tableName = "h_res_shape";}else if (stype == "music"){tableName = "h_res_music";}else if (stype == "media"){tableName = "h_res_media";}return tableName;}/// <summary>/// 獲取文件擴展名/// </summary>/// <param name="fileName"></param>/// <returns></returns>public string GetExtension(string fileName){if (string.IsNullOrWhiteSpace(fileName) || fileName.IndexOf(".") < 0){return string.Empty;}var arr = fileName.Split('.');return arr[arr.Length - 1];}/// <summary>/// 根據類型驗證上傳文件類型/// </summary>/// <param name="stype"></param>/// <returns></returns>private bool IsValidateFileExtension(string fileExtension){string format = System.Configuration.ConfigurationManager.AppSettings["format"].ToString();bool result = false;fileExtension = fileExtension.Replace(".", "");fileExtension = fileExtension.ToLower();if (format.Contains(fileExtension)){result = true;}return result;}}/// <summary>/// 文件上傳結果/// </summary>public class UploadResult{/// <summary>/// 狀態碼 0失敗 1成功/// </summary>public int Code { get; set; }/// <summary>/// 消息/// </summary>public string Msg { get; set; }/// <summary>/// 上傳編號,唯一/// </summary>public string UploadID { get; set; }/// <summary>/// 文件保存信息/// </summary>public UploadFileInfo FileInfo { get; set; }}public class UploadFileInfo{/// <summary>/// 文件保存名稱/// </summary>public string FileName { get; set; }/// <summary>/// 文件保存路徑/// </summary>public string FilePath { get; set; }/// <summary>/// 文件MD5值/// </summary>public string MD5 { get; set; }}}FileConvertUtil.cs(上傳視頻截圖轉格式功能)
using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; using Newtonsoft.Json;namespace GDSMCommon {public class FileConvertUtil{/// <summary>/// 獲取視頻的第一幀轉換成圖片/// </summary>/// <param name="ffmpegPath">ffmpeg路徑</param>/// <param name="oriVideoPath">視頻路徑</param>/// <param name="thubHeight">轉換后圖片高度</param>/// <param name="frameIndex">第幾幀</param>/// <param name="thubWidth">轉換后圖片的寬度</param>/// <param name="thubImagePath">轉換后圖片存儲路徑</param>public static void MediaExstractImage(string ffmpegPath,string oriVideoPath,string thubHeight,string frameIndex,string thubWidth,string thubImagePath){Process p = new Process();//建立外部調用線程p.StartInfo.FileName =ffmpegPath;//要調用外部程序的絕對路徑string command = string.Format("-i \"{1}\" -vframes 1 -r 1 -ac 1 -ab 2 -s {3}*{4} -f image2 \"{5}\"", ffmpegPath, oriVideoPath, frameIndex, thubWidth, thubHeight, thubImagePath);command = string.Format(" -i \"{0}\" -y -f image2 -ss 00:00:01 -t 0.000001 -s {1}*{2} \"{3}\"",oriVideoPath,thubWidth,thubHeight,thubImagePath);p.StartInfo.Arguments = command;p.StartInfo.UseShellExecute = false;//不使用操作系統外殼程序啟動線程(一定為FALSE,詳細的請看MSDN)p.StartInfo.RedirectStandardError = true;//把外部程序錯誤輸出寫到StandardError流中(這個一定要注意,FFMPEG的所有輸出信息,都為錯誤輸出流,用StandardOutput是捕獲不到任何消息的...這是我耗費了2個多月得出來的經驗...mencoder就是用standardOutput來捕獲的)p.StartInfo.CreateNoWindow = true;//不創建進程窗口p.ErrorDataReceived += new DataReceivedEventHandler(Output);//外部程序(這里是FFMPEG)輸出流時候產生的事件,這里是把流的處理過程轉移到下面的方法中,詳細請查閱MSDNp.Start();//啟動線程p.BeginErrorReadLine();//開始異步讀取p.WaitForExit();//阻塞等待進程結束p.Close();//關閉進程p.Dispose();//釋放資源LogHelper.WriteLog("圖片轉換成功:"+ thubImagePath);}/// <summary>/// 視頻轉成相應格式/// </summary>/// <param name="ffmpegPath"></param>/// <param name="oriVideoPath"></param>/// <param name="outVideoPath"></param>public static void ConvertMp4WithoutTxt(string ffmpegPath,string oriVideoPath, string outVideoPath){Process p = new Process();//建立外部調用線程p.StartInfo.FileName = ffmpegPath;// System.Windows.Forms.Application.StartupPath + "\\ffmpeg.exe";//要調用外部程序的絕對路徑// string StrArg = "-i concat:\"" + StrMP4A + "|" + StrMP4B + "\" -vcodec copy -acodec copy " + StrOutMp4Path + " -y";//string StrArg = "- i concat: \"" + StrMP4A + "|" + StrMP4B + "\" - vcodec copy - acodec copy "+ StrOutMp4Path + " -y";// string StrArg = "-i D:\\123.flv -i D:\\water.png -filter_complex \"overlay=10:10\" -b 1024k -acodec copy";// string StrArg = "-i "+StrMP4A+" -acodec copy -vcodec copy -f flv C:\\dis\\test1.mp4";string StrArg = "-i " + oriVideoPath + " -c:v libx264 -strict -2 " + oriVideoPath; //"-i \"" + oriVideoPath + "\" -qscale 6 \"" + outVideoPath + "\"";// "-i " + StrMP4A + " -y -vcodec h264 -b 500000 "+StrOutMp4Path ;p.StartInfo.Arguments = StrArg;p.StartInfo.UseShellExecute = false;//不使用操作系統外殼程序啟動線程(一定為FALSE,詳細的請看MSDN)p.StartInfo.RedirectStandardError = true;//把外部程序錯誤輸出寫到StandardError流中(這個一定要注意,FFMPEG的所有輸出信息,都為錯誤輸出流,用StandardOutput是捕獲不到任何消息的...這是我耗費了2個多月得出來的經驗...mencoder就是用standardOutput來捕獲的)p.StartInfo.CreateNoWindow = true;//不創建進程窗口p.ErrorDataReceived += new DataReceivedEventHandler(Output);//外部程序(這里是FFMPEG)輸出流時候產生的事件,這里是把流的處理過程轉移到下面的方法中,詳細請查閱MSDNp.Start();//啟動線程p.BeginErrorReadLine();//開始異步讀取p.WaitForExit();//阻塞等待進程結束p.Close();//關閉進程p.Dispose();//釋放資源}/// <summary>/// 轉換后調用方法/// </summary>/// <param name="sendProcess"></param>/// <param name="output"></param>private static void Output(object sendProcess, DataReceivedEventArgs output){if (!String.IsNullOrEmpty(output.Data)){//處理方法...}else{}}} }?
總結
以上是生活随笔為你收集整理的多文件断点续传,上传视频自动转MP4和截图,图片格式转换的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 婚庆APP开发解决方案
- 下一篇: 射频功放学习之数据关联——DAC元件的使