news 2026/9/13 16:17:16

如何用 AI SDK 的 generateSpeech 生成语音并获取音频数据

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
如何用 AI SDK 的 generateSpeech 生成语音并获取音频数据

如何用 AI SDK 的 generateSpeech 生成语音并获取音频数据

【免费下载链接】aiThe AI Toolkit for TypeScript. From the creators of Next.js, the AI SDK is a free open-source library for building AI-powered applications and agents项目地址: https://gitcode.com/GitHub_Trending/ai/ai

当你需要在 TypeScript 应用中把一段文本转成音频时,AI SDK(The AI Toolkit for TypeScript)提供的generateSpeech函数可以直接完成这件事:调用语音模型生成语音,返回结果中的audio对象提供二进制数据(Uint8Array)和 base64 字符串两种访问方式,还可以按mediaType把音频写入磁盘。本文以 OpenAI 的tts-1模型为例,走通从配置密钥、调用函数到验证产出文件的完整路径。

准备依赖与 API Key

仓库自带的示例位于examples/ai-functions,其 README(examples/ai-functions/README.md)说明了三步:

  1. examples/ai-functions下创建.env文件,写入对应服务商的密钥。以 OpenAI 为例,按文档原样填写(引号内替换为你自己的密钥):
OPENAI_API_KEY="YOUR_OPENAI_API_KEY"
  1. 从 AI SDK 仓库根目录安装并构建:
pnpm install pnpm build
  1. 之后可以从examples/ai-functions目录用pnpm tsx运行任意示例脚本,格式为:
pnpm tsx src/path/to/example.ts

调用 generateSpeech 生成语音

generateSpeechai包导入(参考 API 文档)。必填参数是modeltext,可选参数包括voiceoutputFormatspeedlanguageproviderOptions等。仓库内置的 OpenAI 基础示例 examples/ai-functions/src/generate-speech/openai/basic.ts 展示了最短可行调用:

import { openai } from '@ai-sdk/openai'; import { generateSpeech } from 'ai'; const result = await generateSpeech({ model: openai.speech('tts-1'), text: 'Hello from the AI SDK!', });

如果需要通过 OpenAI 的voice参数指定声音,可选值在 OpenAI Provider 文档 中列明:alloyashcoralechofableonyxnovasageshimmer

