当前位置: 首页 > news >正文

特色专业建设展示网站北京seo培训

特色专业建设展示网站,北京seo培训,设计师网站大全,wordpress帝国哪个安全前言最近接到一个业务需求:录音文件上传时因为文件过大(超过100M)有报错,(服务器端对单次文件的上传,有大小限制)。经过讨论,最后决定使用‘分片’解决问题。我做了一个小案例&#…

前言

最近接到一个业务需求:录音文件上传时因为文件过大(超过100M)有报错,

(服务器端对单次文件的上传,有大小限制)。

经过讨论,最后决定使用‘分片’解决问题。

我做了一个小案例(非业务代码),用HTML代码实现前端页面用express实现后端服务

一、分片上传的核心原理​

分片上传是将大文件分割成多个小片段(分片),逐个上传到服务器,最后在服务器端合并所有分片形成完整文件的技术。这种方式的优势在于:​

  • 避免单次上传大文件导致的超时问题​
  • 支持断点续传,某分片失败只需重传该分片​
  • 减轻服务器单次处理压力,提高系统稳定性​

对于录音文件来说,由于可能包含长时间的音频数据(尤其是高清录音),文件体积往往较大,非常适合采用分片上传方案。

二、前端实现核心逻辑​

前端主要负责录音、文件分片和上传控制三个部分。

1. 录音功能实现​

使用浏览器原生的MediaRecorderAPI 实现录音功能:

