针对上传带进度条视频并提取缩略图的需求,可以通过以下步骤来实现:
1. 前端页面准备
首先,我们需要在前端页面中添加一个用于上传视频文件的表单,这个表单需要设置 enctype="multipart/form-data"
属性以支持文件上传。此外,还需要添加一个用于显示上传进度的进度条,通过实时更新进度条的值来展示上传进度。
以下是一个简单的示例:
<form id="upload-form" enctype="multipart/form-data">
<input type="file" name="video" />
<button type="submit">上传</button>
<div>
<progress id="upload-progress" max="100" value="0"></progress>
<span id="progress-label">0%</span>
</div>
</form>
2. Ajax 异步上传视频
为了实现异步上传视频,我们可以使用 jQuery 的 $.ajax()
方法。在调用 $.ajax()
方法时,我们需要指定以下参数:
- url
:服务器端处理上传请求的 URL;
- type
:请求类型,通常为 POST
;
- data
:上传的 FormData 对象,其中包含视频文件;
- processData
:设置为 false
,确保 jQuery 不会将 FormData 对象处理成查询字符串;
- contentType
:设置为 false
,确保 jQuery 不会设置请求头中的 Content-Type;
- xhr
:一个用于创建 XMLHttpRequest 对象的函数,我们可以使用此选项来绑定上传进度事件和完成事件。
以下是一个示例:
$('#upload-form').on('submit', function(e) {
e.preventDefault();
var formData = new FormData(this);
$.ajax({
url: '/upload',
type: 'POST',
data: formData,
processData: false,
contentType: false,
xhr: function() {
var xhr = $.ajaxSettings.xhr();
xhr.upload.onprogress = function(e) {
if (e.lengthComputable) {
var percent = e.loaded / e.total * 100;
$('#upload-progress').val(percent);
$('#progress-label').text(Math.round(percent) + '%');
}
};
return xhr;
}
});
});
在上传文件的过程中,我们会不断地收到上传进度信息,通过监听 xhr.upload.onprogress
事件即可实时更新进度条的值并显示进度百分比。
3. 服务器端处理上传请求
在服务端,我们需要先接收用户上传的视频文件,然后使用 FFmpeg 工具提取视频缩略图。为了完成这个过程,我们需要先安装 FFmpeg 工具,并在服务端调用 FFmpeg 的命令行工具。
以下是一个使用 Node.js 和 Express 框架的示例:
const express = require('express');
const multer = require('multer');
const spawn = require('child_process').spawn;
const app = express();
// 配置 multer 中间件
const upload = multer({ dest: 'uploads/' });
// 处理上传请求
app.post('/upload', upload.single('video'), (req, res) => {
const { path: videoPath } = req.file;
const thumbnailPath = `thumbnails/${Date.now()}.jpg`;
const ffmpeg = spawn('ffmpeg', [
'-i', videoPath,
'-ss', '00:00:01.000',
'-vframes', '1',
thumbnailPath
]);
ffmpeg.on('close', () => {
res.json({ thumbnailUrl: thumbnailPath });
});
});
在上述示例中,我们使用 multer 中间件来处理上传请求,通过调用 upload.single('video')
方法指定上传的文件字段名为 video
,接收上传的视频文件并将其保存到 uploads/
目录下。
接着,我们使用 child_process.spawn()
方法来调用 FFmpeg 命令行工具,通过传入命令行参数来设置缩略图的生成规则。在命令执行完成后,我们会收到 close
事件,此时我们可以返回包含缩略图 URL 的 JSON 响应。
4. 显示视频缩略图
最后,我们需要在前端页面中通过 <img>
元素来显示服务器返回的缩略图 URL,以便用户可以预览上传的视频。
以下是一个简单的示例:
$.ajax({
url: '/upload',
type: 'POST',
data: formData,
processData: false,
contentType: false,
xhr: function() {
// ...
},
success: function(res) {
var thumbnailUrl = res.thumbnailUrl;
$('<img>').attr('src', thumbnailUrl).appendTo('body');
}
});
在上述示例中,我们通过调用 $.ajax()
方法来上传视频文件并获取服务器返回的 JSON 响应。在成功处理响应后,我们可以通过创建一个 <img>
元素来显示缩略图。
示例1
下面是一个基于 Node.js 和 Express 框架的完整示例,用于演示如何上传带进度条的视频并提取缩略图:
const express = require('express');
const multer = require('multer');
const spawn = require('child_process').spawn;
const app = express();
// 配置 multer 中间件
const upload = multer({ dest: 'uploads/' });
// 处理上传请求
app.post('/upload', upload.single('video'), (req, res) => {
const { path: videoPath } = req.file;
const thumbnailPath = `thumbnails/${Date.now()}.jpg`;
const ffmpeg = spawn('ffmpeg', [
'-i', videoPath,
'-ss', '00:00:01.000',
'-vframes', '1',
thumbnailPath
]);
ffmpeg.on('close', () => {
res.json({ thumbnailUrl: thumbnailPath });
});
});
// 监听本地端口
app.listen(3000, () => {
console.log('Server started on http://localhost:3000');
});
<!DOCTYPE html>
<html>
<head>
<title>Ajax 异步上传带进度条视频并提取缩略图</title>
</head>
<body>
<form id="upload-form" enctype="multipart/form-data">
<input type="file" name="video" />
<button type="submit">上传</button>
<div>
<progress id="upload-progress" max="100" value="0"></progress>
<span id="progress-label">0%</span>
</div>
</form>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script>
$('#upload-form').on('submit', function(e) {
e.preventDefault();
var formData = new FormData(this);
$.ajax({
url: '/upload',
type: 'POST',
data: formData,
processData: false,
contentType: false,
xhr: function() {
var xhr = $.ajaxSettings.xhr();
xhr.upload.onprogress = function(e) {
if (e.lengthComputable) {
var percent = e.loaded / e.total * 100;
$('#upload-progress').val(percent);
$('#progress-label').text(Math.round(percent) + '%');
}
};
return xhr;
},
success: function(res) {
var thumbnailUrl = res.thumbnailUrl;
$('<img>').attr('src', thumbnailUrl).appendTo('body');
}
});
});
</script>
</body>
</html>
示例2
以下是一段完整的使用 Vue.js 实现上传视频并提取缩略图的代码:
<template>
<div>
<h1>上传带进度条视频并提取缩略图</h1>
<form @submit.prevent="uploadVideo">
<input type="file" @change="onFileChange" />
<button :disabled="!file">上传</button>
<div>
<progress :value="progress" max="100"></progress>
<span>{{ Math.round(progress) }}%</span>
</div>
</form>
<div v-if="thumbnailUrl">
<img :src="thumbnailUrl" />
</div>
</div>
</template>
<script>
import axios from 'axios';
export default {
data() {
return {
file: null,
progress: 0,
thumbnailUrl: null
};
},
methods: {
onFileChange(e) {
this.file = e.target.files[0];
},
uploadVideo() {
const formData = new FormData();
formData.append('video', this.file);
axios({
method: 'POST',
url: '/upload',
data: formData,
onUploadProgress: (e) => {
if (e.lengthComputable) {
this.progress = e.loaded / e.total * 100;
}
}
}).then((response) => {
this.thumbnailUrl = response.data.thumbnailUrl;
});
}
}
};
</script>
在上述示例中,我们通过一个 Vue.js 组件来实现上传带进度条的视频并提取缩略图的功能。通过监听 @change
事件来监听用户选择了哪个视频文件,绑定 @submit.prevent
事件处理函数用于上传视频,并在用户选择视频文件后启用上传按钮。
通过调用 axios()
方法来实现异步上传视频。在调用 axios()
方法时,我们需要指定以下参数:
method
:请求类型,通常为POST
;url
:服务器端处理上传请求的 URL;data
:上传的 FormData 对象,其中包含视频文件;onUploadProgress
:用于处理上传进度的函数,Vue.js 模板中将进度条的值绑定到了progress
变量上。
在 API 返回 JSON 响应时,我们将响应中包含的缩略图 URL 绑定到了 Vue.js 模板中的 thumbnailUrl
变量上,将显示缩略图的 <img>
元素展示给用户。
完整的 Node.js + Express 服务端代码与这个示例的前端代码不变。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:ajax 异步上传带进度条视频并提取缩略图 - Python技术站