Node.js实现MP4转MP3直传Firebase及ENOENT报错修复
解决Node.js中MP4转MP3直接上传Firebase Storage(无需本地存储)的问题
原代码出现ENOENT错误的核心原因有两个:
ffmpeg.run()是异步操作,但未正确等待转换完成就执行readFile,此时文件尚未生成,导致读取失败。- 依赖本地文件作为中转,不符合“无需本地保存”的需求。
以下是修正后的实现方案,全程在内存中完成转换与上传,不落地本地文件:
import { initializeApp } from "firebase/app"; import { getStorage, ref, getDownloadURL, uploadBytesResumable } from "firebase/storage"; import serviceAccount from '../firebase/serviceAccountKey'; import { path as ffmpegPath } from '@ffmpeg-installer/ffmpeg'; import ffmpeg from 'fluent-ffmpeg'; import { PassThrough } from 'stream'; initializeApp(serviceAccount); ffmpeg.setFfmpegPath(ffmpegPath); // 将MP4转换为MP3并返回内存Buffer async function convertMP4ToMP3Buffer(inputPath: string): Promise<Buffer> { const passThroughStream = new PassThrough(); const ffmpegProcess = ffmpeg(inputPath) .audioCodec('libmp3lame') .format('mp3') .pipe(passThroughStream); return new Promise((resolve, reject) => { const chunks: Uint8Array[] = []; passThroughStream.on('data', (chunk) => chunks.push(chunk)); passThroughStream.on('end', () => resolve(Buffer.concat(chunks))); ffmpegProcess.on('error', (err) => reject(err)); }); } async function convertAndUpload(inputPath: string, firebaseStoragePath: string) { try { // 内存中完成格式转换 const mp3Buffer = await convertMP4ToMP3Buffer(inputPath); // 上传至Firebase Storage const storage = getStorage(); const storageRef = ref(storage, firebaseStoragePath); const metadata = { contentType: 'audio/mpeg' }; const uploadTask = uploadBytesResumable(storageRef, mp3Buffer, metadata); const snapshot = await uploadTask; const downloadURL = await getDownloadURL(snapshot.ref); console.log('转换并上传成功!'); console.log('下载链接:', downloadURL); } catch (error) { console.error('操作失败:', error); } } // 使用示例 const inputPath = './video.mp4'; const firebaseStoragePath = `audio/${Date.now()}.mp3`; // 建议用分类路径管理存储文件 convertAndUpload(inputPath, firebaseStoragePath);
关键改动说明:
- 内存流转换:用
PassThrough流接收ffmpeg的输出,将流数据拼接为Buffer,全程在内存中处理,彻底避免本地文件操作。 - 异步时序修复:用Promise包装ffmpeg的流事件,确保转换完成后再执行上传操作,解决原代码的异步竞态问题。
- 路径优化:将Firebase存储路径改为
audio/前缀的分类路径,更便于管理云端文件。
内容的提问来源于stack exchange,提问作者James
相关产品推荐
相关产品推荐

