Kitta AI 文档
Kitta Audio CLI

Node.js SDK

使用服务端 SDK 生成语音、等待并保存音频文件。

需要 Node.js 22+、账号 API Key 和足够的 API 额度。仅在服务端使用,不要在浏览器中暴露长期密钥。

npm install @kittaai/audio-sdk

完整生成与保存示例

将以下代码保存为 generate-speech.mjs。从运行环境注入 KITTA_API_KEY,CLI 钥匙串不会自动供 SDK 使用。本示例从仓库独立示例同步生成。

import { lstat, writeFile } from 'node:fs/promises';
import { KittaClient, KittaError } from '@kittaai/audio-sdk';

const [voiceId, idempotencyKey, output = 'hello.mp3'] = process.argv.slice(2);
if (!voiceId || !idempotencyKey || !process.env.KITTA_API_KEY) {
  throw new Error(
    'Set KITTA_API_KEY, then run: node generate-speech.mjs VOICE_ID BUSINESS_OPERATION_KEY [output.mp3]',
  );
}
try {
  await lstat(output);
  throw new Error('Output already exists; choose a new filename. No request was submitted.');
} catch (error) {
  if (error.code !== 'ENOENT') throw error;
}

const client = new KittaClient({
  origin: 'https://kittaai.com',
  apiKey: process.env.KITTA_API_KEY,
});
let taskId;
try {
  const created = await client.createTts(
    { voiceId, text: 'Hello from Kitta', format: 'mp3' },
    { idempotencyKey },
  );
  taskId = created.data.task.taskId;
  console.error(JSON.stringify({ taskId }));
  await client.waitTts(taskId);
  const audio = await client.request('getHttpTtsV3JobAudio', { jobId: taskId });
  if (!(audio.data instanceof Response)) throw new Error('Expected an audio response.');
  const bytes = Buffer.from(await audio.data.arrayBuffer());
  if (bytes.length === 0) throw new Error('The audio response was empty.');
  await writeFile(output, bytes, { flag: 'wx' });
  console.log(JSON.stringify({ taskId, output, bytes: bytes.length }));
} catch (error) {
  console.error(
    JSON.stringify({
      code: error instanceof KittaError ? error.code : 'LOCAL_ERROR',
      taskId: error instanceof KittaError ? (error.taskId ?? taskId) : taskId,
      requestId: error instanceof KittaError ? error.requestId : undefined,
      message:
        'Keep the original operation key and task ID. Inspect the task before creating another paid request.',
    }),
  );
  process.exitCode = 1;
}
node generate-speech.mjs VOICE_ID BUSINESS_OPERATION_KEY hello.mp3

用可用声音 ID 和已保留的业务幂等键替换占位符。成功后 hello.mp3 包含音频,stdout 返回文件信息。短文本示例先将音频读入内存再保存;大文件应使用流和临时文件,再以不覆盖方式发布结果。

其他音频操作

request 使用公共 API 字段名,不使用 CLI 参数别名。以下是独立的付费操作示例,不要为验证导入就全部执行。

await client.request('createOpenSpeechTranscription', { audio_url: 'https://example.com/recording.wav' });
await client.request('createOpenVoice', { name: 'Narrator', audioFiles: ['sample.wav'], visibility: 'private' });
await client.request('createOpenVoiceDesign', { prompt: 'A calm warm narrator', previewText: 'Hello from Kitta' });

请用你有权处理的 URL 或文件替换样本。具体字段、约束和返回结构以导出的 operations 和命令参考中的 API Schema 为准。

错误与恢复

SDK 不持久化密钥、幂等键或任务 ID。业务系统必须在提交前保留幂等键,并保存返回的任务 ID。已知 ID 时,使用 getTts、waitTts 和下载接口恢复,而不是创建新请求。

KittaError 提供 code、status、requestId 和 taskId。读取及幂等 TTS 创建会重试暂时性错误;其他付费操作不自动重试。停止本地等待不会取消远程任务。默认请求超时 30 秒、等待超时 600 秒。

恢复与计费 · 命令与字段参考