如何在不耗尽内存的情况下上传视频至Cloudflare Stream
解决Cloudflare Stream上传内存耗尽问题
你的问题核心在于multer会将整个文件加载到内存(或本地磁盘)后再处理,导致大文件占用过多内存。用busboy替换multer,结合tus-js做流式分块上传,就能实现边读取边上传,内存占用始终保持在分块大小(8MB)左右。
步骤1:安装依赖
先安装busboy(替代multer做流式解析):
npm install busboy
步骤2:替换路由处理逻辑
直接用busboy解析请求中的文件流,传给tus-js进行分块上传,全程不缓存整个文件:
const express = require('express'); const Busboy = require('busboy'); const tus = require('tus-js-client'); const app = express(); // 替换原multer的上传路由 app.post('/upload', (req, res) => { const busboy = new Busboy({ headers: req.headers }); // 监听文件字段 busboy.on('file', (fieldname, fileStream, filename) => { // 初始化tus上传配置 const upload = new tus.Upload(fileStream, { endpoint: 'https://api.cloudflare.com/client/v4/accounts/[你的Cloudflare账户ID]/stream', headers: { 'Authorization': 'Bearer [你的Cloudflare API令牌]', 'Tus-Resumable': '1.0.0', // 传递文件元数据(base64编码文件名) 'Upload-Metadata': `filename ${Buffer.from(filename).toString('base64')}` }, chunkSize: 8 * 1024 * 1024, // 8MB分块 onError: (err) => { console.error('上传失败:', err); res.status(500).send('上传失败'); }, onProgress: (bytesUploaded, bytesTotal) => { const progress = ((bytesUploaded / bytesTotal) * 100).toFixed(2); console.log(`上传进度: ${progress}%`); }, onSuccess: () => { console.log('文件上传完成'); res.status(200).send('上传成功'); } }); // 启动上传 upload.start(); }); // 监听请求解析完成 busboy.on('finish', () => { console.log('请求解析完毕'); }); // 将请求流导入busboy进行解析 req.pipe(busboy); }); app.listen(3000, () => { console.log('服务启动在3000端口'); });
关键注意事项
- 替换代码中的
[你的Cloudflare账户ID]和[你的Cloudflare API令牌]为实际值,确保令牌拥有Cloudflare Stream的上传权限。 Upload-Length(文件总大小)如果客户端请求头中没有携带,可以通过req.headers['content-length']获取,部分场景下busboy也能从文件流中获取准确长度。- 这种流式处理方式下,内存占用仅为分块大小(8MB),无论文件多大都不会出现内存耗尽问题。
- 如果需要处理多个文件,
busboy.on('file')会为每个文件触发一次,分别初始化tus上传即可。
内容的提问来源于stack exchange,提问作者jhnxx
相关产品推荐
相关产品推荐

