本篇文章提供现成的前端代码+后端代码,实现视频内容上传
演示
前端代码
考虑到该组件适用性,采用HTML + CDN引入的方式编写代码。核心组件为el-upload,该组件会自动上传用户选择的视频内容
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>视频上传平台</title>
<script src="https://unpkg.com/vue@3"></script>
<!-- import CSS -->
<link rel="stylesheet" href="https://unpkg.com/element-plus/dist/index.css">
<!-- import JavaScript -->
<script src="https://unpkg.com/element-plus"></script>
<script src="https://unpkg.com/element-plus"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
</head>
<body>
<div id="app">
<div class="main-container">
<div class="upload-card">
<div class="header">
<i class="fas fa-video icon"></i>
<h1>视频上传中心</h1>
</div>
<el-upload
class="custom-upload"
action="http://localhost:8080/api/upload/video"
:on-success="handleSuccess"
:on-error="handleError"
:before-upload="beforeUpload"
:limit="5"
accept="video/*"
:auto-upload="true"
:file-list="fileList"
drag
>
<div class="upload-area">
<i class="fas fa-cloud-upload-alt cloud-icon"></i>
<div class="upload-text">
<p>拖放文件到这里 或</p>
<el-button type="primary" class="upload-button">
<i class="fas fa-upload button-icon"></i>选择文件
</el-button>
</div>
</div>
<template #tip>
<div class="upload-tip">
<i class="fas fa-info-circle tip-icon"></i>
支持格式:MP4/AVI/MOV,最大500MB
</div>
</template>
</el-upload>
</div>
</div>
</div>
<script>
const { createApp } = Vue;
const { ElUpload, ElButton, ElMessage } = ElementPlus;
createApp({
data() {
return { fileList: [] };
},
methods: {
handleSuccess(response) {
ElMessage({
message: '上传成功!视频路径:' + response.filePath,
type: 'success',
duration: 5000,
showClose: true
});
},
handleError() {
ElMessage.error('上传失败,请检查网络或文件格式');
},
beforeUpload(file) {
const isVideo = file.type.startsWith('video/');
const isLt500M = file.size / 1024 / 1024 < 500;
if (!isVideo) {
ElMessage.error('仅支持视频文件');
return false;
}
if (!isLt500M) {
ElMessage.error('文件大小超过500MB限制');
return false;
}
return true;
}
}
})
.use(ElementPlus)
.mount('#app');
</script>
<style>
body {
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
min-height: 100vh;
margin: 0;
font-family: 'Helvetica Neue', Arial, sans-serif;
}
.main-container {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
padding: 20px;
}
.upload-card {
background: white;
border-radius: 16px;
box-shadow: 0 8px 30px rgba(0,0,0,0.12);
padding: 40px;
width: 100%;
max-width: 600px;
transition: transform 0.3s ease;
}
.upload-card:hover {
transform: translateY(-5px);
}
.header {
text-align: center;
margin-bottom: 30px;
}
.icon {
font-size: 48px;
color: #409EFF;
margin-bottom: 15px;
}
h1 {
color: #2c3e50;
margin: 0;
font-weight: 600;
}
.upload-area {
padding: 40px 20px;
border: 2px dashed #e0e0e0;
border-radius: 12px;
transition: all 0.3s ease;
}
.upload-area:hover {
border-color: #409EFF;
background: #f8f9ff;
}
.cloud-icon {
font-size: 64px;
color: #409EFF;
margin-bottom: 20px;
opacity: 0.8;
}
.upload-text {
font-size: 16px;
color: #666;
line-height: 1.6;
}
.upload-button {
margin-top: 15px;
padding: 12px 28px;
font-size: 16px;
letter-spacing: 0.5px;
transition: all 0.3s ease;
}
.button-icon {
margin-right: 8px;
}
.upload-tip {
margin-top: 20px;
color: #909399;
font-size: 14px;
display: flex;
align-items: center;
justify-content: center;
}
.tip-icon {
margin-right: 8px;
color: #409EFF;
}
@media (max-width: 768px) {
.upload-card {
padding: 25px;
border-radius: 12px;
}
.cloud-icon {
font-size: 48px;
}
}
</style>
</body>
</html>
后端代码
依然是考虑读者cv代码的方便程度,因此将所有逻辑写入Controller。需要注意的是,当前代码存储视频路径被写死,通过UPLOAD_DIR
指定。读者可根据实际情况改变存储方式,譬如oss对象存储
@RestController
@RequestMapping("/api/upload")
public class VideoUploadController {
// 获取 resources 目录的真实路径
private static final String UPLOAD_DIR = "E:\java_code\video-upload\src\main\resources\uploads";
@PostMapping("/video")
@CrossOrigin(origins = "*")
public ResponseEntity<Map<String, Object>> uploadVideo(@RequestParam("file") MultipartFile file) {
Map<String, Object> response = new HashMap<>();
if (file.isEmpty()) {
response.put("message", "文件为空,请选择一个文件!");
return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST);
}
String fileName = file.getOriginalFilename();
if (fileName == null || !fileName.toLowerCase().matches(".*\.(mp4|avi|mov|mkv)$")) {
response.put("message", "只能上传视频文件(支持格式:MP4、AVI、MOV、MKV)!");
return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST);
}
try {
// 获取 resources 目录的真实路径
File uploadDir = new File(UPLOAD_DIR);
// 如果目录不存在,则创建
if (!uploadDir.exists()) {
uploadDir.mkdirs();
}
// 构建文件路径
Path filePath = Paths.get(uploadDir.getAbsolutePath(), fileName);
// 如果文件存在,则删除
if (filePath.toFile().exists()) {
filePath.toFile().delete();
}
// 将文件保存到指定路径
Files.copy(file.getInputStream(), filePath);
response.put("message", "视频上传成功!");
response.put("fileName", fileName);
response.put("filePath", filePath.toString());
return new ResponseEntity<>(response, HttpStatus.OK);
} catch (IOException e) {
e.printStackTrace();
response.put("message", "视频上传失败:" + e.getMessage());
return new ResponseEntity<>(response, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}