인증 시작하기
타입캐스트 API를 사용하려면 API 키로 요청을 인증해야 합니다. 다음 단계를 따르세요:첫 번째 단계
타입캐스트 API 콘솔을 방문하여 새 API 키를 생성하세요
첫 번째 요청 실행하기
- SDK
- Direct API
SDK 설치
pip install --upgrade typecast-python
npm install @neosapience/typecast-js
# pnpm add @neosapience/typecast-js
# yarn add @neosapience/typecast-js
dotnet add package typecast-csharp
<dependency>
<groupId>com.neosapience</groupId>
<artifactId>typecast-java</artifactId>
<version>1.2.3</version>
</dependency>
dependencies {
implementation("com.neosapience:typecast-kotlin:1.2.3")
}
[dependencies]
typecast-rust = "0.3.3"
tokio = { version = "1", features = ["full"] }
go get github.com/neosapience/typecast-sdk/typecast-go
모든 SDK는 최신 버전이 필요합니다.
- Python: 이전 버전이 있다면
pip install --upgrade typecast-python으로 업그레이드하세요 - Javascript: 이전 버전이 있다면
npm update @neosapience/typecast-js로 업그레이드하세요 - C#:
dotnet add package typecast-csharp로 업데이트하세요 - Java:
pom.xml또는build.gradle에서 버전을 업데이트하세요 - Kotlin:
build.gradle.kts에서 버전을 업데이트하세요 - Rust:
Cargo.toml에서 버전을 업데이트하세요
음성 합성과 오디오 파일 저장만 필요하다면 SDK의
generateToFile 또는 generate_to_file 헬퍼를 사용하세요. 각 SDK 페이지에서 언어별 예시를 확인할 수 있습니다.가져오기 및 초기화
from typecast import Typecast
from typecast.models import TTSRequest, SmartPrompt
# 클라이언트 초기화
client = Typecast(api_key="YOUR_API_KEY")
# 텍스트를 음성으로 변환
response = client.text_to_speech(TTSRequest(
text="Everything is going to be okay.",
model="ssfm-v30",
voice_id="tc_672c5f5ce59fac2a48faeaee",
prompt=SmartPrompt(
emotion_type="smart",
previous_text="I just got the best news!",
next_text="I can't wait to celebrate!"
)
))
# 오디오 파일 저장
with open('typecast.wav', 'wb') as f:
f.write(response.audio_data)
import { TypecastClient } from '@neosapience/typecast-js';
import fs from 'fs';
// 클라이언트 초기화
const client = new TypecastClient({
apiKey: 'YOUR_API_KEY'
});
// 텍스트를 음성으로 변환
const audio = await client.textToSpeech({
text: "Everything is going to be okay.",
model: "ssfm-v30",
voice_id: "tc_672c5f5ce59fac2a48faeaee",
prompt: {
emotion_type: "smart",
previous_text: "I just got the best news!",
next_text: "I can't wait to celebrate!"
}
});
// 오디오 파일 저장
await fs.promises.writeFile('typecast.wav', Buffer.from(audio.audioData));
using Typecast;
using Typecast.Models;
// 클라이언트 초기화
using var client = new TypecastClient("YOUR_API_KEY");
// 텍스트를 음성으로 변환
var request = new TTSRequest(
text: "Everything is going to be okay.",
voiceId: "tc_672c5f5ce59fac2a48faeaee",
model: TTSModel.SsfmV30
)
{
Prompt = new SmartPrompt(
previousText: "I just got the best news!",
nextText: "I can't wait to celebrate!"
)
};
var response = await client.TextToSpeechAsync(request);
// 오디오 파일 저장
await response.SaveToFileAsync("typecast.wav");
import com.neosapience.TypecastClient;
import com.neosapience.models.*;
import java.io.FileOutputStream;
// 클라이언트 초기화
TypecastClient client = new TypecastClient("YOUR_API_KEY");
// 텍스트를 음성으로 변환
TTSRequest request = TTSRequest.builder()
.voiceId("tc_672c5f5ce59fac2a48faeaee")
.text("Everything is going to be okay.")
.model(TTSModel.SSFM_V30)
.prompt(SmartPrompt.builder()
.previousText("I just got the best news!")
.nextText("I can't wait to celebrate!")
.build())
.build();
TTSResponse response = client.textToSpeech(request);
// 오디오 파일 저장
try (FileOutputStream fos = new FileOutputStream("typecast.wav")) {
fos.write(response.getAudioData());
}
client.close();
import com.neosapience.TypecastClient
import com.neosapience.models.*
import java.io.File
// 클라이언트 초기화
val client = TypecastClient.create("YOUR_API_KEY")
// 텍스트를 음성으로 변환
val request = TTSRequest.builder()
.voiceId("tc_672c5f5ce59fac2a48faeaee")
.text("Everything is going to be okay.")
.model(TTSModel.SSFM_V30)
.prompt(SmartPrompt.builder()
.previousText("I just got the best news!")
.nextText("I can't wait to celebrate!")
.build())
.build()
val response = client.textToSpeech(request)
// 오디오 파일 저장
File("typecast.wav").writeBytes(response.audioData)
client.close()
use typecast_rust::{TypecastClient, TTSRequest, TTSModel, SmartPrompt};
use std::fs;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// 클라이언트 초기화
let client = TypecastClient::with_api_key("YOUR_API_KEY")?;
// 텍스트를 음성으로 변환
let request = TTSRequest::new(
"tc_672c5f5ce59fac2a48faeaee",
"Everything is going to be okay.",
TTSModel::SsfmV30,
)
.prompt(
SmartPrompt::new()
.previous_text("I just got the best news!")
.next_text("I can't wait to celebrate!")
);
let response = client.text_to_speech(&request).await?;
// 오디오 파일 저장
fs::write("typecast.wav", &response.audio_data)?;
Ok(())
}
API 키를 두 가지 방법으로 설정할 수 있습니다:
- 애플리케이션 코드에서 직접 구성
- 셸 환경 변수로 설정
# 현재 세션에 설정
export TYPECAST_API_KEY='YOUR_API_KEY'
# 현재 세션에 설정
set TYPECAST_API_KEY=YOUR_API_KEY
import requests
import os
api_key = os.environ.get("TYPECAST_API_KEY", "YOUR_API_KEY")
url = "https://api.typecast.ai/v1/text-to-speech"
headers = {"X-API-KEY": api_key, "Content-Type": "application/json"}
payload = {
"text": "Everything is going to be okay.",
"model": "ssfm-v30",
"voice_id": "tc_672c5f5ce59fac2a48faeaee",
"prompt": {
"emotion_type": "smart",
"previous_text": "I just got the best news!",
"next_text": "I can't wait to celebrate!"
}
}
response = requests.post(url, headers=headers, json=payload)
if response.status_code == 200:
with open('typecast.wav', 'wb') as f:
f.write(response.content)
print("Audio file saved as typecast.wav")
else:
print(f"Error: {response.status_code} - {response.text}")
import fs from "fs";
const apiKey = process.env.TYPECAST_API_KEY || 'YOUR_API_KEY';
async function convertTextToSpeech() {
const url = 'https://api.typecast.ai/v1/text-to-speech';
const payload = {
text: "Everything is going to be okay.",
model: "ssfm-v30",
voice_id: "tc_672c5f5ce59fac2a48faeaee",
prompt: {
emotion_type: "smart",
previous_text: "I just got the best news!",
next_text: "I can't wait to celebrate!"
}
};
try {
const response = await fetch(url, {
method: 'POST',
headers: {
'X-API-KEY': apiKey,
'Content-Type': 'application/json'
},
body: JSON.stringify(payload)
});
if (!response.ok) {
throw new Error(`Error: ${response.status} - ${await response.text()}`);
}
const audioData = await response.arrayBuffer();
fs.writeFileSync('typecast.wav', Buffer.from(audioData));
console.log('Audio file saved as typecast.wav');
} catch (error) {
console.error('Error converting text to speech:', error);
}
}
convertTextToSpeech();
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
String apiKey = System.getenv("TYPECAST_API_KEY");
if (apiKey == null) apiKey = "YOUR_API_KEY";
String urlString = "https://api.typecast.ai/v1/text-to-speech";
String payload = "{" +
"\"text\": \"Everything is going to be okay.\"," +
"\"model\": \"ssfm-v30\"," +
"\"voice_id\": \"tc_672c5f5ce59fac2a48faeaee\"," +
"\"prompt\": {" +
"\"emotion_type\": \"smart\"," +
"\"previous_text\": \"I just got the best news!\"," +
"\"next_text\": \"I can't wait to celebrate!\"" +
"}" +
"}";
URL url = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("X-API-KEY", apiKey);
conn.setRequestProperty("Content-Type", "application/json");
conn.setDoOutput(true);
try (OutputStream os = conn.getOutputStream()) {
os.write(payload.getBytes("UTF-8"));
}
if (conn.getResponseCode() == 200) {
try (InputStream is = conn.getInputStream();
FileOutputStream fos = new FileOutputStream("typecast.wav")) {
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = is.read(buffer)) != -1) {
fos.write(buffer, 0, bytesRead);
}
}
System.out.println("Audio file saved as typecast.wav");
} else {
System.out.println("Error: " + conn.getResponseCode());
}
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
var apiKey = Environment.GetEnvironmentVariable("TYPECAST_API_KEY") ?? "YOUR_API_KEY";
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-KEY", apiKey);
var payload = new
{
text = "Everything is going to be okay.",
model = "ssfm-v30",
voice_id = "tc_672c5f5ce59fac2a48faeaee",
prompt = new
{
emotion_type = "smart",
previous_text = "I just got the best news!",
next_text = "I can't wait to celebrate!"
}
};
var content = new StringContent(
JsonSerializer.Serialize(payload),
Encoding.UTF8,
"application/json"
);
var response = await client.PostAsync("https://api.typecast.ai/v1/text-to-speech", content);
if (response.IsSuccessStatusCode)
{
var audioData = await response.Content.ReadAsByteArrayAsync();
await File.WriteAllBytesAsync("typecast.wav", audioData);
Console.WriteLine("Audio file saved as typecast.wav");
}
else
{
Console.WriteLine($"Error: {response.StatusCode}");
}
curl -X POST "https://api.typecast.ai/v1/text-to-speech" \
-H "X-API-KEY: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "ssfm-v30",
"text": "Everything is going to be okay.",
"voice_id": "tc_672c5f5ce59fac2a48faeaee",
"prompt": {
"emotion_type": "smart",
"previous_text": "I just got the best news!",
"next_text": "I can'\''t wait to celebrate!"
}
}' --output typecast.wav
오디오 출력 설정
요청에output 객체를 추가하여 오디오 출력을 커스터마이즈할 수 있습니다:| 파라미터 | 타입 | 범위 | 기본값 | 설명 |
|---|---|---|---|---|
volume | integer | 0–200 | 100 | 상대적 볼륨 스케일링. target_lufs와 동시에 사용할 수 없습니다. |
target_lufs | number | -70–0 | — | LUFS 기반 절대 라우드니스 정규화. volume과 동시에 사용할 수 없습니다. |
audio_pitch | integer | -12–12 | 0 | 피치 조정 (반음 단위). |
audio_tempo | number | 0.5–2.0 | 1.0 | 재생 속도 배율. |
audio_format | string | wav, mp3 | wav | 출력 오디오 포맷. |
target_lufs는 여러 클립 간 일관된 라우드니스가 필요할 때, volume은 단순한 상대적 볼륨 조절이 필요할 때 사용하세요.예시: target_lufs를 사용한 출력 설정
{
"text": "일관된 라우드니스 예시입니다.",
"model": "ssfm-v30",
"voice_id": "tc_672c5f5ce59fac2a48faeaee",
"output": {
"target_lufs": -14.0,
"audio_format": "mp3"
}
}
요청에 사용할 수 있는 Voice ID를 찾아보려면 API 레퍼런스의 보이스 목록 조회를 참조하세요.
모든 보이스 목록 조회하기
타입캐스트를 효과적으로 사용하려면 Voice ID에 액세스해야 합니다./v2/voices 엔드포인트는 고유 식별자, 이름, 지원 모델 및 감정이 포함된 사용 가능한 보이스의 전체 목록을 제공합니다.
모델, 성별, 연령대 및 사용 사례 등의 선택적 쿼리 파라미터를 사용하여 보이스를 필터링할 수 있습니다.
보이스 페이지에서 API 호출 없이 API에서 사용할 수 있는 보이스 목록과 샘플 음성을 미리 보고 들어볼 수 있습니다. 먼저 보이스를 비교한 뒤, 사용할 Voice ID를 API 요청에 넣어주세요.
- SDK
- Direct API
from typecast import Typecast
from typecast.models import VoicesV2Filter, TTSModel
# 클라이언트 초기화
client = Typecast(api_key="YOUR_API_KEY")
# 모든 음성 가져오기 (선택적으로 모델, 성별, 나이, 사용 사례로 필터링)
voices = client.voices_v2(VoicesV2Filter(model=TTSModel.SSFM_V30))
print(f"Found {len(voices)} voices:")
for voice in voices:
for model in voice.models:
print(f"ID: {voice.voice_id}, Name: {voice.voice_name}, Model: {model.version.value}, Emotions: {', '.join(model.emotions)}")
import { TypecastClient } from '@neosapience/typecast-js';
// 클라이언트 초기화
const client = new TypecastClient({
apiKey: 'YOUR_API_KEY'
});
// 모든 음성 가져오기 (선택적으로 모델, 성별, 나이, 사용 사례로 필터링)
const voices = await client.getVoicesV2({model: 'ssfm-v30'});
console.log(`Found ${voices.length} voices:`);
voices.forEach(voice => {
voice.models.forEach(model => {
console.log(`ID: ${voice.voice_id}, Name: ${voice.voice_name}, Model: ${model.version}, Emotions: ${model.emotions.join(', ')}`);
});
});
using Typecast;
using Typecast.Models;
// 클라이언트 초기화
using var client = new TypecastClient("YOUR_API_KEY");
// 모든 음성 가져오기 (선택적으로 모델, 성별, 나이, 사용 사례로 필터링)
var filter = new VoicesV2Filter { Model = TTSModel.SsfmV30 };
var voices = await client.GetVoicesV2Async(filter);
Console.WriteLine($"Found {voices.Count} voices:");
foreach (var voice in voices)
{
foreach (var model in voice.Models)
{
Console.WriteLine($"ID: {voice.VoiceId}, Name: {voice.VoiceName}, Model: {model.Version}, Emotions: {string.Join(", ", model.Emotions)}");
}
}
import com.neosapience.TypecastClient;
import com.neosapience.models.*;
// 클라이언트 초기화
TypecastClient client = new TypecastClient("YOUR_API_KEY");
// 모든 음성 가져오기 (선택적으로 모델, 성별, 나이, 사용 사례로 필터링)
VoicesV2Filter filter = VoicesV2Filter.builder()
.model(TTSModel.SSFM_V30)
.build();
List<VoiceV2Response> voices = client.getVoicesV2(filter);
System.out.println("Found " + voices.size() + " voices:");
for (VoiceV2Response voice : voices) {
for (ModelInfo model : voice.getModels()) {
System.out.println("ID: " + voice.getVoiceId() + ", Name: " + voice.getVoiceName() +
", Model: " + model.getVersion() + ", Emotions: " + String.join(", ", model.getEmotions()));
}
}
client.close();
import requests
import os
api_key = os.environ.get("TYPECAST_API_KEY", "YOUR_API_KEY")
url = "https://api.typecast.ai/v2/voices"
headers = {"X-API-KEY": api_key}
params = {"model": "ssfm-v30"} # 선택 사항: model, gender, age, use_cases
response = requests.get(url, headers=headers, params=params)
if response.status_code == 200:
voices = response.json()
print(f"Found {len(voices)} voices:")
for voice in voices:
for model in voice['models']:
print(f"ID: {voice['voice_id']}, Name: {voice['voice_name']}, Model: {model['version']}, Emotions: {', '.join(model['emotions'])}")
else:
print(f"Error: {response.status_code} - {response.text}")
const apiKey = process.env.TYPECAST_API_KEY || 'YOUR_API_KEY';
async function getVoices() {
const url = 'https://api.typecast.ai/v2/voices';
const params = new URLSearchParams({model: 'ssfm-v30'}); // 선택 사항: model, gender, age, use_cases
try {
const response = await fetch(`${url}?${params}`, {
method: 'GET',
headers: {'X-API-KEY': apiKey}
});
if (!response.ok) {
throw new Error(`Error: ${response.status} - ${await response.text()}`);
}
const voices = await response.json();
console.log(`Found ${voices.length} voices:`);
voices.forEach(voice => {
voice.models.forEach(model => {
console.log(`ID: ${voice.voice_id}, Name: ${voice.voice_name}, Model: ${model.version}, Emotions: ${model.emotions.join(', ')}`);
});
});
} catch (error) {
console.error('Error fetching voices:', error);
}
}
getVoices();
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
String apiKey = System.getenv("TYPECAST_API_KEY");
if (apiKey == null) apiKey = "YOUR_API_KEY";
String urlString = "https://api.typecast.ai/v2/voices?model=ssfm-v30";
URL url = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("X-API-KEY", apiKey);
if (conn.getResponseCode() == 200) {
try (BufferedReader br = new BufferedReader(
new InputStreamReader(conn.getInputStream(), "UTF-8"))) {
StringBuilder response = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
response.append(line);
}
System.out.println(response.toString());
}
} else {
System.out.println("Error: " + conn.getResponseCode());
}
var apiKey = Environment.GetEnvironmentVariable("TYPECAST_API_KEY") ?? "YOUR_API_KEY";
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-KEY", apiKey);
var response = await client.GetAsync("https://api.typecast.ai/v2/voices?model=ssfm-v30");
if (response.IsSuccessStatusCode)
{
var json = await response.Content.ReadAsStringAsync();
Console.WriteLine(json);
}
else
{
Console.WriteLine($"Error: {response.StatusCode}");
}
curl -X GET "https://api.typecast.ai/v2/voices?model=ssfm-v30" \
-H "X-API-KEY: YOUR_API_KEY"
{
"voice_id": "tc_672c5f5ce59fac2a48faeaee",
"voice_name": "Dylan",
"models": [
{
"version": "ssfm-v30",
"emotions": ["normal", "happy", "sad", "angry", "whisper", "toneup", "tonedown"]
}
],
"gender": "male",
"age": "young_adult",
"use_cases": ["Conversational", "TikTok/Reels/Shorts", "Audiobook/Storytelling"]
}
텍스트 음성 변환 요청을 할 때 유효한 Voice ID가 필요합니다. ssfm-v30을 사용하면 모든 7가지 감정 프리셋을 모든 보이스에서 사용할 수 있습니다.
실시간 오디오 스트리밍
저지연 애플리케이션의 경우, 스트리밍 엔드포인트를 사용하여 전체 합성을 기다리지 않고 오디오 청크가 도착하는 즉시 재생할 수 있습니다. WAV 스트리밍 형식: 32000 Hz, 16비트, 모노 PCM. 첫 번째 청크에 44바이트 WAV 헤더가 포함되며, 이후 청크는 원시 PCM 데이터만 포함합니다.- SDK
- Direct API
# pip install typecast-python sounddevice
import sounddevice as sd
from typecast import Typecast
from typecast.models import TTSRequestStream, OutputStream
client = Typecast(api_key="YOUR_API_KEY")
request = TTSRequestStream(
text="이 텍스트를 실시간으로 오디오로 스트리밍합니다.",
model="ssfm-v30",
voice_id="tc_672c5f5ce59fac2a48faeaee",
output=OutputStream(audio_format="wav", target_lufs=-14.0)
)
with sd.RawOutputStream(samplerate=32000, channels=1, dtype="int16") as player:
buf, first = bytearray(), True
for chunk in client.text_to_speech_stream(request):
if first:
chunk = chunk[44:] # 44바이트 WAV 헤더 건너뛰기
first = False
buf.extend(chunk)
n = len(buf) - (len(buf) % 2) # int16 정렬
if n:
player.write(bytes(buf[:n]))
del buf[:n]
// Node 18+. 스트림을 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", target_lufs: -14.0 }
});
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));
import com.neosapience.TypecastClient;
import com.neosapience.models.*;
import javax.sound.sampled.*;
import java.io.*;
TypecastClient client = new TypecastClient("YOUR_API_KEY");
TTSRequestStream request = TTSRequestStream.builder()
.voiceId("tc_672c5f5ce59fac2a48faeaee")
.text("이 텍스트를 실시간으로 오디오로 스트리밍합니다.")
.model(TTSModel.SSFM_V30)
.output(com.neosapience.models.OutputStream.builder()
.audioFormat(AudioFormat.WAV)
.targetLufs(-14.0).build())
.build();
// 32000 Hz, 16비트, 모노, signed, 리틀엔디안
javax.sound.sampled.AudioFormat format =
new javax.sound.sampled.AudioFormat(32000, 16, 1, true, false);
SourceDataLine line = javax.sound.sampled.AudioSystem.getSourceDataLine(format);
line.open(format, 8192);
line.start();
try (InputStream stream = client.textToSpeechStream(request)) {
byte[] buf = new byte[4096];
boolean first = true;
int bytesRead;
while ((bytesRead = stream.read(buf)) != -1) {
int offset = 0;
if (first) { offset = 44; bytesRead -= 44; first = false; }
line.write(buf, offset, bytesRead);
}
}
line.drain();
line.close();
client.close();
더 많은 언어(Go, Rust, Swift, C#, Kotlin, C)의 실시간 재생 예시는 각 SDK 문서를 참조하세요.
# pip install requests sounddevice
import requests
import sounddevice as sd
import os
api_key = os.environ.get("TYPECAST_API_KEY", "YOUR_API_KEY")
response = requests.post(
"https://api.typecast.ai/v1/text-to-speech/stream",
headers={"X-API-KEY": api_key, "Content-Type": "application/json"},
json={
"text": "이 텍스트를 실시간으로 오디오로 스트리밍합니다.",
"model": "ssfm-v30",
"voice_id": "tc_672c5f5ce59fac2a48faeaee",
"output": {"audio_format": "wav", "target_lufs": -14.0},
},
stream=True
)
response.raise_for_status()
with sd.RawOutputStream(samplerate=32000, channels=1, dtype="int16") as player:
buf, first = bytearray(), True
for chunk in response.iter_content(chunk_size=4096):
if not chunk:
continue
if first:
chunk = chunk[44:] # WAV 헤더 건너뛰기
first = False
buf.extend(chunk)
n = len(buf) - (len(buf) % 2)
if n:
player.write(bytes(buf[:n]))
del buf[:n]
# ffplay로 직접 파이핑하여 즉시 재생
curl -s -X POST "https://api.typecast.ai/v1/text-to-speech/stream" \
-H "X-API-KEY: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "ssfm-v30",
"text": "이 텍스트를 실시간으로 오디오로 스트리밍합니다.",
"voice_id": "tc_672c5f5ce59fac2a48faeaee",
"output": {"audio_format": "wav", "target_lufs": -14.0}
}' | ffplay -autoexit -nodisp -loglevel error -i pipe:0
| 파라미터 | 타입 | 범위 | 기본값 | 설명 |
|---|---|---|---|---|
audio_pitch | integer | -12–12 | 0 | 세미톤 단위의 피치 조절 |
audio_tempo | number | 0.5–2.0 | 1.0 | 속도 배율 |
audio_format | string | wav, mp3 | wav | 출력 오디오 형식 |
target_lufs | number | -70–0 | — | LUFS 기반 절대 라우드니스 정규화 |
target_lufs로 스트리밍 오디오의 라우드니스를 클립 간 일관되게 맞출 수 있습니다. 스트리밍 모드에서는 volume을 지원하지 않습니다.타임스탬프 TTS로 자막 생성하기
POST /v1/text-to-speech/with-timestamps를 사용하면 오디오와 함께 단어 단위 정렬 데이터를 받아 자막, 가라오케, 립싱크 애플리케이션을 만들 수 있습니다.
from typecast import Typecast
from typecast.models import TTSRequestWithTimestamps
client = Typecast(api_key="YOUR_API_KEY")
response = client.text_to_speech_with_timestamps(TTSRequestWithTimestamps(
text="Hello. How are you?",
model="ssfm-v30",
voice_id="tc_60e5426de8b95f1d3000d7b5",
))
# 단어별 타임스탬프 출력
for word in response.words:
print(f"[{word.start_time:.3f}s – {word.end_time:.3f}s] {word.text}")
# SRT 자막 내보내기
srt = response.to_srt()
with open("output.srt", "w") as f:
f.write(srt)
import Typecast from "@neosapience/typecast-js";
const client = new Typecast({ apiKey: "YOUR_API_KEY" });
const response = await client.textToSpeechWithTimestamps({
voiceId: "tc_60e5426de8b95f1d3000d7b5",
text: "Hello. How are you?",
model: "ssfm-v30",
});
// 단어별 타임스탬프 출력
for (const word of response.words) {
console.log(`[${word.startTime.toFixed(3)}s – ${word.endTime.toFixed(3)}s] ${word.text}`);
}
// VTT 자막 내보내기
const vtt = response.toVtt();
curl -X POST https://api.typecast.ai/v1/text-to-speech/with-timestamps \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"voice_id": "tc_60e5426de8b95f1d3000d7b5",
"text": "Hello. How are you?",
"model": "ssfm-v30",
"granularity": "word"
}'
각 언어별 타임스탬프 TTS 사용법은 SDK 문서를 참조하세요. 일본어(jpn), 중국어(zho)는
granularity: "char" (문자 단위) 를 사용해야 합니다.다음 단계
축하합니다! 첫 번째 AI 음성을 만들었습니다. 더 자세히 알아보려면 다음 리소스를 참조하세요:API 레퍼런스
타입캐스트 API 사용 방법 알아보기
모델
ssfm-v30 및 ssfm-v21 모델에 대해 알아보기
변경 로그
최신 API 변경 사항 및 업데이트 확인