1,准备工作:

1,运行环境:jdk1.7; tomcat7;eclipse;

2,运用框架:ssm,webuploader,servlet;

2,   前端部分:

1,html:

<script type="text/javascript" src="<%=request.getContextPath()%>/pages/reception/resources/js/jquery1.8.3.js"></script><script type="text/javascript" src="<%=request.getContextPath()%>/pages/reception/resources/js/webuploader.js"></script><script type="text/javascript" src="<%=request.getContextPath()%>/pages/reception/resources/js/js.js"></script><script src="<%=request.getContextPath()%>/pages/reception/resources/js/jquery-ui.1.12.1.js"></script>
<script type="text/javascript" src="<%=request.getContextPath()%>/pages/reception/resources/js/upLoadVideo.js"></script>
<div class="upvideo"><div class="top clearfix"><span class="msg1"><i></i>选择视频上传</span><a class="upbtn" id="add_video"></a><div class="statusBar01"><div class="progress01"  style="display:none;"><span class="text">0%</span><span class="percentage"></span></div><div class="infovd"><span style="color:red;font-size:12px;">文件大小不可超过1G。</span></div></div></div><div id="item1"></div></div>  

2,js

var fileMd5,// 可能有pedding, ready, uploading, confirm, done.stateVideo = 'pedding',// 添加的文件数量fileCountvd = 0,// 添加的文件总大小fileSizevd = 0,// 文件总体选择信息。$infovd = $(".statusBar01").find('.infovd');//监听分块上传过程中的三个时间点WebUploader.Uploader.register({"before-send-file":"beforeSendFile","before-send":"beforeSend","after-send-file":"afterSendFile",},{//时间点1:所有分块进行上传之前调用此函数beforeSendFile:function(file){var deferred = WebUploader.Deferred();//1、计算文件的唯一标记,用于断点续传(new WebUploader.Uploader()).md5File(file,0,6*1024*1024).progress(function(percentage){//$('#item1').find("p.state").text("正在读取文件信息...");}).then(function(val){fileMd5=val;//$('#item1').find("p.state").text("成功获取文件信息,");//获取文件信息后进入下一步deferred.resolve();});return deferred.promise();},//时间点2:如果有分块上传,则每个分块上传之前调用此函数beforeSend:function(block){var deferred = WebUploader.Deferred();$.ajax({type:"POST",url:BASE_URL+"/VideoProcess?action=checkChunk",data:{//文件唯一标记fileMd5:fileMd5,//当前分块下标chunk:block.chunk,//当前分块大小chunkSize:block.end-block.start},dataType:"json",success:function(response){if(response.ifExist){//分块存在,跳过//alert("跳过");deferred.reject();}else{//分块不存在或不完整,重新发送该分块内容deferred.resolve();}}});this.owner.options.formData.fileMd5 = fileMd5;deferred.resolve();return deferred.promise();},//时间点3:所有分块上传成功后调用此函数afterSendFile:function(file){//如果分块上传成功,则通知后台合并分块var chunksTotal = Math.ceil(file.size / (6*1024*1024));if (chunksTotal > 1) {$.ajax({type:"POST",url:BASE_URL +"/VideoProcess?action=mergeChunks",data:{fileMd5:fileMd5,},success:function(response){//alert("上传成功");/*var path = "uploads/"+fileMd5+".mp4";$("#item1").attr("src",path);*/}});}}}); var uploaderVideo = WebUploader.create({auto:true,// swf文件路径swf: BASE_URL + '/pages/reception/resources/js/Uploader.swf',// 文件接收服务端。server: BASE_URL +"/VideoUpload",// 选择文件的按钮。可选。// 内部根据当前运行是创建,可能是input元素,也可能是flash.pick: {id:'#add_video',multiple:false,},disableGlobalDnd: false,//禁用拖拽功能//开启分片上传chunked: true,chunkSize:6*1024*1024,// 如果某个分片由于网络问题出错,允许自动重传多少次?chunkRetry: 3,prepareNextFile: true,//上传当前分片时预处理下一分片fileNumLimit: 1,fileSingleSizeLimit: 1 * 1024 * 1024 * 1024, // 单个文件大小 M//duplicate:true,//可重复上传//compress:false,compress:null,//默认压缩图片,可以按照原始比例上传图片  threads:1,//上传并发数。允许同时最大上传进程数,为了保证文件上传顺序  accept: {//限制上传文件为MP4extensions: 'mp4,wmv,rmvb,3gp,mov,amv,dmv',mimeTypes: '.mp4,.wmv,.rmvb,.3gp,.mov,.amv,.dmv',}});// 当有文件被添加进队列的时候uploaderVideo.on( 'fileQueued', function( file ) {$('#item1').empty();$('#item1').html('<div id="' + file.id + '" class="item">'+'<p class="filename">文件名称:<span>' + file.name + '</span></p>'+'<p class="filesize">文件大小:<span>' + WebUploader.formatSize(file.size) + '</span></p>'+'<p class="fileext">文件格式:<span>' + file.ext + '</span></p>'+'<p class="filetype">文件类型:<span>' + file.type + '</span></p>'+'<button type="button" id="vdbtn" οnclick="stop()">暂停上传</button>');});// 文件上传过程中创建进度条实时显示。uploaderVideo.on( 'uploadProgress', function( file, percentage ) {$(".statusBar01 .progress01").show();$(".statusBar01 .progress01").find("span.percentage").css('width', Math.round(percentage * 100) + '%');$(".statusBar01 .progress01").find("span.text").text(+Math.round(percentage * 100) + '%');//$('#item1').find('p.state').text('上传中 '+Math.round(percentage * 100) + '%');updateStatusvideo();});// 文件上传成功处理。uploaderVideo.on( 'uploadSuccess', function( file ) {$infovd.find("span").text("上传成功。");console.log(file);console.log("文件名:"+file.name);console.log("文件大小:"+file.size);console.log("文件格式:"+file.ext);console.log("文件类型:"+file.type);});uploaderVideo.on( 'uploadError', function( file ) {$infovd.html('');$infovd.append('<span style="color:red;">上传出错,请检查网络连接。</span>');});// 长传完毕,不管成功失败都会调用该事件,主要用于关闭进度条uploaderVideo.on( 'uploadComplete', function( file ) {$(".statusBar01 .progress01").fadeOut();$('#vdbtn').hide();});uploaderVideo.onError = function(code) {alert('Error: ' + code);};function start(){uploaderVideo.upload();$('#vdbtn').attr("onclick","stop()");$('#vdbtn').text("暂停上传");}function stop(){uploaderVideo.stop(true);$('#vdbtn').attr("onclick","start()");$('#vdbtn').text("继续上传");}uploaderVideo.onFileQueued = function(file) {fileCountvd++;fileSizevd += file.size;setState('ready');};uploaderVideo.onFileDequeued = function(file) {fileCount--;fileSize -= file.size;if (!fileCount) {setState('pedding');}updateStatusvideo();};uploaderVideo.on('all',function(type) {var stats;switch (type) {case 'uploadFinished':setState('confirm');break;case 'startUpload':setState('uploading');break;case 'stopUpload':setState('paused');break;}});function setState(val) {var file, stats;if (val === stateVideo) {return;}state = val;//显示进度条switch (stateVideo) {case 'uploading':$(".statusBar01 .progress01").show();break;case 'paused':$(".statusBar01 .progress01").show();break;case 'confirm':$(".statusBar01 .progress01").hide();stats = uploaderVideo.getStats();if (stats.successNum && !stats.uploadFailNum) {setState('finish');return;}break;case 'finish':stats = uploaderVideo.getStats();if (stats.successNum) {//alert('上传成功');} else {// 没有成功的图片,重设stateVideo = 'done';location.reload();}break;}updateStatusvideo();}function updateStatusvideo() {var text = '',stats;if (state === 'ready') {text = '已选择' + fileCountvd + '个视频,共' + WebUploader.formatSize(fileSizevd) + '。';} else if (state === 'confirm') {stats = uploaderVideo.getStats();if (stats.uploadFailNum) {text = '已成功上传' + stats.successNum + '个视频至视频库,' + stats.uploadFailNum + '个视频上传失败。'}} else {stats = uploaderVideo.getStats();text = '已选择' + fileCountvd + '个视频(' + WebUploader.formatSize(fileSizevd) + '),<span>正在上传中...</span>';if (stats.uploadFailNum) {text += ',失败' + stats.uploadFailNum + '个';}}$infovd.html(text);}

