메인 콘텐츠로 건너뛰기

Documentation Index

Fetch the complete documentation index at: https://typecast.ai/docs/llms.txt

Use this file to discover all available pages before exploring further.

타입캐스트 API를 위한 공식 Rust 라이브러리입니다. AI 기반 음성을 사용하여 텍스트를 생동감 있는 음성으로 변환하세요. Tokio 런타임을 사용한 async/await 지원으로 구축되었습니다. Cargo 패키지 관리자와 함께 작동합니다.

Crates.io

Typecast Rust SDK

소스 코드

Typecast Rust SDK 소스 코드

설치

Cargo.toml에 다음을 추가하세요:
[dependencies]
typecast-rust = "0.3.0"
tokio = { version = "1", features = ["full"] }
또는 Cargo를 사용하여 의존성을 추가하세요:
cargo add typecast-rust tokio --features tokio/full
버전 0.3.0 이상이 설치되어 있는지 확인하세요. 업데이트가 필요하면 Cargo.toml을 확인하세요.

빠른 시작

use typecast_rust::{TypecastClient, TTSRequest, TTSModel};
use std::fs;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 클라이언트 초기화 (환경변수에서 TYPECAST_API_KEY 읽기)
    let client = TypecastClient::from_env()?;

    // 텍스트를 음성으로 변환
    let request = TTSRequest::new(
        "tc_672c5f5ce59fac2a48faeaee",
        "안녕하세요! 저는 텍스트 음성 변환 에이전트입니다.",
        TTSModel::SsfmV30,
    );

    let response = client.text_to_speech(&request).await?;

    // 오디오 파일 저장
    fs::write("output.wav", &response.audio_data)?;

    println!(
        "Audio saved! Duration: {:.2}s, Format: {:?}",
        response.duration, response.format
    );

    Ok(())
}

기능

Typecast Rust SDK는 텍스트 음성 변환을 위한 강력한 기능을 제공합니다:
  • 다중 음성 모델: ssfm-v30(최신) 및 ssfm-v21 AI 음성 모델 지원
  • 다국어 지원: 영어, 한국어, 스페인어, 일본어, 중국어 등 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
  • 빌더 패턴: 쉬운 요청 구성을 위한 메서드 체이닝 Fluent API
  • Async/Await: 효율적인 비동기 작업을 위해 Tokio 기반으로 구축
  • 타임스탬프 TTS: 자막, 가라오케, 립싱크를 위한 단어·문자 단위 정렬 데이터
  • 스트리밍: 저지연 재생을 위한 실시간 청크 오디오 전송
  • 포괄적인 오류 처리: 패턴 매칭을 지원하는 타입화된 에러 enum

구성

환경 변수 또는 생성자를 통해 API 키를 설정하세요:
use typecast_rust::{TypecastClient, ClientConfig};
use std::time::Duration;

// 환경 변수 사용 (권장)
// export TYPECAST_API_KEY="your-api-key-here"
let client = TypecastClient::from_env()?;

// 또는 직접 전달
let client = TypecastClient::with_api_key("your-api-key-here")?;

// 또는 사용자 정의 구성과 함께
let config = ClientConfig::new("your-api-key-here")
    .base_url("https://api.typecast.ai")
    .timeout(Duration::from_secs(120));

let client = TypecastClient::new(config)?;

환경 파일

프로젝트 루트에 .env 파일을 만드세요:
TYPECAST_API_KEY=your-api-key-here
.env 파일에서 환경 변수를 로드하려면 dotenvy 크레이트를 사용하세요.

고급 사용법

감정 제어 (ssfm-v30)

ssfm-v30은 두 가지 감정 제어 모드를 제공합니다: 프리셋스마트.
AI가 문맥에서 감정을 추론하도록 합니다:
use typecast_rust::{TTSRequest, TTSModel, SmartPrompt};

let request = TTSRequest::new(
    "tc_672c5f5ce59fac2a48faeaee",
    "모든 것이 잘 될 거예요.",
    TTSModel::SsfmV30,
)
.prompt(
    SmartPrompt::new()
        .previous_text("방금 최고의 소식을 들었어요!")  // 선택적 문맥
        .next_text("축하할 수 있어서 너무 기다려져요!")     // 선택적 문맥
);

let response = client.text_to_speech(&request).await?;

오디오 사용자 정의

라우드니스, 피치, 템포 및 출력 형식을 제어합니다:
use typecast_rust::{TTSRequest, TTSModel, Output, AudioFormat};

let request = TTSRequest::new(
    "tc_672c5f5ce59fac2a48faeaee",
    "사용자 정의 오디오 출력!",
    TTSModel::SsfmV30,
)
.output(
    Output::new()
        .target_lufs(-14.0)                 // 범위: -70 ~ 0 (LUFS)
        .audio_pitch(2)                   // 범위: -12 to +12 반음
        .audio_tempo(1.2)                 // 범위: 0.5x to 2.0x
        .audio_format(AudioFormat::Mp3)   // 옵션: Wav, Mp3
)
.seed(42);  // 부호 없는 정수 시드 (재현 가능한 결과)

