You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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);

关键改动说明:

  1. 内存流转换:用PassThrough流接收ffmpeg的输出,将流数据拼接为Buffer,全程在内存中处理,彻底避免本地文件操作。
  2. 异步时序修复:用Promise包装ffmpeg的流事件,确保转换完成后再执行上传操作,解决原代码的异步竞态问题。
  3. 路径优化:将Firebase存储路径改为audio/前缀的分类路径,更便于管理云端文件。

内容的提问来源于stack exchange,提问作者James

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 11:52:31