因项目要求,从应用系统中将视频与数据关联后把文件存储至FTP服务器中,应用系统点击详情后可查看关联的视频。(FTP服务与应用服务器为两台服务器)。
在需要关联视频的数据后添加操作上传视频操作做按钮
details.html
<div class="layui-card-body">
<table id="LAY-xczfjlcxclxq-manage" lay-filter="LAY-xczfjlcxclxq-manage"></table>
<script type="text/html" id="table-xczfjlcxclxq-webuser">
<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="edit"><i class="layui-icon layui-icon-edit"></i>编辑</a>
<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="details"><i class="layui-icon layui-icon-edit"></i>详情</a>
<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="scsp"><i class="layui-icon layui-icon-video">上传视频</i>
</script>
</div>
在js事件中,先判断登录用户是否有上传视频权限,如果有则打开上传界面
details.js
if(obj.event==='scsp'){
var ajid=obj.data.id
$.ajax({
url:"/total/check",
data:ajid,
type: 'POST',
contentType:'application/json;charset=utf-8',
processData: false
}).success(function (data) {
if(data == "cg"){
layer.open({
type: 2
,title: '上传视频'
,content: '/total/total_scsp/'+ajid
,maxmin: true
,area: ['1000px', '600px']
,success: function(layero,index){
//在回调方法中的第2个参数“index”表示的是当前弹窗的索引。
//通过layer.full方法将窗口放大。
layer.full(index);
}
,btn: ['返回']
,yes: function (index, layero) {
layer.close(index);
}
,success: function(layero, index){
}
});
}else {
layer.open({
title:'提示'
,content:'你无法对其单位数据进行此操作!'
});
}
}).error(function (data) {
layer.msg(data.message);
});
}
Controller.java
跳转打开上传页面
//上传视频页面
@RequestMapping("/total_scsp/{carsId}")
public String totalScsp(@PathVariable("carsId") Integer carsId,Model model) {
Car car = carService.selectById(carsId);
model.addAttribute("car",car);
return "/djffyy/djffyy_upload_video.html";
}
上传页面 upload.html
<div class="layui-col-md12">
<div class="layui-card">
<div class="layui-card-body">
<div class="layui-upload">
<button type="button" class="layui-btn layui-btn-normal" id="test-upload-testList">选择文件</button>(可同时选择多个文件,不能重名,视频大小不能超过300M)
<div class="layui-upload-list">
<table class="layui-table">
<thead>
<tr><th>文件名</th>
<th>大小</th>
<th>上传进度</th>
<th>状态</th>
<th>操作</th>
</tr></thead>
<tbody id="test-upload-demoList"></tbody>
</table>
</div>
<button type="button" class="layui-btn" id="test-upload-testListAction" onclick="gbtxt()">开始上传</button>
</div>
</div>
</div>
</div>
<script>
layui.config({
base: '${ctxPath}/static/layuiadmin/' //静态资源所在路径
}).extend({
index: 'lib/index' //主入口模块
}).use(['element','form','layer'], function(){
var $ = layui.$
,form = layui.form
,upload = layui.upload ;
var element=layui.element;
var demoListView = $('#test-upload-demoList')
var id=document.getElementById("carsid").value
,uploadListIns = upload.render({
elem: '#test-upload-testList'
,url: '/total/total_upload'
,accept: 'video'
,data:{"id":id}
,multiple: true
,auto: false
,bindAction: '#test-upload-testListAction'
,before:function (obj,index) {
layer.load();
var n = 0;
timer = setInterval(function(){
n = n + Math.random()*10|0;
if(n>95){
n = 95;
clearInterval(timer);
}
element.progress('progress_' + index, n+'%');
}, 50+Math.random()*100);
}
,choose: function(obj){
var btnname=document.getElementById("test-upload-testListAction");
btnname.innerHTML="开始上传";
document.getElementById("test-upload-testListAction").disabled=false;
var files = this.files = obj.pushFile(); //将每次选择的文件追加到文件队列
//读取本地文件
obj.preview(function(index, file, result){
var tr = $(['<tr id="upload-'+ index +'">'
,'<td>'+ file.name +'</td>'
,'<td>'+ (file.size/1024).toFixed(1) +'kb</td>'
, '<td><div class="layui-progress layui-progress-big" lay-filter="progress_'+index+'" lay-showPercent="true"><div class="layui-progress-bar" lay-percent="0%"></div></div></td>'
,'<td>等待上传</td>'
,'<td>'
,'<button class="layui-btn layui-btn-mini test-upload-demo-reload layui-hide">重传</button>'
,'<button class="layui-btn layui-btn-mini layui-btn-danger test-upload-demo-delete">删除</button>'
,'</td>'
,'</tr>'].join(''));
//单个重传
tr.find('.test-upload-demo-reload').on('click', function(){
obj.upload(index, file);
});
//删除
tr.find('.test-upload-demo-delete').on('click', function(){
delete files[index]; //删除对应的文件
tr.remove();
uploadListIns.config.elem.next()[0].value = ''; //清空 input file 值,以免删除后出现同名文件不可选
});
demoListView.append(tr);
});
}
,allDone:function (obj) {
var btnname=document.getElementById("test-upload-testListAction");
btnname.innerHTML="上传完成";
document.getElementById("test-upload-testListAction").disabled=true;
layer.closeAll();
}
,done: function(res, index, upload){
element.progress('progress_' + index, '100%'); //一成功就把进度条置为100%
if(res.code == 0){ //上传成功
var tr = demoListView.find('tr#upload-'+ index)
,tds = tr.children();
tds.eq(3).html('<span style="color: #5FB878;">上传成功</span>');
tds.eq(4).html(''); //清空操作
return delete this.files[index]; //删除文件队列已经上传成功的文件
}else {
var tr = demoListView.find('tr#upload-'+ index)
,tds = tr.children();
tds.eq(3).html('<span style="color: #FF5722;">上传失败</span>');
tds.eq(4).find('.test-upload-demo-reload').removeClass('layui-hide'); //显示重传
}
this.error(index, upload);
}
,error: function(index, upload){
var tr = demoListView.find('tr#upload-'+ index)
,tds = tr.children();
tds.eq(3).html('<span style="color: #FF5722;">上传失败</span>');
tds.eq(4).find('.test-upload-demo-reload').removeClass('layui-hide'); //显示重传
}
});
});
function gbtxt() {
var btnname=document.getElementById("test-upload-testListAction");
btnname.innerHTML="上传中,请稍候...";
document.getElementById("test-upload-testListAction").disabled=true;
}
</script>
上传方法Controller.java
//ftp 上传方法
public static boolean uploadFile(String url,// FTP服务器hostname
int port,// FTP服务器端口
String username, // FTP登录账号
String password, // FTP登录密码
String path, // FTP服务器保存目录
String path1, // FTP服务器保存目录1
String filename, // 上传到FTP服务器上的文件名
InputStream input // 输入流
){
boolean success = false;
FTPClient ftp = new FTPClient();
ftp.setControlEncoding("GBK");
try {
int reply;
ftp.connect(url, port);// 连接FTP服务器
// 如果采用默认端口,可以使用ftp.connect(url)的方式直接连接FTP服务器
ftp.login(username, password);// 登录
reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
return success;
}
ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
ftp.makeDirectory(path); //创建文件夹
ftp.changeWorkingDirectory(path); //切换到文件夹
ftp.makeDirectory(path1);
ftp.changeWorkingDirectory(path1);
ftp.storeFile(filename, input);
input.close();
ftp.logout();
success = true;
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ftp.isConnected()) {
try {
ftp.disconnect();
} catch (IOException ioe) {
}
}
}
return success;
}
调用
参数:IP地址,端口,用户名,密码,上传根目录path ,上传子目录path1,文件名、文件流
当上传成功后将需要的管理的信息保存至数据库中
boolean flag = uploadFile("192.168.110.11",21,"cwd",
"cwd2020!@#",lj,Tool.getCurrentDate(),video.getOriginalFilename(),video.getInputStream());
if(flag==true){
code=0;
AjVideo ajVideo = new AjVideo();
ajVideo.setCarnum(carnum);
ajVideo.setVideopath(lj+"/"+Tool.getCurrentDate());
ajVideo.setUploadcompany(deptName);
ajVideo.setUploadtime(currentDate);
ajVideo.setUploadname(name);
ajVideo.setGlid(glid);
ajVideo.setVideoname(video.getOriginalFilename());
ajVideo.insert();
在详情显示界面添加视频列表,有播放下载按钮点击播放按钮调用js打开播放页面
function ck(value) {
layer.open({
type: 2
,title: '正在播放'
,content: '/total/cktsvideo_l/'+value
,maxmin: true
,area: ['600px', '430px']
,success: function(layero, index){
}
});
}
播放页面使用的是ckplayer 。页面显示位置
<div class="layui-card">
<input type="hidden" id="id" value="${id}">
<div id="video" style="width: 100%; height: 350px;max-width: 600px;">
</div>
</div>
var ids=document.getElementById("id").value;
var videoObject = {
container: '#video', //容器的ID或className
variable: 'player', //播放函数名称
loop: true, //播放结束是否循环播放
autoplay: true,//是否自动播放
poster: '../../../../static/js/ckplayer/material/ts.png', //封面图片
preview: { //预览图片
file: ['../../../../static/js/ckplayer/material/ts.png', '../../../../static/js/ckplayer/material/ts.png'],
scale: 2
},
video:[
['${ctxPath}/total/picurTsvideo/'+ids, 'video/mp4', '中文标清', 0]
]
};
var player = new ckplayer(videoObject);
播放器加载时调用后台方法从FTP服务器中下载视频进行播放。首先根据点击播放按钮传递的保存ID 从数据库中查询到要播放的视频文件路劲及视频名称
//查询视频路劲
String videopath=ajVideoService.selectById(id).getVideopath();
//查询视频名称
String videoname=ajVideoService.selectById(id).getVideoname();
//创建FTPClient
FTPClient ftp = new FTPClient();
ftp.setControlEncoding("GBK");
try {
int reply;
ftp.connect("192.168.110.11", 21);// 连接FTP服务器
// 如果采用默认端口,可以使用ftp.connect(url)的方式直接连接FTP服务器
ftp.login("cwd", "cwd2020!@#");// 登录
reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
}
ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
ftp.changeWorkingDirectory(videopath);//切换到文件保存目录
ftp.enterLocalPassiveMode();
FTPFile[] ftpFiles = ftp.listFiles();//获取FTP服务器上的文件别表
InputStream in = null;
OutputStream os = null ;
for (FTPFile file : ftpFiles) { //遍历文件列表
// 取得指定文件
if (file.getName().equals(videoname)) {
if (file.isFile()){
String fileName = file.getName();
//获取文件流
in = ftp.retrieveFileStream(new String(fileName.getBytes("gbk"), "ISO-8859-1"));
//创建ByteArrayOutputStream
ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
int ch;
//循环将文件流写入ByteArrayOutputStream 中
while ((ch = in.read()) != -1) {
swapStream.write(ch);
}
//将ByteArrayOutputStream 转成byte[]
byte[] bytes = swapStream.toByteArray();
//通过输出流输出即可
response.getOutputStream().write(bytes);
os.close();
}
}
}
效果: