能否将文件缓冲区/流作为fluent-ffmpeg输入?寻求高效视频处理方案
解决方案:无需本地文件的fluent-ffmpeg视频压缩与上传
核心解决思路
fluent-ffmpeg支持直接输入可读流,并非只能传入文件路径。你可以把API接收的file.buffer转换为Readable流,直接作为ffmpeg的输入,同时将ffmpeg的输出流直接管道到Firebase的写入流,全程无需写入本地临时文件,彻底省去磁盘IO开销。
优化后的代码实现
const { Readable } = require('stream'); const ffmpeg = require('fluent-ffmpeg'); // 将Buffer转换为可读流 const inputStream = Readable.from(file.buffer); ffmpeg() // 传入可读流作为ffmpeg输入 .input(inputStream) .format('mp4') .size('50%') // 把ffmpeg输出直接管道到Firebase写入流,无需本地存储 .pipe(bucket.file(`video/${uniqueId}`).createWriteStream(), { end: true }) .on('end', async () => { // 获取处理后文件的签名URL const resizedFile = bucket.file(`video/${uniqueId}`); const url = await resizedFile.getSignedUrl({ action: 'read', expires: '03-17-2025' }); console.log('Resized file uploaded successfully. URL:', url); }) .on('error', (err) => { console.log('An error occurred:', err.message); });
关键细节说明
Readable.from(file.buffer):将API接收的Buffer转换为Node.js可读流,这是实现无文件输入的核心步骤。.pipe(outputStream, { end: true }):配置ffmpeg处理完成后自动关闭输出流,确保Firebase写入流正常结束。- 全程无磁盘IO:避免了临时文件的写入与删除操作,不仅提升处理效率,还消除了临时文件残留的风险。
替代方案(若fluent-ffmpeg流处理遇兼容问题)
如果流处理存在兼容性问题,可直接通过child_process调用ffmpeg命令行实现流处理,逻辑更底层但同样高效:
const { spawn } = require('child_process'); const { Readable } = require('stream'); const inputStream = Readable.from(file.buffer); const outputStream = bucket.file(`video/${uniqueId}`).createWriteStream(); // 直接调用ffmpeg命令,从stdin读入、stdout输出 const ffmpegProcess = spawn('ffmpeg', [ '-i', '-', '-vf', 'scale=iw/2:ih/2', // 等价于size('50%')的视频缩放逻辑 '-f', 'mp4', '-' ]); inputStream.pipe(ffmpegProcess.stdin); ffmpegProcess.stdout.pipe(outputStream); // 等待上传完成 await new Promise((resolve, reject) => { outputStream.on('finish', resolve); ffmpegProcess.on('error', reject); }); // 后续获取签名URL逻辑同前
内容的提问来源于stack exchange,提问作者Moath Thawahreh
相关产品推荐
相关产品推荐

