/**
* 上传学习视频信息
*/
@Log(title = "上传学习视频信息", businessType = BusinessType.INSERT)
@PostMapping("/uploadVideo")
public AjaxResult add(HttpServletRequest request) {
return toAjax(videoInfoService.insertVideoInfo(request));
}
/**
* 上传学习视频信息
*
* @param request 学习视频信息
* @return 结果
*/
@Override
public int insertVideoInfo(HttpServletRequest request) {
// 获取视频文件
MultipartFile videoFile = ((MultipartHttpServletRequest) request).getFile("file");
VideoInfo sysVideoInfo = new VideoInfo();
if ((videoFile != null) && (!videoFile.isEmpty())) {
// 获取项目路径
String projectPath = RuoYiConfig.getUploadPath();
// 获得文件名
String oriFileName = videoFile.getOriginalFilename();
//不带点后缀
String suffix = FilenameUtils.getExtension(oriFileName);
// 获取文件大小
long size = videoFile.getSize() / 1024;
// 设置默认deviceNumber
String deviceNumber = "learning";
sysVideoInfo.setDeviceNumber(deviceNumber);
// 获取文件夹路径
String folderPath = projectPath + File.separator + "videoInfo/info" + File.separator + deviceNumber + File.separator;
// 获取文件路径
String filePath = folderPath + oriFileName;
//判断文件夹是否存在
File file1 = new File(folderPath);
if (!file1.exists()) {
file1.mkdirs();//创建目录
}
File dest = new File(filePath);
if (dest.exists()) {
//文件已存在
return 2;
}
try {
videoFile.transferTo(dest);
sysVideoInfo.setFileMd5(Md5Util.getFileMD5(dest));
} catch (IOException e) {
e.printStackTrace();
}
// 设置ID
sysVideoInfo.setId(GUIDCreater.getGUID());
// 设置视频类型
//sysVideoInfo.setVideoType(videoType);
// 设置文件名
sysVideoInfo.setFileName(oriFileName);
// 设置存储路径
sysVideoInfo.setFilePath(filePath);
// 设置下载路径
String downloadPath = "videoInfo/info/download/" + deviceNumber + "/" + oriFileName.substring(0, oriFileName.lastIndexOf(".")) + "/" + suffix;
sysVideoInfo.setDownloadPath(downloadPath);
// 设置文件大小
sysVideoInfo.setFileSize(String.valueOf(size));
} else {
return 0;
}
return videoInfoMapper.insertVideoInfo(sysVideoInfo);
}
/**
* 下载视频
*
* @param fileName 文件名
* @param fileSuffix 文件后缀
* @param request
* @param response
* @throws IOException
* @throws ServletException
*/
@GetMapping("/download/{device_number}/{file_name}/{file_suffix}")
public void downloadProgramFile(@PathVariable("device_number") String deviceNumber, @PathVariable("file_name") String fileName, @PathVariable("file_suffix") String fileSuffix
, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
fileName += "." + fileSuffix;
String localPath = RuoYiConfig.getProfile();
String fileRealPath = localPath + File.separator + "upload" + File.separator + "/videoInfo/info" + File.separator + deviceNumber + File.separator + fileName;
//设置文件路径
File file = new File(fileRealPath);
if (!file.exists()) {
response.sendError(404, "视频文件不存在,下载失败");
return;
}
Path filePath = Paths.get(fileRealPath);
String mimeType = Files.probeContentType(filePath);
response.setContentType(mimeType);
request.setAttribute(NonStaticResourceHttpRequestHandler.ATTR_FILE, filePath);
nonStaticResourceHttpRequestHandler.handleRequest(request, response);
}
//新建一个文件
package com.ruoyi.image;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;
import javax.servlet.http.HttpServletRequest;
import java.nio.file.Path;
@Component
public class NonStaticResourceHttpRequestHandler extends ResourceHttpRequestHandler {
public final static String ATTR_FILE = "NON-STATIC-FILE";
@Override
protected Resource getResource(HttpServletRequest request) {
final Path filePath = (Path) request.getAttribute(ATTR_FILE);
return new FileSystemResource(filePath.toString());
}
}
-------------------------------------------------------------------------------------------------------------
前端记录
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="视频名称" prop="fileName">
<el-input
v-model="queryParams.fileName"
placeholder="请输入视频名称"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleImport"
>上传</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['videoInfo:info:remove']"
>删除</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<div ref="tableDom">
<el-table v-loading="loading" :data="infoList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="视频文件名称" align="center" prop="fileName" />
<el-table-column label="视频文件存储路径" align="center" prop="filePath" />
<el-table-column label="视频文件大小" align="center" prop="fileSize" />
<el-table-column label="视频文件上传时间" align="center" prop="uploadDate" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.uploadDate, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="下载路径" align="center" prop="downloadPath" />
<el-table-column label="视频预览" align="center">
<template slot-scope="scope">
<el-button
type="primary"
size="small"
@click="handlePlay(scope.row)"
>
预览
</el-button>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['videoInfo:info:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<el-dialog title="视频预览" :visible.sync="open">
<video-player
class="video-player vjs-custom-skin"
ref="videoPlayer"
:playsinline="true"
:options="playerOptions"
>
</video-player>
</el-dialog>
<uploadVideoDialog
@handleSaveSuccess="getList"
ref="uploadVideoDialogRef"
></uploadVideoDialog>
</div>
</template>
<script>
import { listInfo, getInfo, delInfo, addInfo, updateInfo } from "@/api/videoInfo/info";
import uploadVideoDialog from "./uploadVideoDialog";
// import { videoPlayer } from 'vue-video-player'
// import 'video.js/dist/video-js.css'
export default {
components: { uploadVideoDialog},
name: "Info",
data() {
return {
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
// 学习视频信息表格数据
infoList: [],
// 弹出层标题
title: "",
// 是否显示弹出层
open: false,
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 10,
fileName: null,
},
// 视频预览窗口
open: false,
// 表单参数
form: {},
// 播放参数
playerOptions: {},
removeParams: {
filePaths: [],
ids: [],
},
// 选中视频id
videoId: "",
tableHeight: "",
// 表单参数
form: {},
// 表单校验
rules: {
}
};
},
created() {
this.getList();
},
mounted() {
var _this = this;
this.resizeTable();
window.onresize = function () {
_this.resizeTable();
};
},
//记得清空 如果在keepalive中 则使用activated deactivated
destroyed() {
window.onresize = null;
},
methods: {
/** 查询学习视频信息列表 */
getList() {
this.loading = true;
listInfo(this.queryParams).then(response => {
this.infoList = response.rows;
this.total = response.total;
this.loading = false;
});
},
// 取消按钮
cancel() {
this.open = false;
this.reset();
},
// 表单重置
reset() {
this.form = {
id: null,
videoType: null,
fileName: null,
filePath: null,
fileSize: null,
uploadDate: null,
delFlag: null,
fileMd5: null,
deviceNumber: null,
nickName: null,
jobNumber: null,
userId: null,
downloadPath: null
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 预览按钮 */
handlePlay(row) {
console.log("row");
console.log(row);
const name = row.fileName.substring(0, row.fileName.lastIndexOf("."));
const downloadPath = row.downloadPath;
console.log(downloadPath);
this.open = true;
console.log(process.env.VUE_APP_BASE_API + "/" + downloadPath);
this.playerOptions = {
playbackRates: [0.75, 1.0, 1.25, 1.5, 2.0], //播放速度
autoplay: false, // 是否自动播放。
muted: false, // 是否静音播放,默认情况下将会消除任何音频。
loop: false, // 是否循环播放。
preload: "auto", // 建议浏览器在<video>加载元素后是否应该开始下载视频数据。auto浏览器选择最佳行为,立即开始加载视频(如果浏览器支持)
language: "zh-CN",
aspectRatio: "16:9", // 将播放器置于流畅模式,并在计算播放器的动态大小时使用该值。值应该代表一个比例 - 用冒号分隔的两个数字(例如"16:9"或"4:3")
fluid: true, // 是否流体从而按比例缩放以适应其容器。
flash: { hls: { withCreadentials: false } }, //可以播放rtmp视频
html5: { hls: { withCreadentials: false } }, //可以播放m3u8视频
sources: [
{
type: "video/mp4", // 播放的类型,在这里项目中需要的是rtmp,也可以修改为:‘video/mp4’
src:process.env.VUE_APP_BASE_API + "/" + downloadPath,
//src:"http://127.0.0.1:8088/videoInfo/info/download/learning/测试视频/mp4/",
//src :"https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/2minute-demo.mp4"
},
],
width: "100%",
notSupportedMessage: "此视频暂无法播放...", // 当无法播放时允许覆盖Video.js,显示的默认信息。
controlBar: {
timeDivider: true,
durationDisplay: true,
remainingTimeDisplay: false,
fullscreenToggle: true,
},
};
},
// 打开上传文件弹出框
handleImport() {
this.$refs.uploadVideoDialogRef.open();
},
//table自动高度
returnTableHeight(ref, bottomOffset) {
let height = null;
height =
window.innerHeight - ref.getBoundingClientRect().top - bottomOffset;
return height;
},
resizeTable() {
this.$nextTick(() => {
this.tableHeight = this.returnTableHeight(this.$refs.tableDom, 100);
}, 0);
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.id != null) {
updateInfo(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addInfo(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids;
this.$modal.confirm('是否确认删除学习视频信息编号为"' + ids + '"的数据项?').then(function() {
return delInfo(ids);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
}
};
</script>
上传文件的弹窗
<template>
<div class="app-container">
<el-dialog
:title="setLightTitle"
:visible.sync="visible"
:close-on-click-modal="false"
width="25%"
>
<el-form
ref="appForm"
style="margin-bottom: -30px"
:model="appData"
:rules="rules"
size="small"
label-width="100px"
>
<div style="margin: 0 auto; text-align: center">
<el-upload
action="#"
ref="upload"
:show-file-list="true"
:auto-upload="false"
:multiple="false"
:on-change="uploadFile"
:limit="1"
drag
accept=".mp4"
>
<i class="el-icon-upload"></i>
<div class="el-upload__text">
将文件拖到此处,或<em>点击上传</em>
</div>
<div class="el-upload__tip text-center" slot="tip">
<span>仅允许mp4文件。</span>
</div>
</el-upload>
</div>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="visible = false" type="primary" size="small"
>取 消</el-button
>
<el-button
type="primary"
size="small"
@click="handleUpload"
:loading="loading"
>确 定</el-button
>
</span>
</el-dialog>
</div>
</template>
<script>
import { addInfo } from "@/api/videoInfo/info";
export default {
name: "upload-file-dialog",
data() {
return {
file: null,
formData: null,
updateVersion: null, //上传版本
updateSupport: null, //是否全部更新
appData: {
handwareid: null,
updateVersion: null,
updateSupport: null,
},
loading: false,
visible: false,
setLightTitle: "上传视频",
acceptFile: ".mp4",
rules: {
updateVersion: [
{ required: true, message: "请xx", trigger: "blur" },
],
},
};
},
methods: {
dialogClose() {
this.visible = false;
},
open() {
this.file = null;
this.formData = null;
this.visible = true;
this.updateVersion = null;
this.updateSupport = false;
this.$refs.upload?.clearFiles();
},
uploadFile(item) {
this.file = item.raw; // 通过DOM取文件数据
this.formData = new FormData(); //new一个formData事件
this.formData.append("file", this.file); //将file属性添加到formData里
},
handleUpload() {
if (this.file == null) {
this.$message("请先选择文件!");
return;
}
let vm = this;
this.$refs.appForm.validate((valid) => {
if (valid) {
vm.loading = true;
addInfo(vm.formData)
.then((response) => {
vm.loading = false;
this.$refs.upload.clearFiles();
if (response.code === 200) {
vm.visible = false; //关闭窗口
vm.$emit("handleSaveSuccess"); //成功通知父窗口
vm.$message("上传成功!");
}
})
.catch(function (error) {
vm.loading = false;
setTimeout(() => {
vm.$message("上传失败!" + error);
}, 150);
});
}
});
},
},
};
</script>
<style scoped>
/deep/ .el-upload {
width: 70%;
height: 100%;
}
/deep/ .el-upload .el-upload-dragger {
width: 100%;
height: 100%;
}
</style>
08-14
1万+

08-08
788

02-14
5304