3,后端部分:

需要注意:一开始用的ssm框架集成webuploader去实现断点续传,但是过程中发现这个类ServletFileUpload不兼容ssm,获取不到webuploader插件传到后台的数据,因为改用原生servlet兼容ssm去实现上传;

package com.imagelibrary.imagesnews.controller.video;import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FileUtils;
import com.imagelibrary.imagesnews.model.SystemConstants;@SuppressWarnings("serial")
public class VideoUpload extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {super.doGet(req, resp);doPost(req, resp);}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {DiskFileItemFactory factory = new DiskFileItemFactory();ServletFileUpload sfu = new ServletFileUpload(factory);sfu.setHeaderEncoding("utf-8");Date date = new Date();SimpleDateFormat sdf = new SimpleDateFormat("/yyyy/MM/dd");String videoPath = sdf.format(date);//1. 文件保存路径---本地盘符//String savePath = "D:\\video" + videoPath;//2. 文件保存路径---虚拟机本地盘符String savePath = SystemConstants.SFTP_directory_video + videoPath;String fileMd5 = null;String chunk = null;String fileName = "";try {List<FileItem> items = sfu.parseRequest(request);for(FileItem item:items){if(item.getFieldName().equals("name")){  fileName = new String(item.getString().getBytes("ISO-8859-1"), "UTF-8");//System.out.println(fileName);request.getSession().setAttribute("fileName", fileName);}if(item.isFormField()){String fieldName = item.getFieldName();if(fieldName.equals("fileMd5")){fileMd5 = item.getString("utf-8");}if(fieldName.equals("chunk")){chunk = item.getString("utf-8");}}else{File file = new File(savePath+"/"+fileMd5);if(!file.exists()){file.mkdir();}File chunkFile = new File(savePath+"/"+fileMd5+"/"+chunk);FileUtils.copyInputStreamToFile(item.getInputStream(), chunkFile);}}} catch (FileUploadException e) {e.printStackTrace();}}
}
package com.imagelibrary.imagesnews.controller.video;import java.io.File;import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.imagelibrary.imagesnews.model.SystemConstants;@SuppressWarnings("serial")
public class VideoProcess extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {super.doGet(request, response);doPost(request, response);}@SuppressWarnings("resource")public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {Date date = new Date();SimpleDateFormat sdf = new SimpleDateFormat("/yyyy/MM/dd");String videoPath = sdf.format(date);//1. 文件保存路径---本地盘符//String savePath = "D:\\video" + videoPath;//2. 文件保存路径---虚拟机本地盘符String savePath = SystemConstants.SFTP_directory_video + videoPath;      String action = request.getParameter("action");if(action.equals("mergeChunks")){//合并文件//需要合并的文件的目录标记String fileMd5 = request.getParameter("fileMd5");//读取目录里的所有文件File f = new File(savePath+"/"+fileMd5);File[] fileArray = f.listFiles(new FileFilter(){//排除目录只要文件@Overridepublic boolean accept(File pathname) {if(pathname.isDirectory()){return false;}return true;}});//转成集合,便于排序List<File> fileList = new ArrayList<File>(Arrays.asList(fileArray));Collections.sort(fileList,new Comparator<File>() {@Overridepublic int compare(File o1, File o2) {if(Integer.parseInt(o1.getName()) < Integer.parseInt(o2.getName())){return -1;}return 1;}});//获取视频名称String fileName = (String) request.getSession().getAttribute("fileName");//截取文件名的后缀名  //最后一个"."的位置  int pointIndex=fileName.lastIndexOf(".");  //后缀名  String suffix=fileName.substring(pointIndex);  //合并后的文件  //UUID.randomUUID().toString()-->随机名//File outputFile = new File(savePath+"/"+fileMd5+".mp4");File outputFile = new File(savePath+"/"+fileMd5+suffix);//创建文件outputFile.createNewFile();//输出流FileChannel outChnnel = new FileOutputStream(outputFile).getChannel();//合并FileChannel inChannel;for(File file : fileList){inChannel = new FileInputStream(file).getChannel();inChannel.transferTo(0, inChannel.size(), outChnnel);inChannel.close();//删除分片file.delete();}outChnnel.close();//清除文件夹File tempFile = new File(savePath+"/"+fileMd5);if(tempFile.isDirectory() && tempFile.exists()){tempFile.delete();}String newName = outputFile.getName();//System.out.println(newName);//System.out.println("合并成功");//request.setAttribute("videoPath",videoPath1);SystemConstants.SFTP_httpUrl + "/video" + videoPath + newName//request.getRequestDispatcher("/imagelibrary/webapp/pages/reception/upLoadVideo.jsp").forward(request, response);request.getSession().setAttribute("videoPath", SystemConstants.SFTP_httpUrl + "/video" + videoPath + "/" + newName);}else if(action.equals("checkChunk")){//检查当前分块是否上传成功String fileMd5 = request.getParameter("fileMd5");String chunk = request.getParameter("chunk");String chunkSize = request.getParameter("chunkSize");File checkFile = new File(savePath+"/"+fileMd5+"/"+chunk);response.setContentType("text/html;charset=utf-8");//检查文件是否存在,且大小是否一致if(checkFile.exists() && checkFile.length()==Integer.parseInt(chunkSize)){//上传过response.getWriter().write("{\"ifExist\":1}");}else{//没有上传过response.getWriter().write("{\"ifExist\":0}");}}}
}

