视频的分片上传

news2025/3/31 7:21:28

分片上传需求分析:

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

要实现分片上传,需要对视频进行分割,分割成不同的大小进行上传,但是在上传的时候后台需要知道文件的唯一标识,进行识别,避免是重复数据上传,这个时候我们可以使用hash对内容进行生成唯一标识。

第一种方法实现:

html文件:

<input type="file" id="videoFile" accept="video/*" />

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,
    }),
});

第二种具体实现:

这个地方使用hash (spark-md5 第三方依赖)生成唯一标识,这个方式只对前端分片进行了封装,可以结合上面的代码传递给后端。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>视频分片上传</title>

</head>

<body>
    <input type="file" id="file"/>
    <script src="../node_modules/spark-md5/spark-md5.js"></script>

<script>
    const inp = document.querySelector('#file');
    inp.onchange = async () => {
        const file = inp.files[0];
        if(!file){
            alert("文件不存在!");
        }
       const chunks = createChunks(file,10*1024*1024);
        console.log(chunks);
        const result = await hash(chunks);
        console.log(result);
    }
	
	//生成hash
    function hash(chunks){
       return new Promise((resolve, reject) => {
           const spark = new SparkMD5();
           function _read(i){
               if(i>=chunks.length){
                   resolve(spark.end());
                   return;
               }
               const blob = chunks[i];
               const reader = new FileReader();
               reader.onload = function(e){
                   const bytes = e.target.result;//读取到的字节数组
                   spark.append(bytes);
                   _read(i+1)
               }
               reader.readAsText(blob);
           }
           _read(0);
       })
    }

    function createChunks(file,chunkSize){
        const result = [];
        for (let i = 0; i < file.size; i+=chunkSize) {
            result.push(file.slice(i,i+chunkSize));
        }
        return result;
    }
</script>

</body>
</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2304509.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Moonshot AI 新突破:MoBA 为大语言模型长文本处理提效论文速读

前言 在自然语言处理领域&#xff0c;随着大语言模型&#xff08;LLMs&#xff09;不断拓展其阅读、理解和生成文本的能力&#xff0c;如何高效处理长文本成为一项关键挑战。近日&#xff0c;Moonshot AI Research 联合清华大学、浙江大学的研究人员提出了一种创新方法 —— 混…

Deepseek首页实现 HTML

人工智能与未来&#xff1a;机遇与挑战 引言 在过去的几十年里&#xff0c;人工智能&#xff08;AI&#xff09;技术取得了突飞猛进的发展。从语音助手到自动驾驶汽车&#xff0c;AI 正在深刻地改变我们的生活方式、工作方式以及社会结构。然而&#xff0c;随着 AI 技术的普及…

VS2022配置FFMPEG库基础教程

1 简介 1.1 起源与发展历程 FFmpeg诞生于2000年&#xff0c;由法国工程师Fabrice Bellard主导开发&#xff0c;其名称源自"Fast Forward MPEG"&#xff0c;初期定位为多媒体编解码工具。2004年后由Michael Niedermayer接任维护&#xff0c;逐步发展成为包含音视频采…

kafka基本知识

什么是 Kafka&#xff1f; Apache Kafka 是一个开源的分布式流处理平台&#xff0c;最初由 LinkedIn 开发&#xff0c;后来成为 Apache 软件基金会的一部分。Kafka 主要用于构建实时数据管道和流处理应用程序。它能够高效地处理大量的数据流&#xff0c;广泛应用于日志收集、数…

类型系统下的语言分类与类型系统基础

类型系统是一种根据计算值的种类对程序语法进行分类的方式&#xff0c;目的是自动检查是否有可能导致错误的行为。 —Benjamin.C.Pierce&#xff0c;《类型与编程语言》&#xff08;2002&#xff09; 每当谈到编程语言时&#xff0c;人们常常会提到“静态类型”和“动态类型”。…

有没有使用wxpython开发的类似于visio或drawio的开源项目(AI生成)

有没有使用wxpython开发的类似于visio或drawio的开源项目 是的&#xff0c;有一些使用wxPython开发的类似于Microsoft Visio或draw.io&#xff08;现为diagrams.net&#xff09;的开源项目。wxPython 是一个跨平台的GUI工具包&#xff0c;它允许Python开发者创建桌面应用程序&…

【MySQL 一 数据库基础】深入解析 MySQL 的索引(3)

索引 索引操作 自动创建 当我们为一张表加主键约束(Primary key)&#xff0c;外键约束(Foreign Key)&#xff0c;唯一约束(Unique)时&#xff0c;MySQL会为对应的的列自动创建一个索引&#xff1b;如果表不指定任何约束时&#xff0c;MySQL会自动为每一列生成一个索引并用ROW_I…

【C++】优先级队列宝藏岛

> &#x1f343; 本系列为初阶C的内容&#xff0c;如果感兴趣&#xff0c;欢迎订阅&#x1f6a9; > &#x1f38a;个人主页:[小编的个人主页])小编的个人主页 > &#x1f380; &#x1f389;欢迎大家点赞&#x1f44d;收藏⭐文章 > ✌️ &#x1f91e; &#x1…

List 接口中的 sort 和 forEach 方法

