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

视频的分片上传

分片上传需求分析:

项目中很多地方需要上传视频,如果视频很大,上传到服务器需要很多时间 ,这个时候体验就会很差。所以需要前端实现分片上传的功能。

代码分析:

html文件:

<input type="file" id="videoFile" accept="video/*" />
<button id="uploadBtn">上传</button>

javascript 文件:

document.getElementById('uploadBtn').addEventListener('click', async () => {
    const fileInput = document.getElementById('videoFile');
    const file = fileInput.files[0];
    
    if (!file) {
        alert('请选择一个文件');
        return;
    }

    const chunkSize = 5 * 1024 * 1024; // 每个分片的大小,例如 5MB
    //分析存在几个分片,假如文件是10M ,那就是两个分片。
    const totalChunks = Math.ceil(file.size / chunkSize);
    //唯一id,这个是必须的,用来区分不同的分片
    const fileId = Date.now().toString(); // 生成一个唯一的文件ID
	
	//遍历分片,去分别上传到服务器
    for (let chunkNumber = 0; chunkNumber < totalChunks; chunkNumber++) {
        const start = chunkNumber * chunkSize;
        const end = Math.min(start + chunkSize, file.size);
        const chunk = file.slice(start, end);
		
		//处理数据给后端需要的格式
        const formData = new FormData();
        formData.append('file', chunk);
        formData.append('fileId', fileId);
        formData.append('chunkNumber', chunkNumber);
        formData.append('totalChunks', totalChunks);
        formData.append('fileName', file.name);

        try {
            const response = await fetch('/upload', {
                method: 'POST',
                body: formData,
            });

            if (!response.ok) {
                throw new Error('上传失败');
            }

            console.log(`分片 ${chunkNumber + 1}/${totalChunks} 上传成功`);
        } catch (error) {
            console.error('上传出错:', error);
            break;
        }
    }

    console.log('所有分片上传完成');
});

分析一下上面的formData:
在这里插入图片描述
更多的数据格式参考文章:点击跳转

服务端处理:

服务器端需要处理每个分片的上传请求,并在所有分片上传完成后将其合并。

接受分片:

服务器端可以使用类似以下的代码来接收分片:

app.post('/upload', (req, res) => {
    const { fileId, chunkNumber, totalChunks, fileName } = req.body;
    const chunk = req.files.file;

    // 保存分片到临时目录
    const chunkPath = `./temp/${fileId}-${chunkNumber}`;
    fs.writeFileSync(chunkPath, chunk.data);

    res.send({ success: true });
});

合并分片:

当所有分片上传完成后,服务器端可以将它们合并成一个完整的文件:

app.post('/merge', (req, res) => {
    const { fileId, totalChunks, fileName } = req.body;

    const outputPath = `./uploads/${fileName}`;
    const writeStream = fs.createWriteStream(outputPath);

    for (let i = 0; i < totalChunks; i++) {
        const chunkPath = `./temp/${fileId}-${i}`;
        const chunk = fs.readFileSync(chunkPath);
        writeStream.write(chunk);
        fs.unlinkSync(chunkPath); // 删除临时分片
    }

    writeStream.end();
    res.send({ success: true });
});

前端通知服务器合并分片

在所有分片上传完成后,前端可以发送一个请求通知服务器合并分片:

fetch('/merge', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
    },
    body: JSON.stringify({
        fileId: fileId,
        totalChunks: totalChunks,
        fileName: file.name,
    }),
});

http://www.kler.cn/a/553374.html

相关文章:

  • Markdown 常用语法及示例
  • 【C++】类与对象全面剖析(尾卷)(构造深化、类型转换、static成员特性及内部类与匿名对象)
  • 网页制作04-html,css,javascript初认识のhtml如何使用列表
  • MySQL + Python 开发之旅:深入数据库操作与数据交互
  • 如何写出优秀的测试用例?
  • Linux vi模式:从入门到精通
  • 【第一节】C++设计模式(创建型模式)-工厂模式
  • 多模态机器学习火热idea汇总!
  • MYSQL总结(2)
  • 鸿蒙5.0实战案例:图片选择和下载保存案例
  • 卷积神经网络之AlexNet经典神经网络,实现手写数字0~9识别
  • 2025软件测试就业形势剖析:机遇与挑战交织
  • 换服务器需要做的工作(记录一下)
  • [生活杂项][运动教程]自由泳
  • 语音识别中的MFCC特征提取:时频分析如何转化为机器可理解的声学参数?(附完整代码实现)
  • Deepseekv3原理架构中的数学公式,通过高度概括实现快速入门
  • VS Code 如何搭建C/C++开发环境
  • CAN总线常见的错误帧及产生原因
  • 目标检测之YOLO论文简读
  • spring boot知识点3