let response = client.text_to_speech(&request).await?;

fs::write("output.mp3", &response.audio_data)?;
println!("Duration: {:.2}s, Format: {:?}", response.duration, response.format);

음성 탐색 (V2 API)

향상된 메타데이터로 사용 가능한 음성을 나열하고 필터링합니다:
use typecast_rust::{TypecastClient, VoicesV2Filter, TTSModel, Gender, Age};

// 모든 음성 가져오기
let voices = client.get_voices_v2(None).await?;

// 기준으로 필터링
let filter = VoicesV2Filter::new()
    .model(TTSModel::SsfmV30)
    .gender(Gender::Female)
    .age(Age::YoungAdult);

let filtered = client.get_voices_v2(Some(filter)).await?;

// 음성 정보 표시
for voice in &voices {
    println!("ID: {}, Name: {}", voice.voice_id, voice.voice_name);
    println!("Gender: {:?}, Age: {:?}", voice.gender, voice.age);

    for model in &voice.models {
        println!("Model: {:?}, Emotions: {:?}", model.version, model.emotions);
    }

    if let Some(use_cases) = &voice.use_cases {
        println!("Use cases: {}", use_cases.join(", "));
    }
}

// ID로 특정 음성 가져오기
let voice = client.get_voice_v2("tc_672c5f5ce59fac2a48faeaee").await?;
println!("Voice: {} ({:?})", voice.voice_name, voice.gender);

다국어 콘텐츠

SDK는 자동 언어 감지와 함께 37개 언어를 지원합니다:
// 언어 자동 감지 (권장)
let request = TTSRequest::new(
    "tc_672c5f5ce59fac2a48faeaee",
    "こんにちは。お元気ですか。",
    TTSModel::SsfmV30,
);

let response = client.text_to_speech(&request).await?;

// 또는 명시적으로 언어 지정
let korean_request = TTSRequest::new(
    "tc_672c5f5ce59fac2a48faeaee",
    "안녕하세요. 반갑습니다.",
    TTSModel::SsfmV30,
)
.language("kor");  // ISO 639-3 언어 코드

let korean_response = client.text_to_speech(&korean_request).await?;

스트리밍

저지연 재생을 위한 실시간 오디오 청크 스트리밍:
// 원시 PCM 추출 (44바이트 WAV 헤더 건너뛰기)
let mut stream = client.text_to_speech_stream(&request).await?;
let mut first = true;

while let Some(chunk) = stream.next().await {
    let bytes = chunk?;
    let pcm = if first {
        first = false;
        &bytes[44..]  // WAV 헤더 건너뛰기
    } else {
        &bytes
    };
    // pcm은 32000 Hz 16비트 모노 원시 PCM
    // 오디오 출력으로 전달 (예: rodio, cpal)
}
WAV 스트리밍 형식: 32000 Hz, 16비트, 모노 PCM. 첫 번째 청크에 44바이트 WAV 헤더(size = 0xFFFFFFFF)가 포함되며, 이후 청크는 원시 PCM 데이터만 포함합니다. MP3 형식: 320 kbps, 44100 Hz, 각 청크는 독립적으로 디코딩 가능합니다. StreamExt를 사용하려면 futures-util이 필요합니다. 스트리밍 엔드포인트는 volumetarget_lufs를 지원하지 않습니다.

타임스탬프 TTS

text_to_speech_with_timestamps()POST /v1/text-to-speech/with-timestamps를 래핑하며, 오디오와 함께 단어·문자 단위 정렬 데이터를 반환합니다. 가라오케 하이라이트, 자막 생성, 립싱크 애플리케이션에 활용할 수 있습니다.

기본 사용법

use typecast::{TypecastClient, models::TTSRequestWithTimestamps};
use std::fs;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = TypecastClient::new("YOUR_API_KEY");

    let result = client.text_to_speech_with_timestamps(TTSRequestWithTimestamps {
        voice_id: "tc_60e5426de8b95f1d3000d7b5".to_string(),
        text: "Hello. How are you?".to_string(),
        model: "ssfm-v30".to_string(),
        ..Default::default()
    }).await?;

    fs::write("output.wav", result.audio_bytes())?;
    println!("재생 시간: {:.3}초", result.audio_duration);

    for word in &result.words {
        println!("  [{:.3}s – {:.3}s] {}", word.start_time, word.end_time, word.text);
    }
    Ok(())
}

정밀도(Granularity) 설정

Granularity::Word(기본값) 또는 Granularity::Char를 설정해 정렬 단위를 제어합니다.
use typecast::models::Granularity;

// 문자 단위 정렬 — 일본어·중국어에 필수
let result = client.text_to_speech_with_timestamps(TTSRequestWithTimestamps {
    voice_id: "tc_60e5426de8b95f1d3000d7b5".to_string(),
    text: "Hello. How are you?".to_string(),
    model: "ssfm-v30".to_string(),
    granularity: Some(Granularity::Char),
    ..Default::default()
}).await?;

자막 내보내기

let srt = result.to_srt()?;
fs::write("output.srt", srt)?;

