Node.js从Firebase取WebM文件用Whisper转写:Blob转File遇阻
解决Node.js中Blob转File适配OpenAI Whisper转写的问题
核心问题在于:Node.js环境没有浏览器原生的File构造函数,而OpenAI的Node.js SDK实际上不需要严格传入浏览器式的File对象——它支持传入可读流、文件路径字符串或Buffer来替代。以下是几种可行的解决方案:
方案一:直接将Blob转为可读流传入SDK
无需构造File,利用Blob.stream()获取可读流,直接传递给createTranscription:
import axios from 'axios'; import { OpenAI } from 'openai'; const openai = new OpenAI({ apiKey: '你的API密钥' }); export const getFile = async(publicUrl: string) => { const response = await axios.get(publicUrl, { responseType: 'blob' }); return response.data; }; export const transcribeWebm = async(publicUrl: string) => { const blob = await getFile(publicUrl); const transcription = await openai.audio.transcriptions.create({ file: blob.stream(), // 传入Blob的可读流 model: 'whisper-1', filename: 'audio.webm', // 指定文件名,帮助识别格式 contentType: 'video/webm' }); return transcription; };
方案二:将Blob保存为临时文件后传入
把Blob写入本地临时文件,直接给SDK传文件路径或文件流,适合大文件场景:
import axios from 'axios'; import { OpenAI } from 'openai'; import fs from 'fs/promises'; import os from 'os'; import path from 'path'; const openai = new OpenAI({ apiKey: '你的API密钥' }); export const getFile = async(publicUrl: string) => { const response = await axios.get(publicUrl, { responseType: 'arraybuffer' }); return response.data; }; export const transcribeWebm = async(publicUrl: string) => { const arrayBuffer = await getFile(publicUrl); // 创建临时文件路径 const tempDir = os.tmpdir(); const tempFilePath = path.join(tempDir, 'temp-audio.webm'); // 写入临时文件 await fs.writeFile(tempFilePath, Buffer.from(arrayBuffer)); // 调用SDK,支持传入文件路径或可读流 const transcription = await openai.audio.transcriptions.create({ file: tempFilePath, // 直接传文件路径 model: 'whisper-1' }); // 清理临时文件 await fs.unlink(tempFilePath); return transcription; };
方案三:跳过Blob,直接从Firebase Storage获取流
如果使用Firebase的服务端SDK(@google-cloud/storage),可以直接获取文件可读流,无需下载为Blob:
import { Storage } from '@google-cloud/storage'; import { OpenAI } from 'openai'; const gcs = new Storage(); const openai = new OpenAI({ apiKey: '你的API密钥' }); export const transcribeFromFirebase = async(bucketName: string, filePath: string) => { const fileStream = gcs.bucket(bucketName).file(filePath).createReadStream(); const transcription = await openai.audio.transcriptions.create({ file: fileStream, model: 'whisper-1', filename: 'audio.webm', contentType: 'video/webm' }); return transcription; };
为什么之前的尝试失败?
- Node.js环境不存在浏览器的
File构造函数,直接调用new File()必然报错; - 手动给Blob添加属性无法通过TypeScript的类型检查,因为SDK定义的
File类型是兼容节点流/文件路径的抽象类型,而非浏览器原生File实例。
内容的提问来源于stack exchange,提问作者Peter Toth
相关产品推荐
相关产品推荐