// 开始录音
startRecordBtn.addEventListener('click', async () => {const stream = await navigator.mediaDevices.getUserMedia({ audio: true });mediaRecorder = new MediaRecorder(stream);audioChunks = [];mediaRecorder.ondataavailable = (event) => {audioChunks.push(event.data);};mediaRecorder.start();// 更新UI状态...
});// 停止录音
stopRecordBtn.addEventListener('click', () => {mediaRecorder.stop();mediaRecorder.stream.getTracks().forEach(track => track.stop());mediaRecorder.onstop = () => {audioBlob = new Blob(audioChunks, { type: 'audio/webm' });audioUrl = URL.createObjectURL(audioBlob);// 显示上传区域...};
});

2. 分片上传核心实现​

创建AudioChunkUploader类处理分片逻辑:

class AudioChunkUploader {constructor(options) {this.options = {chunkSize: 5 * 1024 * 1024, // 5MB每片uploadUrl: 'http://localhost:3000/upload/chunk',mergeUrl: 'http://localhost:3000/upload/merge',...options};this.state = {totalChunks: 0,uploadedChunks: 0,fileMd5: '', // 文件唯一标识isPaused: false};}// 计算文件MD5(用于标识同一文件)async _calculateFileMd5() {return new Promise((resolve) => {const fileReader = new FileReader();const spark = new SparkMD5.ArrayBuffer();fileReader.onload = (e) => {spark.append(e.target.result);this.state.fileMd5 = spark.end();resolve();};fileReader.readAsArrayBuffer(this.options.file);});}// 上传单个分片async _uploadSingleChunk(chunkIndex) {const start = chunkIndex * this.options.chunkSize;const end = Math.min(start + this.options.chunkSize, this.state.fileSize);const chunk = this.options.file.slice(start, end);const formData = new FormData();formData.append('chunk', chunkIndex);formData.append('chunks', this.state.totalChunks);formData.append('fileMd5', this.state.fileMd5);formData.append('file', chunk);return fetch(this.options.uploadUrl, {method: 'POST',body: formData}).then(response => response.json());}// 上传所有分片async _uploadChunks() {for (let i = 0; i < this.state.totalChunks; i++) {if (this.state.isPaused) {// 等待恢复上传await new Promise(resolve => {const check = setInterval(() => {if (!this.state.isPaused) {clearInterval(check);resolve();}}, 100);});}await this._uploadSingleChunk(i);this.state.uploadedChunks = i + 1;// 触发进度更新...}}// 通知服务器合并分片async _mergeChunks() {return fetch(this.options.mergeUrl, {method: 'POST',headers: { 'Content-Type': 'application/json' },body: JSON.stringify({fileMd5: this.state.fileMd5,fileName: this.options.fileName,chunks: this.state.totalChunks})}).then(response => response.json());}
}

3. 播放控制功能​

实现带暂停 / 继续功能的音频播放:

let audioPlayer = null;
let lastPlayTime = 0;// 播放录音
playRecordBtn.addEventListener('click', () => {if (!audioPlayer) {audioPlayer = new Audio(audioUrl);if (lastPlayTime > 0) {audioPlayer.currentTime = lastPlayTime;}} else {audioPlayer.currentTime = lastPlayTime;}audioPlayer.play();// 更新按钮状态...
});// 暂停播放
stopPlayBtn.addEventListener('click', () => {lastPlayTime = audioPlayer.currentTime;audioPlayer.pause();// 更新按钮状态...
});

三、后端实现核心逻辑​

Express 后端负责接收分片、临时存储和合并文件:​

1. 分片接收接口

const multer = require('multer');
const upload = multer({ storage: multer.diskStorage({destination: (req, file, cb) => {// 为每个文件创建独立的临时目录const chunkDir = path.join(tempDir, req.body.fileMd5);if (!fs.existsSync(chunkDir)) {fs.mkdirSync(chunkDir, { recursive: true });}cb(null, chunkDir);},filename: (req, file, cb) => {// 用分片索引作为文件名cb(null, req.body.chunk);}})
});// 处理分片上传
app.post('/upload/chunk', upload.single('file'), (req, res) => {res.json({success: true,message: `分片 ${req.body.chunk} 上传成功`});
});

2. 分片合并接口

app.post('/upload/merge', (req, res) => {const { fileMd5, fileName, chunks } = req.body;const chunkDir = path.join(tempDir, fileMd5);const destPath = path.join(uploadDir, fileName);// 检查所有分片是否上传完成if (fs.readdirSync(chunkDir).length !== parseInt(chunks)) {return res.status(400).json({success: false,message: '分片不完整'});}// 合并分片const writeStream = fs.createWriteStream(destPath);let chunkIndex = 0;const mergeNextChunk = () => {const chunkPath = path.join(chunkDir, chunkIndex.toString());if (fs.existsSync(chunkPath)) {const readStream = fs.createReadStream(chunkPath);readStream.pipe(writeStream, { end: false });readStream.on('end', () => {fs.unlinkSync(chunkPath); // 删除已合并的分片chunkIndex++;mergeNextChunk();});} else {writeStream.end(); // 所有分片合并完成}};mergeNextChunk();writeStream.on('finish', () => {fs.rmdirSync(chunkDir, { recursive: true }); // 清理临时目录res.json({success: true,fileName,filePath: destPath});});
});

四、效果展示

可以在设定好存放上传文件的文件夹下看到上传的录音文件

五、总结与拓展​

录音文件分片上传方案的核心在于:​

  • 前端将录音文件分割成固定大小的分片,计算文件唯一标识​
  • 逐个上传分片,支持暂停 / 继续功能​
  • 后端接收分片并临时存储​
  • 所有分片上传完成后,后端按顺序合并成完整文件​

方案可以进一步优化:​

  • 添加断点续传功能,上传前先查询已上传的分片​
  • 实现分片上传的并发控制,提高上传速度​
  • 增加文件校验机制,确保上传文件的完整性​
  • 对大文件 MD5 计算进行优化,避免页面卡顿​

分片上传技术不仅适用于录音文件,也可推广到视频、文档等各种大文件上传场景,是 Web 开发中处理大文件的重要方案。

代码获取,后台联系。

http://www.dtcms.com/a/423128.html

相关文章:

  • 网络原理-HTTP补充1
  • 做外贸相关的网站全面的vi设计公司
  • 如何构建高效 AI 智能体
  • 9.25训练赛+Codeforces1054 (Div. 3)
  • 老Java项目访问提示orcale 19c ORA-01017: 用户名/口令无效; 登录被拒绝
  • 目标检测:yolov7算法在RK3588上部署
  • Maya Python: 安装pymel
  • 全景网站开发待遇南宁logo设计公司
  • 北京工商局网站怎么做增资网易代理暴雪
  • 制造行业订单全生命周期管理数仓项目实战
  • 《深度学习入门:基于Python的理论与实现》第7章 卷积神经网络笔记
  • 网络游戏编程 - Socket 技术以及应用 - 上 -《了解游戏网络基础知识》
  • 珠海建网站的网络公司网站名称格式
  • 舆情观察类文章写作指南与新浪舆情通应用
  • C语言——深入理解函数声明定义和调用访问
  • 网站开发大约多少钱制作一个网站的步骤是什么
  • RabbitMQ (一)简单模式
  • 阿里巴巴 Java 开发手册 v1.2.0
  • Leetcode+Java+单调栈
  • Word和WPS文字如何从特定的页开始编号(页码)?
  • EDSR模型
  • thinkphp做中英文网站网站跟app区别
  • 6. 数据库设计基础知识
  • 【nginx平滑升级演示】
  • 桥梁缺陷检测数据集:腐蚀、剥落、渗透等5类,3k+图像,yolo标注
  • 上交提出单图生成3D场景方法SceneGen:单图输入,多资源输出,3D 合成性能飙升的“秘密武器”!
  • 百度验证网站济南网络科技公司
  • NO5.硼:火箭专家
  • 细化处理refinement process
  • 第四部分:VTK常用类详解(第120章 vtkWarpTo变形到类)