let vtt = result.to_vtt()?;
fs::write("output.vtt", vtt)?;
일본어·중국어: 공백 구분자가 없는 언어(jpn, zho)는 단어 단위 세그먼트가 의미를 갖지 않습니다. 해당 언어에는 Granularity::Char를 사용해 문자 단위 정렬 데이터를 얻으세요.

지원 언어

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 오류를 처리할 수 있는 타입화된 에러 enum을 제공합니다:
use typecast_rust::{TypecastClient, TTSRequest, TTSModel, TypecastError};

let request = TTSRequest::new("voice_id", "안녕하세요", TTSModel::SsfmV30);

match client.text_to_speech(&request).await {
    Ok(response) => {
        println!("Success! Duration: {:.2}s", response.duration);
    }
    Err(TypecastError::Unauthorized { detail }) => {
        // 401: 잘못된 API 키
        eprintln!("Invalid API key: {}", detail);
    }
    Err(TypecastError::PaymentRequired { detail }) => {
        // 402: 크레딧 부족
        eprintln!("Insufficient credits: {}", detail);
    }
    Err(TypecastError::NotFound { detail }) => {
        // 404: 리소스를 찾을 수 없음
        eprintln!("Voice not found: {}", detail);
    }
    Err(TypecastError::RateLimited { detail }) => {
        // 429: 요청 한도 초과
        eprintln!("Rate limit exceeded - please try again later: {}", detail);
    }
    Err(TypecastError::ServerError { detail }) => {
        // 500: 서버 오류
        eprintln!("Server error: {}", detail);
    }
    Err(e) => {
        eprintln!("Error: {}", e);
    }
}

오류 유형

오류 변형상태 코드설명
BadRequest400잘못된 요청 매개변수
Unauthorized401잘못되거나 누락된 API 키
PaymentRequired402크레딧 부족
Forbidden403접근 거부
NotFound404리소스를 찾을 수 없음
ValidationError422유효성 검사 오류
RateLimited429요청 한도 초과
ServerError500서버 오류
HttpError-HTTP 클라이언트 오류
JsonError-JSON 직렬화 오류

헬퍼 메서드

if let Err(e) = result {
    if e.is_unauthorized() {
        println!("Please check your API key");
    } else if e.is_rate_limited() {
        println!("Please try again later");
    } else if e.is_server_error() {
        println!("Server issue, please try again later");
    }

    if let Some(code) = e.status_code() {
        println!("HTTP status: {}", code);
    }
}

API 레퍼런스

TypecastClient 메서드

메서드설명
from_env()환경 변수에서 클라이언트 생성
with_api_key(key)API 키로 클라이언트 생성
new(config)사용자 정의 구성으로 클라이언트 생성
text_to_speech(&request)텍스트를 음성 오디오로 변환
get_voices_v2(filter)선택적 필터로 사용 가능한 음성 가져오기
get_voice_v2(voice_id)ID로 특정 음성 가져오기

TTSRequest 필드

필드타입필수설명
voice_idString음성 ID (형식: tc_* 또는 uc_*)
textString합성할 텍스트 (최대 2000자)
modelTTSModelTTS 모델 (SsfmV21 또는 SsfmV30)
languageOption<String>ISO 639-3 코드 (생략 시 자동 감지)
promptOption<TTSPrompt>감정 설정 (Prompt/PresetPrompt/SmartPrompt)
outputOption<Output>오디오 출력 설정
seedOption<u32>재현성을 위한 부호 없는 정수 시드 (≥ 0)

TTSResponse 필드

필드타입설명
audio_dataVec<u8>생성된 오디오 데이터
durationf64오디오 길이 (초)
formatAudioFormat오디오 형식 (Wav 또는 Mp3)

완전한 예제

use typecast_rust::{
    TypecastClient, TTSRequest, TTSModel, PresetPrompt, 
    EmotionPreset, Output, AudioFormat, VoicesV2Filter, Gender,
};
use std::fs;
use std::error::Error;

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    // 클라이언트 초기화
    let client = TypecastClient::from_env()?;
    
    // 음성 탐색
    let filter = VoicesV2Filter::new()
        .model(TTSModel::SsfmV30)
        .gender(Gender::Female);
    
    let voices = client.get_voices_v2(Some(filter)).await?;
    println!("Found {} female voices", voices.len());
    
    // 첫 번째 음성 사용
    if let Some(voice) = voices.first() {
        let request = TTSRequest::new(
            &voice.voice_id,
            "Typecast에 오신 것을 환영합니다! 텍스트 음성 변환 API의 데모입니다.",
            TTSModel::SsfmV30,
        )
        .language("kor")
        .prompt(
            PresetPrompt::new()
                .emotion_preset(EmotionPreset::Happy)
                .emotion_intensity(1.2)
        )
        .output(
            Output::new()
                .target_lufs(-14.0)
                .audio_format(AudioFormat::Mp3)
        );
        
        let response = client.text_to_speech(&request).await?;
        
        fs::write("welcome.mp3", &response.audio_data)?;
        println!("welcome.mp3 saved ({:.2}s)", response.duration);
    }
    
    Ok(())
}