手机版

ajax异步上传带有进度条的视频并提取缩略图

时间:2021-10-01 来源:互联网 编辑:宝哥软件园 浏览:

最近在做一个整合富媒体功能的项目。需要上传视频。这里希望异步上传,有进度条。响应包括状态代码、视频链接和缩略图。

服务器响应

{ ' thumbnail ' : '/SLS xpt//upload/thumbnail/fdceefc . jpg ',' success' : true,' link ' : '/SLS xpt//upload/video/fdceefc . MP ' }并想要我的输入文件控制。原因是表单不能嵌套在表单中。此外,表单标签在浏览器中仍然有一点默认样式,因此可能需要再次编写css。

以前,ajaxFileUpload用于异步上传文件。但是这个东西很久没有更新了,代码中有bug。虽然最后用成功了,但总感觉不好。此外,ajaxFileUpload没有直接添加xhr2的进度事件响应,这相当麻烦。

我上网搜了一下,发现方法很多。

例如,上传文件后,将上传进度放入会话,并轮询服务器会话。但是,我总觉得这个方法有问题。我觉得这个方法看到的进度应该是我的服务器应用程序代码(我的动作)从服务器的临时目录复制文件的进度,因为所有的请求都应该先提交给服务器软件,也就是tomcat,它用session、request等对象封装请求,文件实际上应该是由它接收的。也就是说,在我的动作代码执行之前,文件实际上已经上传了。

后来,我找到了一个更好的方法来使用jquery.form.js插件的ajaxSubmit方法。此方法以表单形式提交,即$。fn.ajaxsubmit. $ (formselector)。ajaxsubmit ({})。这个api的优点是已经处理了xhr2的进度时间,在调用的时候可以传递一个uploadProgress的函数,这样就可以在函数中获取进度。如果不希望输入文件被表单包装也没关系,createElement在代码中应该没问题。但是这个方法失败了,因为我犯了一个小错误,很遗憾。

AjaxSubmit源代码

最后是美元。使用了ajax方法。$.ajax不需要关联表单,这有点像静态方法。唯一遗憾的是,对于美元的进展没有回应。ajax选项。但是,它有一个xhr的参数,这意味着您可以自定义xhr,这样您就可以通过xhr添加长时间的进度事件处理程序。结合看一下ajaxSubmit方法中进度事件的处理,一下子就清楚了。

然后我还可以向$添加一个进度事件处理程序。ajax方法。为了从上传业务中提取dom的操作,我决定把它写成一个插件。下面是插件的代码。

