Commit d16bbdb6 authored by Hanruisong's avatar Hanruisong
Browse files

feat: 更新到v1.2.1

1、增加上传指定文件数组的api方法addUploadFile;
2、上传文件前增加isAllowUploadCallback回调方法;
parent ef7a38de
......@@ -12,6 +12,12 @@
<div class="container-fluid">
<div class="row-fluid">
<div class="span10 ml17">
<div style="margin-left:80px;line-height: 40px;">
<div style="color: #337ab7;font-size: 16px;">这是自己处理文件输入框事件的示例</div>
<div>
<input type="file" name="myFile" onchange="outerFileChangeHandle(this);">
</div>
</div>
<div class="upbox" style="margin: 80px;">
<form id="fileupload" method="POST" enctype="multipart/form-data">
<div class="row fileupload-buttonbar">
......
......@@ -63,7 +63,7 @@
this.slots = [];
this.sending = this.active = 0;
this.initEventHandlers();
//上传序号,每个视频进入排时分配,暂停再开时重新进入排队时不再重复分配
//上传序号,每个视频进入排时分配,暂停再开时重新进入排队时不再重复分配
this.startIndex = 0;
if (!this.isSupportBrowse()) {
......@@ -120,8 +120,7 @@
//添加文件事件
$(this.options.fileInput).change(function(e) {
var data = {
fileInput: $(e.target),
form: $(e.target.form)
fileInput: $(e.target)
};
that.getFileInputFiles(data.fileInput).always(function (files) {
data.files = files;
......@@ -753,10 +752,22 @@
}
},
addUploadFile: function (files) {
if (!files.length) {
files = [files];
}
var data = {files: files};
this.onAdd(data);
},
//准备添加一条文件数据
onAdd: function (data) {
var that = this,
result = true;
// 回调用户检查是否需要上传这些视频
if (!that.callback('isAllowUploadCallback', data.files)){
return;
}
data.originalFiles = data.files;
$.each(data.files, function (index, file) {
var newData = $.extend({}, data);
......@@ -814,7 +825,7 @@
},
//验证添加的文件数据是否可以上传
validateAdd: function (fileName,fileSize) {
validateAdd: function (fileName, fileSize) {
// 处理问题信息
var fileType = fileName.split('.').pop().toLowerCase();
var allowVideoTypes = ',wmv,wm,asf,asx,rm,rmvb,ra,ram,mpg,mpeg,mpe,vob,dat,mov,3gp,mp4,mp4v,m4v,mkv,avi,flv,f4v,mts,m2t,';
......
......@@ -2,149 +2,164 @@
loadCategory();
var uploader = new CCH5Uploader(
{
timeout : 180000, // 设置超时处理时间 超时时间3分钟 超时会重试
maxChunkSize : 1024 * 1024, // 1M 最大不超过4M
limitConcurrentUploads : 3, //并发上传文件数
maxRetries : 10, // 文件上传失败重试次数,默认10次
retryTimeout : 500, //重试延迟时间(毫秒)
autoUpload : true, //是否添加文件后自动上传
fileInput : $("#fileupload").find("input[type='file']"), //文件输入组件,必需要有的配置,可以是多个
filesContainer : $('.files'), //上传文件记录显示的容器
// 重写获取分类名的方法,没有分类时不需要配置或者返回null
getCategoryName : function() {
var hasCategory = $("#uploadCategory").length > 0;
if (!hasCategory) {
return null;
}
return $("#selectCategoryInput").attr("title");
},
//重写获取分类id的方法,没有分类时不需要配置或者返回null
getCategoryId : function() {
var hasCategory = $("#uploadCategory").length > 0;
if (!hasCategory) {
return null;
}
return $("#uploadCategory").val();
},
//上传失败重试指定次数后依然失败后的回调
uploadFail : function(recordNode, fileName, failMsg) {
errorMsgHandler(getShortStr(fileName, 10) + "文件上传失败,原因:" + failMsg);
if (recordNode.find('.rate').length > 0) {
if(recordNode.find("#pause").css("display") != "none"){
recordNode.find("#pause").click();
}
// 有暂停操作的示例
recordNode.find('.rate').html('<div class="tc" style="margin-top:6px;color:red;">上传失败</div>');
} else {
// 无暂停操作的示例
recordNode.find('.start').parent().append('<span style="color:red;">上传失败</span>');
}
},
//上传成功回调,可不做任何处理
uploadSuccess : function(recordNode, fileName, ccvid) {
console.log(fileName + '上传成功');
console.log("对应的视频id为:" + ccvid);
console.log(recordNode);
},
// 生成视频信息
createuploadinfo: function(fileName, fileSize, categoryId){
var video = {};
var encodeFileName = encodeURIComponent(fileName);
var d = {
"title" : encodeFileName,
"filename" : encodeFileName,
"filesize" : fileSize
};
//默认分类时不传分类id参数
if (!!categoryId && categoryId != 0) {
d.categoryid = categoryId;
}
$.ajax({
url : "/video/createuploadinfo",
async : false, //必须以同步的方式执行,否则后续操作拿不到接口返回的数据
type : "post",
data : d,
cache : false,
dataType : "json",
contentType : "application/x-www-form-urlencoded; charset=UTF-8",
error : function() {
video = {
"errMsg" : "获取视频文件vid出错",
"errorType" : "network"
};
},
success : function(data) {
if(data.errMsg){
video.errMsg = data.errMsg;
return;
}
video.success = true;
video.uid = data.videoUploadInfo.userid;
video.ccvid = data.videoUploadInfo.videoid;
video.servicetype = data.videoUploadInfo.servicetype;
video.name = fileName;
video.uri = data.videoUploadInfo.chunkurl;
video.metauri = data.videoUploadInfo.metaurl;
video.size = fileSize;
}
});
return video;
}
});
{
timeout: 180000, // 设置超时处理时间 超时时间3分钟 超时会重试
maxChunkSize: 1024 * 1024, // 1M 最大不超过4M
limitConcurrentUploads: 3, //并发上传文件数
maxRetries: 10, // 文件上传失败重试次数,默认10次
retryTimeout: 500, //重试延迟时间(毫秒)
autoUpload: true, //是否添加文件后自动上传
fileInput: $("#fileupload").find("input[type='file']"), //文件输入组件,必需要有的配置,可以是多个
filesContainer: $('.files'), //上传文件记录显示的容器
// 重写获取分类名的方法,没有分类时不需要配置或者返回null
getCategoryName: function () {
var hasCategory = $("#uploadCategory").length > 0;
if (!hasCategory) {
return null;
}
return $("#selectCategoryInput").attr("title");
},
//重写获取分类id的方法,没有分类时不需要配置或者返回null
getCategoryId: function () {
var hasCategory = $("#uploadCategory").length > 0;
if (!hasCategory) {
return null;
}
return $("#uploadCategory").val();
},
//上传失败重试指定次数后依然失败后的回调
uploadFail: function (recordNode, fileName, failMsg) {
errorMsgHandler(getShortStr(fileName, 10) + "文件上传失败,原因:" + failMsg);
if (recordNode.find('.rate').length > 0) {
if (recordNode.find("#pause").css("display") != "none") {
recordNode.find("#pause").click();
}
// 有暂停操作的示例
recordNode.find('.rate').html('<div class="tc" style="margin-top:6px;color:red;">上传失败</div>');
} else {
// 无暂停操作的示例
recordNode.find('.start').parent().append('<span style="color:red;">上传失败</span>');
}
},
//上传成功回调,可不做任何处理
uploadSuccess: function (recordNode, fileName, ccvid) {
console.log(fileName + '上传成功');
console.log("对应的视频id为:" + ccvid);
console.log(recordNode);
},
// 生成视频信息
createuploadinfo: function (fileName, fileSize, categoryId) {
var video = {};
var encodeFileName = encodeURIComponent(fileName);
var d = {
"title": encodeFileName,
"filename": encodeFileName,
"filesize": fileSize
};
//默认分类时不传分类id参数
if (!!categoryId && categoryId != 0) {
d.categoryid = categoryId;
}
$.ajax({
url: "/video/createuploadinfo",
async: false, //必须以同步的方式执行,否则后续操作拿不到接口返回的数据
type: "post",
data: d,
cache: false,
dataType: "json",
contentType: "application/x-www-form-urlencoded; charset=UTF-8",
error: function () {
video = {
"errMsg": "获取视频文件vid出错",
"errorType": "network"
};
},
success: function (data) {
if (data.errMsg) {
video.errMsg = data.errMsg;
return;
}
video.success = true;
video.uid = data.videoUploadInfo.userid;
video.ccvid = data.videoUploadInfo.videoid;
video.servicetype = data.videoUploadInfo.servicetype;
video.name = fileName;
video.uri = data.videoUploadInfo.chunkurl;
video.metauri = data.videoUploadInfo.metaurl;
video.size = fileSize;
}
});
return video;
},
// 是否允许上传回调,files为本次提交的视频文件
isAllowUploadCallback: function(files) {
$.each(files, function(index, file){
console.log(file.name);
});
return true;
}
});
/*******************************************************************************
* 加载分类
*/
function loadCategory() {
$.getJSON('/category/info?t=' + Math.random(), function(data) {
if (data.error) {
errorMsgHandler('加载分类失败');
return;
}
var categoryDatas = data.category;
// 构造分类树
var categoryTree = initCategoryTree({
datas : categoryDatas,
inputId : 'selectCategoryInput',
outerBox : $("#selectCategoryInput").parent(),
needEnsure : false,
hasDefault : true,
defaultName : '默认分类',
defaultVal : $("#uploadCategory").val(),
selectItem : function(categoryId, name, shortName) {
$("#uploadCategory").val(categoryId);
},
setDeaultName : function(name, shortName) {
$("#selectCategoryInput").val(shortName);
}
});
});
$.getJSON('/category/info?t=' + Math.random(), function (data) {
if (data.error) {
errorMsgHandler('加载分类失败');
return;
}
var categoryDatas = data.category;
// 构造分类树
var categoryTree = initCategoryTree({
datas: categoryDatas,
inputId: 'selectCategoryInput',
outerBox: $("#selectCategoryInput").parent(),
needEnsure: false,
hasDefault: true,
defaultName: '默认分类',
defaultVal: $("#uploadCategory").val(),
selectItem: function (categoryId, name, shortName) {
$("#uploadCategory").val(categoryId);
},
setDeaultName: function (name, shortName) {
$("#selectCategoryInput").val(shortName);
}
});
});
}
window.onbeforeunload = function(e) {
if ($('.progress.progress-striped.active.mb0.tc_rel').length) {
return '视频上传中,离开页面将无法继续上传?';
} else {
if (!window.event) {
return null;
}
}
window.onbeforeunload = function (e) {
if ($('.progress.progress-striped.active.mb0.tc_rel').length) {
return '视频上传中,离开页面将无法继续上传?';
} else {
if (!window.event) {
return null;
}
}
};
function getShortStr(str,maxLen){
if(typeof str != 'string' || str.length <= maxLen){
return str;
}
return str.substr(0,maxLen) + '...';
function getShortStr(str, maxLen) {
if (typeof str != 'string' || str.length <= maxLen) {
return str;
}
return str.substr(0, maxLen) + '...';
}
function errorMsgHandler(msg) {
alert(msg);
alert(msg);
}
/***
* 外部file输入框文件变更事件处理
* @param ele
*/
function outerFileChangeHandle(ele) {
uploader.addUploadFile(ele.files);
}
\ No newline at end of file
## 一、集成方式
### 1、前端页面集成
参照demo中提供的示例,引用相关的css和js;其中cch5upload.js是我们实现的一个简单的基于jquery的H5文件分块上传插件,只供集成到CC点播业务使用,封装了上传的主要功能,index.js是示例对cch5upload.js的配置使用,用户可根据具体情况将index.js中的代码复制到用户的代码中使用和修改;配置后上传插件会对文件输入组件进行onchange事件监听和拖拽文件监听;上传文件时会生成页面记录显示,可参照index.html代码;记录是按页面中的模板生成的,用户可根据需要增减相关列,会将记录填充到filesContainer下,filesContainer可查看index.js中的配置说明。记录的html代码中指定的class名称和id尽量不要做修改,因为上传插件中有根据classs和id来查找记录的情况,如需修改样式可以新增class;需要配置createuploadinfo回调方法用于生成视频信息,文件上传到cc视频服务器的接口信息由创建视频信息接口返回,对上传文件接口的调用封装在cch5upload.js中,集成时用户不需要修改。
参照demo中提供的示例,引用相关的css和js;其中cch5upload.js是我们实现的一个简单的基于jquery的H5文件分块上传插件,只供集成到获得场景点播业务使用,
封装了上传的主要功能,index.js是示例对cch5upload.js的配置使用,可根据具体情况将index.js中的代码复制使用和修改;
配置filesContainer后,上传的视频列表会在此标签内以表格的方式显示,将视频文件拖拽到此表格内将自动添加到上传列表。
视频列表是按index.html页面中的模板生成的,可根据需求增减相关列。html模板代码中指定的class名称和id尽量不要做修改,上传插件中有根据classs和id查找记录的情况,如需修改样式可以新增class;
如果配置了fileInput文件输入组件,上传插件会对此文件输入组件进行onchange事件监听处理。
可以通过addUploadFile api添加上传的文件。
createuploadinfo回调方法必须配置,用于生成视频信息,文件上传到获得场景视频服务器的接口地址通过此回调方法获取,
上传文件的调用封装在cch5upload.js中,集成时不需要修改。
### 2、服务端代码集成
上传文件需要用户服务端提供一个接口,此接口再调用CC视频spark系统的创建视频信息接口生成视频信息。出于安全考虑,生成视频信息的接口只能由用户后端代码发起对CC视频spark系统接口的调用。在demo中用户提供的创建视频信息接口路径为/video/createuploadinfo,通过java实现,用户可参考demo进行后端代码集成和修改,也可根据逻辑使用其它后端代码实现接口。运行demo请先修改Config.java中**USER_ID****USER_KEY**的配置。
上传文件需要用户服务端提供一个接口,此接口再调用获得场景视频spark系统的创建视频信息接口生成视频信息。出于安全考虑,生成视频信息的接口只能由用户后端代码发起对获得场景视频spark系统接口的调用。在demo中用户提供的创建视频信息接口路径为/video/createuploadinfo,通过java实现,用户可参考demo进行后端代码集成和修改,也可根据逻辑使用其它后端代码实现接口。运行demo请先修改Config.java中**USER_ID****USER_KEY**的配置。
### 3、cch5upload.js上传插件使用配置说明:
......@@ -24,7 +39,7 @@
* filesContainer : 可选配置,上传文件记录显示的容器,默认为$('.files')
#### 配置回调方法:
* createuploadinfo: 必选配置,上传插件调用此方法创建视频信息,此方法需要请求用户后台接口,再在后台接口请求CC视频spark接口;
* createuploadinfo: 必选配置,上传插件调用此方法创建视频信息,此方法需要请求用户后台接口,再在后台接口请求获得场景视频spark接口;
* errorMsgHandler: 可选配置,显示错误提示方法回调,默认为alert;
......@@ -36,6 +51,18 @@
* uploadSuccess:可选配置,文件上传成功回调,不需要返回值;
* isAllowUploadCallback: 可选配置,文件上传前回调,参数为待上传的文件数组,返回值类型为boolean, 表示是否允许上传;
#### API方法:
addUploadFile:
```typescript
function addUploadFile(files): void;
```
上传指定文件列表,无返回值。
## 二、js依赖版本
* 请使用jquery1.6以上的版本;
......
......@@ -6,6 +6,6 @@ public class Config {
public static final String USER_ID = "CC443A66867376BF";
/* API KEY,登录admin -->云点播 --> 应用 -->API接口 --> 获取key */
public static final String USER_KEY = "ISRcEhHKUiW3SM59OXut28fj4UlvlXg4";
public static final String USER_KEY = "NMZFClnt97dve7veXyjWA4oTPeDCC43G";
}
package com.dreamwin.h5demo.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import com.alibaba.fastjson.JSONObject;
import com.dreamwin.h5demo.exception.SparkException;
import com.dreamwin.h5demo.util.SparkAPI;
import org.apache.log4j.Logger;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import com.alibaba.fastjson.JSONObject;
import com.dreamwin.h5demo.exception.SparkException;
import com.dreamwin.h5demo.util.SparkAPI;
import java.io.IOException;
import java.io.PrintWriter;
public class CategoryServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
......
package com.dreamwin.h5demo.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import com.alibaba.fastjson.JSON;
import com.dreamwin.h5demo.bean.Video;
import com.dreamwin.h5demo.bean.VideoUploadInfo;
import com.dreamwin.h5demo.exception.SparkException;
import com.dreamwin.h5demo.util.SparkAPI;
import org.apache.log4j.Logger;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import org.apache.log4j.Logger;
import com.alibaba.fastjson.JSON;
import com.dreamwin.h5demo.bean.Video;
import com.dreamwin.h5demo.bean.VideoUploadInfo;
import com.dreamwin.h5demo.exception.SparkException;
import com.dreamwin.h5demo.util.SparkAPI;
public class VideoServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
......
package com.dreamwin.h5demo.util;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.dreamwin.h5demo.Config;
import com.dreamwin.h5demo.bean.Video;
import com.dreamwin.h5demo.bean.VideoUploadInfo;
import com.dreamwin.h5demo.exception.SparkException;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
......@@ -9,16 +18,6 @@ import java.net.URLConnection;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.dreamwin.h5demo.Config;
import com.dreamwin.h5demo.bean.Video;
import com.dreamwin.h5demo.bean.VideoUploadInfo;
import com.dreamwin.h5demo.exception.SparkException;
public class SparkAPI {
public static Logger logger = Logger.getLogger(SparkAPI.class);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment