타입캐스트 API를 위한 공식 Node.js 라이브러리입니다. AI 기반 음성을 사용하여 텍스트를 생동감 있는 음성으로 변환하세요.
Javascript와 TypeScript 모두에서 작동합니다. 전체 TypeScript 타입이 포함되어 있습니다.
ESM 및 CommonJS를 지원합니다. Node.js 18+ 및 최신 브라우저에서 작동합니다. Node.js 16/17 사용자는 isomorphic-fetch 폴리필을 설치해야 합니다.
설치
npm install @neosapience/typecast-js@latest
빠른 시작
import { TypecastClient } from '@neosapience/typecast-js';
import fs from 'fs';
async function main() {
const client = new TypecastClient({ apiKey: 'YOUR_API_KEY' });
const audio = await client.textToSpeech({
text: "Hello there! I'm your friendly text-to-speech agent.",
model: "ssfm-v30",
voice_id: "tc_672c5f5ce59fac2a48faeaee"
});
await fs.promises.writeFile(`output.${audio.format}`, Buffer.from(audio.audioData));
console.log(`Audio saved! Duration: ${audio.duration}s, Format: ${audio.format}`);
}
main();
기능
타입캐스트 Javascript/TypeScript SDK는 텍스트 음성 변환을 위한 강력한 기능을 제공합니다:
- 다중 음성 모델:
ssfm-v30(최신) 및ssfm-v21AI 음성 모델 지원 - 다국어 지원: 영어, 한국어, 스페인어, 일본어, 중국어 등 37개 언어 지원
- 감정 조절: 감정 프리셋(normal, happy, sad, angry, whisper, toneup, tonedown) 또는 스마트 문맥 인식 추론
- 오디오 사용자 정의: 라우드니스(LUFS -70 to 0), 피치(-12 to +12 반음), 템포(0.5x to 2.0x), 형식(WAV/MP3) 제어
- 보이스 탐색: 모델, 성별, 연령대, 사용 사례별 필터링이 가능한 V2 Voices API
- TypeScript 지원: 전체 타입 정의 포함
- 스트리밍: 저지연 재생을 위한 실시간 청크 오디오 전송
- 타임스탬프 TTS: 자막, 가라오케, 립싱크를 위한 단어·문자 단위 정렬 데이터
- 의존성 없음: 네이티브 fetch API 사용 (Node.js 18+ 및 브라우저에서 작동)
보이스 추천
원하는 스타일은 알지만 정확한 voice_id를 모를 때 recommendVoices를 사용합니다.
const recommendations = await client.recommendVoices(
'warm female voice for a product tutorial',
3
);
for (const voice of recommendations) {
console.log(voice.voice_id, voice.voice_name, voice.score);
}
추천 결과에는 voice_id, voice_name, score만 포함됩니다. 지원 모델, 감정, 성별, 연령대, 사용 사례 같은 상세 메타데이터가 필요하면 getVoiceV2(voiceId) 또는 getVoicesV2()로 추가 조회하세요.
설정
환경 변수 또는 생성자를 통해 API 키를 설정하세요:
// 환경 변수 사용
// export TYPECAST_API_KEY="your-api-key-here"
const client = new TypecastClient({
apiKey: process.env.TYPECAST_API_KEY!
});
// 또는 직접 전달
const client = new TypecastClient({
apiKey: 'your-api-key-here'
});
const client = new TypecastClient({
baseHost: 'https://your-proxy.example.com'
});
고급 사용법
감정 조절 (ssfm-v30)
ssfm-v30은 두 가지 감정 제어 모드를 제공합니다: 프리셋 및 스마트.
AI가 문맥에서 감정을 추론하도록 합니다:
import { SmartPrompt } from '@neosapience/typecast-js';
const audio = await client.textToSpeech({
text: "Everything is going to be okay.",
voice_id: "tc_672c5f5ce59fac2a48faeaee",
model: "ssfm-v30",
prompt: {
emotion_type: "smart",
previous_text: "I just got the best news!", // 선택적 문맥
next_text: "I can't wait to celebrate!" // 선택적 문맥
} as SmartPrompt
});
음성 조절
라우드니스, 피치, 템포 및 출력 형식을 제어합니다:
const audio = await client.textToSpeech({
text: "Customized audio output!",
voice_id: "tc_672c5f5ce59fac2a48faeaee",
model: "ssfm-v30",
output: {
target_lufs: -14.0, // 범위: -70 ~ 0 (LUFS)
audio_pitch: 2, // 범위: -12 to +12 반음
audio_tempo: 1.2, // 범위: 0.5x to 2.0x
audio_format: "mp3" // 옵션: wav, mp3
},
seed: 42 // 부호 없는 정수 시드 (재현 가능한 결과)
});
await fs.promises.writeFile(`output.${audio.format}`, Buffer.from(audio.audioData));
console.log(`Duration: ${audio.duration}s, Format: ${audio.format}`);
파일로 바로 생성하기
오디오 데이터를 직접 다루지 않고 파일까지 바로 저장하려면 generateToFile을 사용하세요. 모델은 기본적으로 ssfm-v30을 사용하며, .mp3 / .wav 확장자는 output.audio_format이 없을 때 출력 포맷 추론에 사용됩니다. 사용할 보이스 ID는 Voices 페이지에서 확인할 수 있습니다.
await client.generateToFile('output.mp3', {
text: 'Hello from Typecast.',
voice_id: 'tc_672c5f5ce59fac2a48faeaee' // voice_id는 https://studio.typecast.ai/developers/api/voices 에서 확인하세요.
});
텍스트만으로 쉼 표현
한 voice로 읽는 문장 안에 쉼만 넣고 싶다면 텍스트에 pause markup을 직접 작성합니다. <|5s|>, <|1s|>, <|0.3s|>, <|0.34413s|>처럼 쓰며 값은 초 단위이고 반드시 s로 끝납니다. 별도 pause 함수를 호출하지 않아도 텍스트만 보고 쉼 위치를 확인할 수 있습니다.
const audio = await client
.composeSpeech()
.defaults({ voice_id: 'tc_672c5f5ce59fac2a48faeaee', model: 'ssfm-v30' })
.say('안녕하세요<|5s|>반갑습니다<|1s|>오늘<|2s|>날씨는 어떤 것 같으세요?')
.generate();
다중 화자 합성
한 파일 안에서 서로 다른 voice나 구간별 pitch, tempo, prompt, seed 같은 옵션을 조합해야 할 때 사용합니다. composer는 각 구간을 WAV로 생성하고 앞뒤 무음 PCM 샘플을 trim한 뒤 합성합니다. MP3가 필요하면 먼저 WAV를 생성한 다음 앱 또는 서버 파이프라인에서 변환하세요.
import { TypecastClient } from '@neosapience/typecast-js';
import fs from 'fs/promises';
const client = new TypecastClient({ apiKey: 'YOUR_API_KEY' });
const audio = await client
.composeSpeech()
.defaults({ voice_id: 'tc_672c5f5ce59fac2a48faeaee', model: 'ssfm-v30' })
.say('Hello there')
.pause(5)
.say('Nice to meet you', { voice_id: 'tc_60e5426de8b95f1d3000d7b5', output: { audio_pitch: 2 } })
.say('Today')
.pause(2)
.say('How does the weather feel?')
.generate();
await fs.writeFile('conversation.wav', Buffer.from(audio.audioData));
보이스 탐색 (V2 API)
향상된 메타데이터로 사용 가능한 보이스를 나열하고 필터링합니다:
// 모든 음성 가져오기
const voices = await client.getVoicesV2();
// 기준으로 필터링
const filtered = await client.getVoicesV2({
model: 'ssfm-v30',
gender: 'female',
age: 'young_adult'
});
// 음성 정보 표시
voices.forEach(voice => {
console.log(`ID: ${voice.voice_id}, Name: ${voice.voice_name}`);
console.log(`Gender: ${voice.gender}, Age: ${voice.age}`);
console.log(`Models: ${voice.models.map(m => m.version).join(', ')}`);
console.log(`Use cases: ${voice.use_cases?.join(', ')}`);
});
다국어 콘텐츠
SDK는 자동 언어 감지와 함께 37개 언어를 지원합니다:
// 언어 자동 감지 (권장)
const audio = await client.textToSpeech({
text: "こんにちは。お元気ですか。",
voice_id: "tc_672c5f5ce59fac2a48faeaee",
model: "ssfm-v30"
});
// 또는 명시적으로 언어 지정
const koreanAudio = await client.textToSpeech({
text: "안녕하세요. 반갑습니다.",
voice_id: "tc_672c5f5ce59fac2a48faeaee",
model: "ssfm-v30",
language: "kor" // ISO 639-3 언어 코드
});
await fs.promises.writeFile(`output.${audio.format}`, Buffer.from(audio.audioData));
스트리밍
저지연 재생을 위한 실시간 오디오 청크 스트리밍:
// Node 18+ (내장 fetch). 스트림을 ffplay로 파이핑하여 실시간 재생.
// 사전 설치: ffmpeg (brew/choco/apt install ffmpeg)
import { spawn } from "node:child_process";
import { TypecastClient } from '@neosapience/typecast-js';
const client = new TypecastClient({ apiKey: 'YOUR_API_KEY' });
const ffplay = spawn(
"ffplay",
["-autoexit", "-nodisp", "-loglevel", "error", "-i", "pipe:0"],
{ stdio: ["pipe", "ignore", "ignore"] },
);
const stream = await client.textToSpeechStream({
text: "이 텍스트를 실시간으로 오디오로 스트리밍합니다.",
model: "ssfm-v30",
voice_id: "tc_672c5f5ce59fac2a48faeaee",
output: { audio_format: "wav" }
});
// ReadableStream - 청크가 도착하는 즉시 읽습니다
const reader = stream.getReader();
while (true) {
const { value, done } = await reader.read();
if (done) break;
ffplay.stdin.write(value);
}
ffplay.stdin.end();
await new Promise((resolve) => ffplay.on("close", resolve));
타임스탬프 TTS
textToSpeechWithTimestamps()는 POST /v1/text-to-speech/with-timestamps를 래핑하여 오디오와 함께 단어·문자 단위 정렬 데이터를 반환합니다. 자막 생성, 가라오케 하이라이트, 립싱크 등에 활용할 수 있습니다.
기본 사용법
import { TypecastClient } from '@neosapience/typecast-js';
import fs from 'fs';
const client = new TypecastClient({ apiKey: 'YOUR_API_KEY' });
const result = await client.textToSpeechWithTimestamps({
text: "Hello. How are you?",
model: "ssfm-v30",
voice_id: "tc_60e5426de8b95f1d3000d7b5",
});
await fs.promises.writeFile("output.wav", result.audioBytes());
console.log(`Duration: ${result.audio_duration}s`);
result.words.forEach(w => {
console.log(` [${w.start_time.toFixed(3)}s – ${w.end_time.toFixed(3)}s] ${w.text}`);
});
자막 내보내기
await fs.promises.writeFile("output.srt", result.toSrt(), "utf-8");
await fs.promises.writeFile("output.vtt", result.toVtt(), "utf-8");
지원 언어
SDK는 자동 언어 감지와 함께 37개 언어를 지원합니다:
| 코드 | 언어 | 코드 | 언어 | 코드 | 언어 |
|---|---|---|---|---|---|
eng | 영어 | jpn | 일본어 | ukr | 우크라이나어 |
kor | 한국어 | ell | 그리스어 | ind | 인도네시아어 |
spa | 스페인어 | tam | 타밀어 | dan | 덴마크어 |
deu | 독일어 | tgl | 타갈로그어 | swe | 스웨덴어 |
fra | 프랑스어 | fin | 핀란드어 | msa | 말레이어 |
ita | 이탈리아어 | zho | 중국어 | ces | 체코어 |
pol | 폴란드어 | slk | 슬로바키아어 | por | 포르투갈어 |
nld | 네덜란드어 | ara | 아랍어 | bul | 불가리아어 |
rus | 러시아어 | hrv | 크로아티아어 | ron | 루마니아어 |
ben | 벵골어 | hin | 힌디어 | hun | 헝가리어 |
nan | 민난어 | nor | 노르웨이어 | pan | 펀자브어 |
tha | 태국어 | tur | 터키어 | vie | 베트남어 |
yue | 광둥어 |
오류 처리
SDK는 API 오류 처리를 위한 TypecastAPIError를 제공합니다:
import { TypecastClient, TypecastAPIError } from '@neosapience/typecast-js';
try {
const audio = await client.textToSpeech({
text: "Hello world",
voice_id: "tc_672c5f5ce59fac2a48faeaee",
model: "ssfm-v30"
});
} catch (error) {
if (error instanceof TypecastAPIError) {
// TypecastAPIError는 statusCode, message, response를 노출합니다
switch (error.statusCode) {
case 401:
console.error('Invalid API key');
break;
case 402:
console.error('Insufficient credits');
break;
case 422:
console.error('Validation error:', error.response);
break;
case 429:
console.error('Rate limit exceeded - please try again later');
break;
default:
console.error(`API error (${error.statusCode}):`, error.message);
}
} else {
console.error('Unexpected error:', error);
}
}
TypeScript 지원
이 SDK는 TypeScript로 작성되었으며 전체 타입 정의를 제공합니다:
import type {
TTSRequest,
TTSResponse,
TTSModel,
LanguageCode,
Prompt,
PresetPrompt,
SmartPrompt,
Output,
VoiceV2Response,
VoicesV2Filter
} from '@neosapience/typecast-js';