;(函数($){ var defaults={ uploadProgress : null,beforeSend : null,success : null,},设置={ };var upload=function($ this){ $ this。parent().on('change ',$this,function(event){//var $ this=$(event。target),var formData=new FormData(),target=event。目标| |事件。加速;//$.每个(target.files,function(key,value))/{//console。日志(密钥);//formData.append(键,值);//});formData.append('file '),目标。文件[]);设置。fileType formdata。追加(' fileType ',设置。fileType);$.ajax({ url : $this.data('url '),type : 'POST ',data : formData,dataType : 'json ',processData : false,contentType : false,cache : false,before send : function(){//console。日志(“开始”);if(设置。发送前){设置。send()之前;} },xhr : function(){ var xhr=$。AJaxsettings。xhr();if(xhr。上传){ xhr。上传。addeventlistener(' progress ',function(event){ var total=event。总计,位置=事件。已加载| |事件。位置,百分比=;if(事件。长度可计算){ percent=math。天花板(位置/总数*);} if(设置。uploadprogress){设置。上传进度(事件、位置、总数、百分比);} },false);}返回xhr},成功:函数(数据、状态、jXhr){ if(设置。成功){设置。成功(数据);} },错误:函数(jXhr,状态,错误){ if(设置。错误){设置。错误(jXhr,状态,错误);} } });});};$.fn.uploadFile=函数(选项){设置=$ .扩展({},默认值,选项);//文件上传返回这个。每个(函数(){ upload($(this));});} })($ | | jQuery);下面就可以在我的jsp页面里面使用这个美国石油学会(美国石油协会)了。

div class='col-sm-'输入类型=' text ' name=' resource _ URL ' id=' resource _ URL ' hidden=' hidden '/div class=' progress ' style=' display : none;'' div class='进度条进度条-进度条-成功'上传视频进度'角色='进度条' aria-value now=' aria-value min=' ' aria-value max=' ' style=' width :% '/div/div input type=' file ' file ' class=' form-control file inline BTN BTN-primary uploadInput uploadVideo ' accept=' video/MP ' data-URL=' $ { base URL }/upload-video。action ' data-label=' I class=' glyphicon-glyphicon-cicon-cicon-cicon-circle-circle选择文件/script(函数($){ $(文档))。ready(function(){ var $ progress=$(').uploadvideprogress '),start=false$(' input。上传输入。上传视频').上传文件({ beforeSend :函数(){ $progress.parent().show();},uploadProgress :函数(事件、位置、总数、百分比){ $progress.attr('aria-valuenow ',百分比);$progress.width(百分比"%");if(percent=){ $progress.parent().hide();$progress.attr('aria-valuenow ',);$进步。宽度(" % ");} },成功:函数(数据){ if(数据。成功){ setTimeout(function(){ $(' # thumbnail ')).attr('src ',数据。缩略图);},);} } });});})(jQuery);/script /div这里在响应成功的时候设置超时800毫秒之后获取图片,因为提取缩量图是另一个进程在做可能响应完成的时候缩略图还没提取完成

看下效果

提取缩量图

下面部分就是服务端处理上传,并且对视频提取缩量图下面是行为的处理代码

包装组织。莱伊。app。行动;导入组织。阿帕奇。公地。io。fileutils导入组织。阿帕奇。支柱。servletactioncontext导入组织。莱伊。app。基地。BaseAction导入组织。莱伊。图书馆。SiteHears导入组织。莱伊。图书馆。视频实用程序;导入Java。io。文件;导入Java。io。ioexception导入Java。保安。密钥库;导入Java。乌提尔。HashMap导入Java。乌提尔。地图;/** *由管理员在//上创建*/公共类上传操作扩展了基本操作{私有字符串SaveBasePath私有字符串imagePath私有字符串视频路径;私有字符串音频路径;私有字符串缩略图路径;私有文件文件;私有字符串文件文件名;私有字符串文件内容类型;//省略设置吸气剂方法公共字符串视频(){ MapString,Object dataJson=new hashmap String,Object();System.out.println(文件);System.out.println(文件文件名);系统。出去。println(FileContentType);字符串文件扩展=文件文件名。子字符串(文件文件名。lastIndexOf(' . '));字符串新文件名=SiteHears。文件文件名文件。getTotalSpace());字符串typeDir=' normal字符串缩略图名称=空,缩略图文件=空;boolean needThumb=false,extracok=false if(FileContentType。包含('视频'){ TypeDir=视频路径;//提取缩量图需求拇指=真拇指指甲名称=新文件名. jpg ';缩略图文件=app。getrealpath(saveBasePath缩略图路径)“/”缩略图名称;} String realPath=app。getrealpath(SaveBasepath TypeDir);文件保存文件=新文件(真实路径,新文件名文件扩展);//存在同名文件,跳过if(!saveFile.exists()) { if(!saveFile.getParentFile().exists()){ SaveFile。GetParentFile().mkdirs();}请尝试{ FileUtils.copyFile(文件,保存文件);if(NeedThumb){ extract ok=video utils。提取缩略图(保存文件,缩略图文件);System.out.println('提取缩略图成功: ' extra cok);} dataJson.put('success ',true);} catch(IOException e){ system。出去。println(e . getmessage());dataJson.put('success ',false);} }else{ dataJson.put('success ',true);} if(布尔值)datajson。get(' success '){ datajson。放('链接',app。getcontextpath()'/' SaveBasepath TypeDir '/'新文件名文件扩展名);if(needThumb){ datajson。放('缩略图',app。getcontextpath()'/' savebase路径缩略图路径'/'缩略图名称');} }这个。responcejson(Datajson);返回无} }动作配置

action name=' upload-* ' class=' upload action ' method=' { } ' param name=' saveBasePath '/upload/param name=' images path '/images/param name=' video path '/video/param param name=' audio path '/audio/param name=' thumbnail path '/缩略图/param/操作这里个人认为,如果文件的名称跟大小完全一样的话,它们是一个文件的概率就非常大了,所以我这里取文件名跟文件大小做讯息摘要5运算,应该可以稍微避免下重复上传相同文件了。

转码的时候用到FFmpeg。需要的可以去这里下载。

包装组织。莱伊。图书馆;导入Java。io。文件;导入Java。io。ioexception导入Java。io。InputStream导入Java。乌提尔。ArrayList导入Java。乌提尔。列表;/** *由管理员在//上创建*/公共类视频实用程序{公共静态最终字符串FFMPEG _ EXECUTOR=' c :/Software/FFMPEG。exe ';public static final int THUMANT _ WITTER=;public static final int THUMANT _ HEIGHT=;公共静态布尔提取缩略图(文件输入文件,字符串缩略图输出){列表字符串命令=新数组字符串();文件ffmpegExe=新文件(FFMPEG _ EXECUTOR);if(!ffmpegexe。exists()){ system。出去。println('转码工具不存在');返回false}系统。出去。println(ffmpegxe。getabsolutepath());系统。出去。println(InputFile。GetaBsolutePath());命令。add(ffmpegexe。getabsolutepath());命令。添加('-I ');命令。添加(输入文件。GetaBsolutePath());命令。添加('-y ');命令。添加('-f ');命令。添加('图像');命令。添加('-ss ');命令。添加(" ");命令。添加('-t ');command.add(' . ');命令。添加('-s ');command.add(缩略图_宽度' * '缩略图_高度);command.add(拇指指甲输出);流程生成器=新流程生成器();builder.command(命令);建筑商。redirecterrorstream(true);请尝试{长启动时间=系统。currentimemillis();流程流程=构建器。start();System.out.println('启动耗时(系统。current timemillis()-start time();返回真;} catch(IOexception e){ e . print stack trace();返回false} } }另外这里由爪哇岛启动了另外一个进程,在我看来他们应该是互不相干的,java启动了ffmpeg.exe之后,应该回来继续执行下面的代码,所以并不需要单独起一个线程去提取缩量图。测试看也发现耗时不多。每次长传耗时也区别不大,下面是两次上传同一个文件耗时

第一次

第二次

就用户体验来说没有很大的区别。

另外这里上传较大文件需要对雄猫和结构体做点配置

修改雄猫下conf目录下的server.xml文件,为连接器节点添加属性maxPostSize='0 '表示不显示上传大小

另外修改struts.xml添加配置,这里的价值单位为字节,这里大概300多兆位

版权声明:ajax异步上传带有进度条的视频并提取缩略图是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。