Node.js中用fluent-ffmpeg结合Buffer生成视频缩略图(无需文件系统)
无本地文件依赖的视频缩略图生成方案
你可以通过内存流全程处理视频和缩略图,完全避开本地文件系统,核心思路是利用stream模块将multer内存中的buffer转为可读流传给ffmpeg,同时将缩略图输出导向内存流,再直接上传到Azure Blob Storage。
具体实现步骤
- 用
stream.Readable把multer存储的视频buffer转为可读流,作为ffmpeg的输入 - 配置ffmpeg生成缩略图,将输出导向
stream.PassThrough(内存可写流) - 分别将原视频buffer和缩略图流上传至Azure Blob Storage
代码示例
const stream = require('stream'); const ffmpeg = require('fluent-ffmpeg'); const { BlobServiceClient } = require('@azure/storage-blob'); // 初始化Azure Blob客户端 const blobServiceClient = BlobServiceClient.fromConnectionString(process.env.AZURE_STORAGE_CONNECTION_STRING); const containerClient = blobServiceClient.getContainerClient('your-container-name'); async function handleVideoUpload(req, res) { try { // 将视频buffer转为可读流 const videoStream = new stream.Readable(); videoStream.push(req.file.buffer); videoStream.push(null); // 标记流结束 // 用ffmpeg生成缩略图,输出到内存流 const thumbnailStream = new stream.PassThrough(); await new Promise((resolve, reject) => { ffmpeg(videoStream) .on('end', resolve) .on('error', reject) .screenshots({ timestamps: ['00:00:02.000'], filename: 'thumbnail.png', // 直接输出到PassThrough流,不写入本地文件 stream: thumbnailStream }); }); // 上传原视频到Azure Blob const videoBlobClient = containerClient.getBlockBlobClient(`videos/${req.file.originalname}`); await videoBlobClient.uploadData(req.file.buffer); // 上传缩略图到Azure Blob const thumbnailBlobClient = containerClient.getBlockBlobClient(`thumbnails/${req.file.originalname.replace(/\.[^/.]+$/, '')}_thumbnail.png`); thumbnailStream.seek(0); // 重置流指针到开头 await thumbnailBlobClient.uploadStream(thumbnailStream); res.status(200).json({ message: '视频和缩略图上传成功' }); } catch (error) { console.error(error); res.status(500).json({ error: '处理失败' }); } }
关键细节说明
stream.Readable用于把静态buffer转为ffmpeg可识别的可读流,必须用push(null)标记流结束,否则ffmpeg会一直等待输入- ffmpeg的
screenshots配置中指定stream参数,就能将缩略图输出到内存流,完全跳过本地文件写入 - Azure Blob的
uploadStream方法可直接接收内存流,无需额外转换 - 如需调整缩略图尺寸、格式,可在
screenshots中添加size: '320x240'等参数
内容的提问来源于stack exchange,提问作者Nico Schuck
相关产品推荐
相关产品推荐

