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)?;
자체 프록시를 통해 요청하는 경우 base_url을 프록시 엔드포인트로 설정하고 API 키를 생략할 수 있습니다. API 키가 비어 있거나 없으면 SDK는 X-API-KEY 헤더를 보내지 않습니다. 기본 Typecast 호스트로 요청할 때는 API 키가 계속 필요합니다.
API 키 없는 프록시
let config = ClientConfig::new("") .base_url("https://your-proxy.example.com");let client = TypecastClient::new(config)?;
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, PresetPrompt, EmotionPreset};let request = TTSRequest::new( "tc_672c5f5ce59fac2a48faeaee", "이 기능들을 보여드리게 되어 정말 기대됩니다!", TTSModel::SsfmV30,).prompt( PresetPrompt::new() .emotion_preset(EmotionPreset::Happy) // Normal, Happy, Sad, Angry, Whisper, ToneUp, ToneDown .emotion_intensity(1.5) // 범위: 0.0 ~ 2.0);let response = client.text_to_speech(&request).await?;
한 voice로 읽는 문장 안에 쉼만 넣고 싶다면 텍스트에 pause markup을 직접 작성합니다. <|5s|>, <|1s|>, <|0.3s|>, <|0.34413s|>처럼 쓰며 값은 초 단위이고 반드시 s로 끝납니다. 별도 pause 함수를 호출하지 않아도 텍스트만 보고 쉼 위치를 확인할 수 있습니다.
let audio = client .compose_speech() .defaults(ComposerSettings::new().voice_id("tc_672c5f5ce59fac2a48faeaee").model(TtsModel::SsfmV30)) .say("안녕하세요<|5s|>반갑습니다<|1s|>오늘<|2s|>날씨는 어떤 것 같으세요?") .generate() .await?;
한 파일 안에서 서로 다른 voice나 구간별 pitch, tempo, prompt, seed 같은 옵션을 조합해야 할 때 사용합니다. composer는 각 구간을 WAV로 생성하고 앞뒤 무음 PCM 샘플을 trim한 뒤 합성합니다. MP3가 필요하면 먼저 WAV를 생성한 다음 앱 또는 서버 파이프라인에서 변환하세요.
use typecast_rust::{ComposerSettings, Output, TTSModel, TypecastClient};#[tokio::main]async fn main() -> Result<(), Box<dyn std::error::Error>> { let client = TypecastClient::new("YOUR_API_KEY")?; let audio = client .compose_speech() .defaults(ComposerSettings::new().voice_id("tc_672c5f5ce59fac2a48faeaee").model(TTSModel::SSFM_V30)) .say("Hello there") .pause(5.0) .say_with( "Nice to meet you", ComposerSettings::new().voice_id("tc_60e5426de8b95f1d3000d7b5").output(Output { audio_pitch: Some(2), ..Default::default() }), ) .say("Today") .pause(2) .say("How does the weather feel?") .generate() .await?; std::fs::write("conversation.wav", audio.audio_data)?; Ok(())}
text_to_speech_with_timestamps()는 POST /v1/text-to-speech/with-timestamps를 래핑하며, 오디오와 함께 단어·문자 단위 정렬 데이터를 반환합니다. 가라오케 하이라이트, 자막 생성, 립싱크 애플리케이션에 활용할 수 있습니다.
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?;
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); }}