前段时间做视频上传业务,通过网页上传视频到服务器。
视频大小 小则几十M,大则 1G+,以一般的HTTP请求发送数据的方式的话,会遇到的问题:1,文件过大,超出服务端的请求大小限制;2,请求时间过长,请求超时;3,传输中断,必须重新上传导致前功尽弃;
解决方案:
1,修改服务端上传的限制配置;Nginx 以及 PHP 的上传文件限制 不宜过大,一般5M 左右为好;
2,大文件分片,一片一片的传到服务端,再由服务端合并。这么做的好处在于一旦上传失败只是损失一个分片而已,不用整个文件重传,而且每个分片的大小可以控制在4MB以内,服务端限制在4M即可。
前端
Web前端可使用百度的 webuploader H5大文件分片上传插件;官网地址:http://www.ncmem.com/webapp/up6/index.aspx
<div class="section section6 section5">
<div class="part1"><a href="javascript:;" target="_blank" class="part1__btn">批量删除</a><span class="part1__txt"><em class="part1__num" id="upload_num">0</em>个视频,共 <emclass="part1__num" id="upload_size">0M</em></span></div>
<table class="section5__table">
<tbody id="thelist">
<tr class="thead">
<th class="col1 allCkeck"><input type="checkbox" name="" class="col1__checkBox"/>视频名称</th><th class="col2">视频大小</th><th class="col3">视频分类</th><th class="col4">状态</th><th class="col5">进度</th><th>操作</th>
</tr>
</tbody>
</table>
<div class="selFile" id="selFile">
<div id="drag_tips">
<div id="btns__add2"></div>
<h2 class="txt1">选择视频文件</h2>
<span class="txt2">或直接将文件拖拽至此窗口</span>
</div>
</div>
<div class="btns"><span class="btns__add" id="btns__add">+添加视频文件</span><span class="btns__upload btns__upload-start" id="uploadBtn"><i class="btns__upload_icon"></i>开始上传视频</span></div>
</div>
//引入插件
<script type="text/javascript" src="media/js/lib/webuploader/js/webuploader.min.js"></script>
upload.js
1 // 文件上传
2 jQuery(function() {
3 var $ = jQuery,
4 $list = $('#thelist'),
5 $btn = $('#upload-start'),
6 $thead = $('.thead'),
7 $part_btn = $('.part1__btn'), //批量上传按钮
8 state = 'pending',
9 fileCount = 0, //上传文件总数
10 fileSize = 0,//上传文件的总大小
11 // 上传按钮
12 $upload = $('#uploadBtn'),
13 // 所有文件的进度信息,key为file id
14 percentages = {},
15 // 所有文件的md5,key为file id
16 md5Obj = {},
17 // 可能有pedding, ready, uploading, confirm, done.
18 state = 'pedding',
19 uploader;
20
21 //浏览器关闭提醒
22 window.is_confirm = false;
23 $(window).bind('beforeunload', function(){
24 // 只有在标识变量is_confirm不为false时,才弹出确认提示
25 if(window.is_confirm !== false)
26 return '正在上传视频,该操作将丢失视频,是否继续?';
27 })
28
29 if ( !WebUploader.Uploader.support() ) {
30 alert( 'Web Uploader 不支持您的浏览器!如果你使用的是IE浏览器,请尝试升级浏览器');
31 throw new Error( 'WebUploader does not support the browser you are using.' );
32 }
33
34 $(".pop2 .btns__sure").click(function(){
35 $('.popup,.pop').hide();
36 });
37
38 uploader = WebUploader.create({
39 //拖拽容器
40 dnd:'#selFile',
41
42 // 不压缩image
43 resize: false,
44
45 // swf文件路径
46 swf: '/media/js/lib/webuploader/js/Uploader.swf',
47
48 // 文件接收服务端。
49 server: '/service/upload/upload_file',
50 //server:'http://vod.test.4399sy.com/service/upload/ssl_upload_file',
51 formData: {
52 file_id: 'file',
53 guid:new Date().getTime() + Math.ceil(Math.random()*100),
54 file_name:''
55 },
56
57 // 选择文件的按钮。可选。
58 // 内部根据当前运行是创建,可能是input元素,也可能是flash.
59 pick: {
60 id:'#btns__add',
61 innerHTML:"+添加视频文件"
62 },
63
64 // 开起分片上传。
65 chunked: true,
66
67 //如果要分片,分多大一片2M
68 chunkSize:2*1024*1024,
69
70 //上传文件的类型
71 accept:{
72 title: 'Videos',
73 extensions: 'mp4,avi,flv',
74 mimeTypes: 'video/*'
75 },
76 //验证文件总数量, 超出则不允许加入队列。
77 fileNumLimit: 10,
78 //单个文件上传的大小限制 2G
79 fileSingleSizeLimit:2*1024*1024*1024,
80
81 });
82
83 //添加文件具体函数
84 function addFile( file ){
85 var data = new Date(),
86 month = (data.getMonth()+1)<10 ? '0'+(data.getMonth()+1) : (data.getMonth()+1),
87 day = data.getDate()<10 ? '0'+ data.getDate(): data.getDate(),
88 time = data.getFullYear() + "-" + month + "-" + day,
89 $tr = $('<tr class="toBeUploaded" id="'+file.id+'"></tr>'),
90 $td = $('<td class="col1"><input type="checkbox" name="" class="col1__checkBox"/><input type="text" value="'+ file.name +'" name="" class="name"/></td><td class="col2">'+convert_size(file.size)+'</td><td class="col3"><select class="class_id">'+ class_options +'</select></td><td class="col4">读取视频中</td><td class="col5">0%</td><td class="col6"><ul><li class="view"><a target="_blank" href="javascript:;">查看</a></li><li class="delete">删除</li></ul></td>').appendTo($tr),
91