4,总结

如需进一步了解,请加:QQ:86466280;

断点续传大文件,视频相关推荐

  1. vue上传大文件/视频前后端(java)代码

    vue上传大文件/视频前后端(java)代码 一.上传组件 二.后端java代码 注意: 一.上传组件 <template><div><!-- 上传组件 -->&l ...

  2. SpringBoot 实现大文件视频转码(转码基于FFMPEG实现)

    最近项目需要将用户上传的视频如果不是MP4格式,需要全部转码为MP4格式的,这里我通过FFMPeg进行大文件视频转码的实现. 一.安装FFMPeg 首先我们需要在机器上安装FFMPeg用于我们的视频转 ...

  3. uni-app上传大文件/视频失败详解

    大文件/视频上传失败可能会给你造成一个跨域的假象,仔细分析一下,如果小文件/视频可以上传成功.就说明不是跨域的问题,可以排除跨域.就可能是一下三个原因造成大文件/视频上传失败. 原因一: APP做了上 ...

  4. thinkphp6+webuploader实现大文件(视频)分片上传/本地保存或上传OSS

    thinkPHP6+webuploader分片上传大视频的解决方案: ①能解决视频太大,1G.2G直传服务器压力过大 ②部分追求完美的人不发接受直传,那只能分片上传 ③分片上传是我找到的比较合理的解决 ...

  5. 七牛云分片批量上传大文件视频

    原本用的element上传组件,结果发现大视频总是失败,还跑出outMemoryError :java heap space 内存溢出,排查:jvm内存默认256m,每次文件上传,用的是muiltip ...

  6. PHP上传大文件视频到阿里云oss分片上传

    下载阿里云oss的SDK composer require aliyuncs/oss-sdk-php 上传视频,我用的是分片上传,其实阿里云的文档已经写得很清楚了,不过这是当我把上传的功能写出来后才这 ...

  7. react+antd的Upload 通过证书 上传大文件视频至oss(上传视频)

    主要代码 1. form表单的upload组件引入<Form.Item label="上传视频">{getFieldDecorator('url', {getValue ...

  8. 【微信小程序分包上传大文件/视频】

    这不前两天来了个奇葩需求,我写的小视频平台人家要上传2个G以上的视频,一开始咋想都想不通怎么写,后来一下就茅厕顿开了属于是,话不多说直接上码! upload.js: var bytesPerPiece ...

  9. Web大文件(视频)上传解决方案

    前言:因自己负责的项目(jetty内嵌启动的SpringMvc)中需要实现文件上传,而自己对java文件上传这一块未接触过,且对 Http 协议较模糊,故这次采用渐进的方式来学习文件上传的原理与实践. ...

最新文章

  1. 关于一个无限分类的多选,单选相关的控件
  2. UNIX编程笔记:关于停止的进程接收信号的问题
  3. 努力就要晒出来,13周年订阅专栏送图书/T恤晒单集结号!!!
  4. berkeley db mysql_BDB:源自 Berkeley DB,事务型数据库
  5. 存储基础知识一 主要技术DAS、SAN、NAS
  6. 这个文件传输神器完爆 FTP
  7. Verilator简介及其下载安装卸载
  8. 子集数据帧中的丢包因子级别
  9. java中map类型_Java中Map类型遍历的两种方式对比
  10. nanopc t3开发板系统烧录_基础教程18 定制 Arduino 系统
  11. 汇编编写正弦函数代码
  12. KYLO的Java基础知识总结(其二)
  13. 安卓如何实现图文混排
  14. FAT表、Fat32与exFat与NTFS分区
  15. 微信小程序 - 云开发轮询实现定时推送订阅消息
  16. 【中英】【吴恩达课后测验】Course 3 -结构化机器学习项目 - 第二周测验
  17. 楚琳Web打印控件可以在MVC中调用嘛?
  18. 什么是soft wrap,什么是IDEA的soft wrap,如何设置IDEA默认所有类型的文件都自动换行(如何设置用IDEA打开markdown文件不自动换行)
  19. RCWL0516微波雷达传感器(基于传感器管理组件)
  20. groovy安装教程

热门文章

  1. C/C++小项目(迷人的眼睛)
  2. from用法 prepare_使用 PREPARE 的几个注意点
  3. clickhouse 查询优化_如何提升查询速度?试试ClickHouse
  4. 游戏计算机性能要求吗,能玩游戏的笔记本需要哪些条件
  5. JAVA写的坦克大战(简单)
  6. 手机电池充电时间计算方法
  7. springboot项目使用beetl模板引擎生成word文件
  8. 【C#】人力资源管理系统「WinForm」「sql server」「内附全代码」
  9. python项目之守卫家园
  10. GameFrameWrok-StarForce的熱更强更步驟