react实现视频分片上传
实现视频分片上传的基本思路
视频分片上传的核心是将大文件切割为多个小块(chunk),分别上传到服务器,最后由服务器合并。这种方法能提高上传稳定性、支持断点续传,并减少网络波动的影响。
前端实现步骤
文件分片处理
使用File对象的slice方法对视频文件进行分片。分片大小通常根据网络状况调整(如1MB或5MB)。
const chunkSize = 1024 * 1024; // 1MB
const chunks = [];
let start = 0;
while (start < file.size) {
const chunk = file.slice(start, start + chunkSize);
chunks.push(chunk);
start += chunkSize;
}
上传分片
通过FormData将分片和元数据(如分片序号、文件哈希等)发送到服务器。建议使用并发控制(如Promise.allSettled)管理并行上传。
const uploadChunk = async (chunk, index, fileHash) => {
const formData = new FormData();
formData.append('chunk', chunk);
formData.append('index', index);
formData.append('hash', fileHash);
return axios.post('/upload/chunk', formData, {
headers: { 'Content-Type': 'multipart/form-data' }
});
};
文件哈希生成
为每个文件生成唯一标识(如MD5),用于服务器校验和合并分片。可使用spark-md5库计算文件哈希。
import SparkMD5 from 'spark-md5';
const calculateHash = (file) => {
return new Promise((resolve) => {
const spark = new SparkMD5.ArrayBuffer();
const reader = new FileReader();
reader.readAsArrayBuffer(file);
reader.onload = (e) => {
spark.append(e.target.result);
resolve(spark.end());
};
});
};
合并请求 全部分片上传完成后,发送合并请求通知服务器。
const mergeChunks = async (fileName, fileHash, chunkCount) => {
return axios.post('/upload/merge', {
fileName,
fileHash,
chunkCount
});
};
后端实现要点
分片接收接口 接收分片并临时存储,需校验分片序号和文件哈希。
app.post('/upload/chunk', (req, res) => {
const { index, hash } = req.body;
const chunk = req.files.chunk;
fs.writeFileSync(`temp/${hash}-${index}`, chunk.data);
res.send({ success: true });
});
合并分片接口 按序号读取所有分片,合并为完整文件。
app.post('/upload/merge', (req, res) => {
const { fileName, fileHash, chunkCount } = req.body;
const writeStream = fs.createWriteStream(`uploads/${fileName}`);
for (let i = 0; i < chunkCount; i++) {
const chunkPath = `temp/${fileHash}-${i}`;
writeStream.write(fs.readFileSync(chunkPath));
fs.unlinkSync(chunkPath); // 删除临时分片
}
writeStream.end();
res.send({ success: true });
});
优化与扩展
进度显示
通过axios的onUploadProgress回调更新上传进度。
{
onUploadProgress: progressEvent => {
const percent = Math.round((progressEvent.loaded / progressEvent.total) * 100);
console.log(`进度: ${percent}%`);
}
}
断点续传 服务器记录已上传分片,前端上传前先查询缺失的分片。
错误重试
为每个分片上传添加重试机制,例如使用retry-axios库。
注意事项
- 分片大小需权衡网络环境和服务器性能。
- 文件哈希建议使用Web Worker避免阻塞主线程。
- 临时分片需定期清理,防止磁盘空间占用。
通过以上方法,可实现稳定可靠的视频分片上传功能。实际开发中可根据需求调整分片策略和并发控制参数。