List 接口中的 sort 和 forEach 方法是 Java 8 引入的两个非常实用的函数&#xff0c;分别用于 排序 和 遍历 列表中的元素。以下是它们的详细介绍和用法&#xff1a; sort 函数 功能 对列表中的元素进行排序。 默认使用自然顺序&#xff08;如数字从小到大&#xff0c;字符…

MusicGPT的本地化部署与远程调用:让你的Windows电脑成为AI音乐工作站

文章目录 前言1. 本地部署2. 使用方法介绍3. 内网穿透工具下载安装4. 配置公网地址5. 配置固定公网地址 前言 在如今快节奏的生活里&#xff0c;音乐不仅能够抚慰我们的心灵&#xff0c;还能激发无限创意。想象一下&#xff0c;在忙碌的工作间隙或闲暇时光中&#xff0c;只需输…

Unity通过Vosk实现离线语音识别方法

标注&#xff1a;deepseek直接生成&#xff0c;待验证 在Unity中实现离线语音识别可以通过集成第三方语音识别库来实现。以下是一个使用 Unity 和 Vosk&#xff08;一个开源的离线语音识别库&#xff09;的简单示例。 准备工作 Vosk&#xff1a;一个开源的离线语音识别库&am…

智能优化算法:莲花算法(Lotus flower algorithm,LFA)介绍,提供MATLAB代码

一、 莲花算法 1.1 算法原理 莲花算法&#xff08;Lotus flower algorithm&#xff0c;LFA&#xff09;是一种受自然启发的优化算法&#xff0c;其灵感来源于莲花的自清洁特性和授粉过程。莲花的自清洁特性&#xff0c;即所谓的“莲花效应”&#xff0c;是由其叶片表面的微纳…

企业数据集成:实现高效调拨出库自动化

调拨出库对接调出单-v&#xff1a;旺店通企业奇门数据集成到用友BIP 在企业信息化管理中&#xff0c;数据的高效流转和准确对接是实现业务流程自动化的关键。本文将分享一个实际案例&#xff0c;展示如何通过轻易云数据集成平台&#xff0c;将旺店通企业奇门的数据无缝集成到用…

数据库管理-第295期 IT架构与爆炸半径(20250221)

数据库管理295期 2025-02-21 数据库管理-第295期 架构与爆炸半径&#xff08;20250221&#xff09;1 术语新解2 硬件&#xff1a;存储VS本地盘3 数据库3.1 多模VS专用3.2 集中式VS分布式 4 公有云VS非公有云总结 数据库管理-第295期 架构与爆炸半径&#xff08;20250221&#x…

基于WOA鲸鱼优化的BiLSTM双向长短期记忆网络序列预测算法matlab仿真,对比BiLSTM和LSTM

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 (完整程序运行后无水印) 2.算法运行软件版本 matlab2022a/matlab2024b 3.部分核心程序 &#xff08;完整版代码包含详细中文注释和操作步骤视频…

DeepSeek私有化专家 | 云轴科技ZStack入选IDC中国生成式AI市场概览

DeepSeek 火爆全球AI生态圈&#xff0c;并引发企业用户大量私有化部署需求。 国际数据公司IDC近日发文《DeepSeek爆火的背后&#xff0c;大模型/生成式AI市场生态潜在影响引人关注》&#xff0c;认为中国市场DeepSeekAI模型的推出在大模型/生成式AI市场上引起了轰动&#xff0c…

npm在install时提示要安装python问题处理

使用npm\yarn\pnpm下载以来的时候&#xff0c;一直提示python异常&#xff0c;有的项目安装了python之后&#xff0c;下载依赖还是异常 而且旧版本项目使用python2,新的使用Python3…很烦 解决方案1&#xff1a;cnpm 安装教程&#xff1a; npm安装cnpm&#xff0c;解决node12\…

如何将MySQL数据库迁移至阿里云

将 MySQL 数据库迁移至阿里云可以通过几种不同的方法&#xff0c;具体选择哪种方式取决于你的数据库大小、数据复杂性以及对迁移速度的需求。阿里云提供了多种迁移工具和服务&#xff0c;本文将为你介绍几种常见的方法。 方法一&#xff1a;使用 阿里云数据库迁移服务 (DTS) 阿…

CSS基础(盒子模型的组成、内容溢出、隐藏元素的方式、样式的继承、元素的默认样式、布局技巧、元素之间的空白问题、行内块元素的幽灵空白问题)

文章目录 1. 盒子模型的组成1.1 内容区1.2 默认宽度1.3 内边距1.3.1 内边距属性1.3.2 复合属性1.3.3 单位1.3.4 注意事项 1.4 边框1.4.1 边框属性1.4.2 复合属性1.4.3 单方向边框1.4.4 边框样式1.4.5 注意事项 1.5 外边距1.5.1 外边距属性1.5.2 复合属性1.5.3 注意事项 1.6 外边…

【第二节】C++设计模式(创建型模式)-抽象工厂模式

目录 引言 一、抽象工厂模式概述 二、抽象工厂模式的应用 三、抽象工厂模式的适用场景 四、抽象工厂模式的优缺点 五、总结 引言 抽象工厂设计模式是一种创建型设计模式&#xff0c;旨在解决一系列相互依赖对象的创建问题。它与工厂方法模式密切相关&#xff0c;但在应用…