import { generateSpeech } from 'ai'; import { openai } from '@ai-sdk/openai'; const result = await generateSpeech({ model: openai.speech('tts-1'), text: 'Hello, world!', voice: 'alloy', // OpenAI voice ID });

除 OpenAI 外,generateSpeech还支持其他服务商的语音模型(Speech 概览文档 列出了可用子集),例如 ElevenLabs 的eleven_multilingual_v2

import { generateSpeech } from 'ai'; import { elevenLabs } from '@ai-sdk/elevenlabs'; const { audio } = await generateSpeech({ model: elevenLabs.speech('eleven_multilingual_v2'), text: 'Hello from the AI SDK!', voice: 'your-voice-id', // Required: get this from your ElevenLabs account });

注意voice的值含义依赖服务商:OpenAI 使用固定声音名,ElevenLabs 要求填自己账户中的 voice id(文档原文标注为 Required,需从 ElevenLabs 账户获取)。

获取音频数据:uint8Array、base64 与元数据

generateSpeech的返回值(API 参考)包含以下字段:

字段类型说明
audioGeneratedAudioFile生成的音频
warningsWarning[]来自服务商的警告(如不支持的设置项)
providerMetadataRecord<string, JSONObject>可选,服务商元数据,外层 key 为服务商名
responsesArray<SpeechModelResponseMetadata>响应元数据,包含timestampmodelIdheaders

其中audioGeneratedAudioFile)提供四种访问方式:

属性类型用途
base64string音频的 base64 编码字符串
uint8ArrayUint8Array音频二进制数据
mediaTypestring媒体类型,如"audio/mpeg"
formatstring音频格式,如"mp3"

根据 Speech 文档 的写法,两种取数方式分别是:

const audioData = audio.uint8Array; // audio data as Uint8Array const audioBase64 = audio.base64; // audio data as base64 string

可选分支:按 mediaType 保存为文件

仓库示例提供了 save-audio 辅助函数,演示了如何根据mediaType选择扩展名并把uint8Array写入磁盘:

import type { GeneratedAudioFile } from 'ai'; import fs from 'node:fs'; import path from 'node:path'; const OUTPUT_DIR = 'output'; const audioFormatMap = { 'audio/mpeg': 'mp3', 'audio/wav': 'wav', 'audio/flac': 'flac', 'audio/aac': 'aac', 'audio/ogg': 'ogg', }; export async function saveAudioFile(audio: GeneratedAudioFile) { const timestamp = Date.now(); const extension = audio.mediaType in audioFormatMap ? audioFormatMap[audio.mediaType as keyof typeof audioFormatMap] : 'mp3'; // Save the audio file to disk. fs.mkdirSync(OUTPUT_DIR, { recursive: true }); const filePath = path.join(OUTPUT_DIR, `audio-${timestamp}.${extension}`); await fs.promises.writeFile(filePath, audio.uint8Array); console.log(`Saved audio to ${filePath}`); }

运行示例并验证结果

examples/ai-functions目录下运行 OpenAI 基础示例:

pnpm tsx src/generate-speech/openai/basic.ts

该示例(见 basic.ts)在调用后会打印四个部分,并调用saveAudioFile落盘:

console.log('Audio:', result.audio); console.log('Warnings:', result.warnings); console.log('Responses:', result.responses); console.log('Provider Metadata:', result.providerMetadata); await saveAudioFile(result.audio);

成功的判断依据是:控制台依次输出上述字段,最后一行打印Saved audio to output/audio-<时间戳>.<扩展名>(路径与时间戳为运行时实际值,示例中的audio-${timestamp}由代码动态生成),并且output/目录下出现对应的音频文件。

处理 AI_NoSpeechGeneratedError 与常见设置

无音频产出时的错误处理

generateSpeech无法生成有效音频时会抛出AI_NoSpeechGeneratedError(错误参考)。文档说明该错误出现在 "no audio could be generated from the input" 的情况,Speech 文档 进一步列出两类原因:模型未能生成响应,或模型生成的响应无法解析。错误对象保留两个属性用于排查日志:

  • responses:语音模型响应元数据,含时间戳、模型和 headers;
  • cause:错误原因,可用于更细粒度的错误处理。

判断与捕获方式:

import { generateSpeech, NoSpeechGeneratedError } from 'ai'; import { openai } from '@ai-sdk/openai'; try { await generateSpeech({ model: openai.speech('tts-1'), text: 'Hello, world!', }); } catch (error) { if (NoSpeechGeneratedError.isInstance(error)) { console.log('AI_NoSpeechGeneratedError'); console.log('Cause:', error.cause); console.log('Responses:', error.responses); } }

providerOptions、超时与自定义 Header

  • providerOptions:传递服务商特有参数。OpenAI 示例见 Provider 文档:
import { generateSpeech } from 'ai'; import { openai, type OpenAISpeechModelOptions } from '@ai-sdk/openai'; const result = await generateSpeech({ model: openai.speech('tts-1'), text: 'Hello, world!', voice: 'alloy', providerOptions: { openai: { speed: 1.2, } satisfies OpenAISpeechModelOptions, }, });
  • abortSignal:传入AbortSignal可中止生成或设置超时,文档给出的示例是 1 秒超时:
abortSignal: AbortSignal.timeout(1000), // Abort after 1 second
  • headers:传入Record<string, string>为请求附加自定义 HTTP header,例如:
headers: { 'X-Custom-Header': 'custom-value' },
  • warnings:调用成功后通过audio.warnings(即返回值的warnings字段)读取服务商警告,例如某个参数不被当前模型支持时:
const warnings = result.warnings;

另外,API 参考中还列出了maxRetries(最大重试次数,文档标注 Default: 2)、outputFormat(如"mp3""wav")和language(ISO 639-1 语言码,如"en""es",或"auto"自动检测,文档注明 Provider support varies)等可选参数,可按需查阅 generateSpeech API 参考。

小结

完成该场景需要三步:在examples/ai-functions配好.env密钥并pnpm install+pnpm build,用generateSpeech({ model, text, ... })发起调用,再从result.audio中取uint8Arraybase64消费音频数据、按mediaType落盘。运行pnpm tsx src/generate-speech/openai/basic.ts后,以控制台输出的Saved audio to ...output/目录下的音频文件作为成功标志;若调用抛错,用NoSpeechGeneratedError.isInstance判断并通过causeresponses定位原因。

【免费下载链接】aiThe AI Toolkit for TypeScript. From the creators of Next.js, the AI SDK is a free open-source library for building AI-powered applications and agents项目地址: https://gitcode.com/GitHub_Trending/ai/ai

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/13 16:12:22

CC1310调试解锁:BOOT MODE与OTP状态排查指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/13 16:11:21

AI应用开发实战路线图:云原生胶水层构建无登录聊天网页

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/13 16:10:05

Linux内核IPv6地址管理源码解析:addrconf.c核心机制

去年底我给自己定了一个任务&#xff1a;把 Linux 6.19 的 net/ipv6/addrconf.c 完整读一遍。说实话这个文件我早就想啃&#xff0c;但一直没下定决心&#xff0c;因为地址配置这块涉及的状态机、定时器、netlink 回调纠缠在一起&#xff0c;光看代码很容易绕晕。后来我借助 De…

作者头像 李华