> ## 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.

# Ruby

타입캐스트 [API](https://studio.typecast.ai/developers/api)를 위한 공식 Ruby SDK입니다. AI 음성을 사용해 텍스트를 자연스러운 음성으로 변환하고, 타임스탬프, 보이스 조회, 커스텀 보이스 생성 기능을 사용할 수 있습니다.

Ruby SDK는 런타임 의존성 없이 Ruby 표준 라이브러리만 사용하며 Ruby 2.6 이상을 지원합니다.

<CardGroup cols={2}>
<Card title="RubyGems" icon="gem" href="https://rubygems.org/gems/typecast-ruby">
타입캐스트 Ruby SDK
</Card>

<Card title="소스 코드" icon="github" href="https://github.com/neosapience/typecast-sdk/tree/main/typecast-ruby">
타입캐스트 Ruby SDK 소스 코드
</Card>
</CardGroup>

## 설치

RubyGems에서 설치합니다:

```bash
gem install typecast-ruby
```

또는 Gemfile에 추가합니다:

```ruby
gem "typecast-ruby", "~> 0.1.11"
```

<Warning>
최신 등록 버전은 RubyGems 기준 **0.1.11**입니다. **Ruby 2.6 이상**이 필요합니다. `ruby -v`로 버전을 확인하세요.
</Warning>

## 빠른 시작

```ruby
require "typecast"

client = Typecast::Client.new(api_key: ENV["TYPECAST_API_KEY"])

response = client.text_to_speech(
  Typecast::Models::TTSRequest.new(
    voice_id: "tc_672c5f5ce59fac2a48faeaee",
    text: "안녕하세요! 타입캐스트 Ruby SDK입니다.",
    model: Typecast::Models::TTS_MODEL_V30,
    language: "kor",
    output: Typecast::Models::Output.new(audio_format: "wav")
  )
)

File.binwrite("output.wav", response.audio_data)
puts "재생 시간: #{response.duration}초, 포맷: #{response.format}"
```

## 기능

- **다중 음성 모델**: `ssfm-v30` 및 `ssfm-v21` AI 음성 모델 지원
- **다국어 지원**: 영어, 한국어, 일본어, 중국어, 스페인어 등 35+개 언어
- **감정 제어**: 프리셋 감정 또는 스마트 문맥 인식 추론
- **오디오 커스터마이징**: 음량, 피치, 템포, 출력 포맷 제어
- **보이스 탐색**: V2 Voices API로 모델, 성별, 나이, 용도별 필터링
- **스트리밍 엔드포인트**: Ruby에서 스트리밍 TTS 응답 사용
- **타임스탬프 TTS**: SRT/VTT 헬퍼가 포함된 단어·문자 단위 정렬 데이터
- **즉시 보이스 클로닝**: WAV 샘플을 업로드해 커스텀 보이스 ID 생성
- **런타임 의존성 없음**: Ruby 표준 라이브러리 `net/http` 기반

## 보이스 추천

원하는 스타일은 알지만 정확한 `voice_id`를 모를 때 `recommend_voices`를 사용합니다.

```ruby
voices = client.recommend_voices(
  "warm female voice for a product tutorial",
  count: 3
)

voices.each do |voice|
  puts "#{voice.voice_id} #{voice.voice_name} #{voice.score}"
end
```

추천 결과에는 `voice_id`, `voice_name`, `score`만 포함됩니다. 최신 보이스 메타데이터가 필요하면 `get_voice_v3` 또는 `get_voices_v3`로 조회하세요.

## 설정

환경변수 또는 생성자에 API 키를 직접 전달할 수 있습니다:

<CodeGroup>

```bash 환경변수
export TYPECAST_API_KEY="your-api-key-here"
```

```ruby 환경변수에서 읽기
require "typecast"

client = Typecast::Client.new(
  api_key: ENV["TYPECAST_API_KEY"]
)
```

```ruby 직접 전달
require "typecast"

client = Typecast::Client.new(
  api_key: "your-api-key-here"
)
```

</CodeGroup>

<Info>
자체 프록시를 통해 요청하는 경우 `base_url`을 프록시 엔드포인트로 설정하고 `api_key`를 생략할 수 있습니다. API 키가 비어 있거나 없으면 SDK는 `X-API-KEY` 헤더를 보내지 않습니다. 기본 Typecast 호스트로 요청할 때는 API 키가 계속 필요합니다.
</Info>

```ruby API 키 없는 프록시
client = Typecast::Client.new(
  base_url: "https://your-proxy.example.com"
)
```

API 호스트와 HTTP 타임아웃도 설정할 수 있습니다:

```ruby
client = Typecast::Client.new(
  api_key: ENV["TYPECAST_API_KEY"],
  base_url: "https://api.typecast.ai",
  open_timeout: 10,
  read_timeout: 30
)
```

## 고급 사용법

### 감정 제어 (ssfm-v30)

ssfm-v30은 두 가지 감정 제어 모드를 제공합니다: **프리셋** 및 **스마트**.

<Tabs>
  <Tab title="스마트 모드">
    AI가 문맥에서 감정을 추론합니다:

    ```ruby
    response = client.text_to_speech(
      Typecast::Models::TTSRequest.new(
        voice_id: "tc_672c5f5ce59fac2a48faeaee",
        text: "모든 것이 잘 될 거예요.",
        model: Typecast::Models::TTS_MODEL_V30,
        prompt: Typecast::Models::SmartPrompt.new(
          previous_text: "방금 최고의 소식을 들었어요!",
          next_text: "축하하고 싶어요!"
        )
      )
    )
    ```
  </Tab>

  <Tab title="프리셋 모드">
    프리셋 값으로 감정을 명시적으로 설정합니다:

    ```ruby
    response = client.text_to_speech(
      Typecast::Models::TTSRequest.new(
        voice_id: "tc_672c5f5ce59fac2a48faeaee",
        text: "이 기능들을 보여드리게 되어 정말 기쁩니다!",
        model: Typecast::Models::TTS_MODEL_V30,
        prompt: Typecast::Models::PresetPrompt.new(
          emotion_preset: "happy",
          emotion_intensity: 1.5
        )
      )
    )
    ```
  </Tab>
</Tabs>

### 오디오 커스터마이징

음량, 피치, 템포, 출력 포맷을 제어합니다:

```ruby
response = client.text_to_speech(
  Typecast::Models::TTSRequest.new(
    voice_id: "tc_672c5f5ce59fac2a48faeaee",
    text: "커스터마이징된 오디오 출력!",
    model: Typecast::Models::TTS_MODEL_V30,
    output: Typecast::Models::Output.new(
      target_lufs: -14.0,
      audio_pitch: 2,
      audio_tempo: 1.2,
      audio_format: Typecast::Models::AUDIO_MP3
    ),
  )
)

File.binwrite("output.mp3", response.audio_data)
```

### 파일로 바로 생성하기

`generate_to_file`은 음성 합성과 파일 저장을 한 번에 처리합니다. `model`은 기본값으로 `ssfm-v30`을 사용하고, `.mp3` 또는 `.wav` 확장자로 출력 형식을 결정합니다.

```ruby
client.generate_to_file(
  "hello.mp3",
  text: "안녕하세요, 타입캐스트입니다.",
  voice_id: "tc_672c5f5ce59fac2a48faeaee" # voice_id는 https://studio.typecast.ai/developers/api/voices 에서 확인하세요.
)
```

### 텍스트만으로 쉼 표현

한 voice로 읽는 문장 안에 쉼만 넣고 싶다면 텍스트에 pause markup을 직접 작성합니다. `<|5s|>`, `<|1s|>`, `<|0.3s|>`, `<|0.34413s|>`처럼 쓰며 값은 초 단위이고 반드시 `s`로 끝납니다. 별도 pause 함수를 호출하지 않아도 텍스트만 보고 쉼 위치를 확인할 수 있습니다.

```ruby
audio = client
  .compose_speech
  .defaults(voice_id: "tc_672c5f5ce59fac2a48faeaee", model: "ssfm-v30")
  .say("안녕하세요<|5s|>반갑습니다<|1s|>오늘<|2s|>날씨는 어떤 것 같으세요?")
  .generate
```

### 다중 화자 합성

한 파일 안에서 서로 다른 voice나 구간별 pitch, tempo, prompt 같은 옵션을 조합해야 할 때 사용합니다. composer는 세그먼트를 `POST /v1/text-to-speech/compose`로 보내며 WAV 또는 MP3를 직접 반환합니다. 무음 제거는 TTS 세그먼트에 명시적으로 설정하고, 명시적인 쉼은 유지됩니다.

```ruby
audio = client
  .compose_speech
  .defaults(voice_id: "tc_672c5f5ce59fac2a48faeaee", model: Typecast::Models::TTS_MODEL_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

File.binwrite("conversation.wav", audio.audio_data)
```

### 보이스 탐색 (V3 API)

향상된 메타데이터와 함께 사용 가능한 보이스를 조회합니다:

```ruby
voices = client.get_voices_v3

filtered = client.get_voices_v3(
  Typecast::Models::VoicesV2Filter.new(
    model: Typecast::Models::TTS_MODEL_V30,
    gender: "female",
    age: "young_adult"
  )
)

voices.each do |voice|
  puts "ID: #{voice.voice_id}, 이름: #{voice.voice_name.kor}"
  puts "성별: #{voice.gender}, 나이: #{voice.age}"
end

voice = client.get_voice_v3("tc_672c5f5ce59fac2a48faeaee")
puts voice.voice_name.kor
```

### 스트리밍

`text_to_speech_stream()`으로 스트리밍 엔드포인트를 호출합니다:

```ruby
client.text_to_speech_stream(
  Typecast::Models::TTSRequestStream.new(
    voice_id: "tc_672c5f5ce59fac2a48faeaee",
    text: "이 텍스트를 오디오로 스트리밍합니다.",
    model: Typecast::Models::TTS_MODEL_V30,
    output: Typecast::Models::OutputStream.new(audio_format: "wav")
  )
) do |audio|
  File.binwrite("stream.wav", audio)
end
```

<Note>
**WAV 스트리밍 형식:** 32000 Hz, 16비트, 모노 PCM. 첫 번째 청크에 44바이트 WAV 헤더(size = `0xFFFFFFFF`)가 포함되며, 이후 청크는 원시 PCM 데이터만 포함합니다.
</Note>

## 타임스탬프 TTS

`text_to_speech_with_timestamps()`는 `POST /v1/text-to-speech/with-timestamps`를 래핑하며, 오디오와 함께 단어·문자 단위 정렬 데이터를 반환합니다.

```ruby
result = client.text_to_speech_with_timestamps(
  Typecast::Models::TTSRequest.new(
    voice_id: "tc_60e5426de8b95f1d3000d7b5",
    text: "안녕하세요. 반갑습니다.",
    model: Typecast::Models::TTS_MODEL_V30,
    language: "kor"
  )
)

result.save_audio("output.wav")
puts "재생 시간: #{result.audio_duration}초"

result.words.each do |word|
  puts "[#{word.start_time}초 - #{word.end_time}초] #{word.word}"
end
```

### 정밀도(Granularity) 설정

`granularity: "word"`(기본값) 또는 `granularity: "char"`를 설정해 정렬 단위를 제어합니다.

```ruby
result = client.text_to_speech_with_timestamps(
  Typecast::Models::TTSRequest.new(
    voice_id: "tc_60e5426de8b95f1d3000d7b5",
    text: "안녕하세요. 반갑습니다.",
    model: Typecast::Models::TTS_MODEL_V30,
    language: "kor"
  ),
  granularity: "char"
)
```

### 자막 내보내기

```ruby
File.write("output.srt", result.to_srt)
File.write("output.vtt", result.to_vtt)
```

## 즉시 보이스 클로닝

짧은 WAV 샘플을 업로드해 커스텀 보이스를 생성합니다:

```ruby
voice = client.clone_voice(
  audio: File.binread("sample.wav"),
  filename: "sample.wav",
  name: "My Voice",
  model: Typecast::Models::TTS_MODEL_V30
)

puts "커스텀 보이스 ID: #{voice.voice_id}"
```

<Warning>
보이스 클로닝 오디오는 **25 MB 이하**여야 하며, 커스텀 보이스 이름은 **1-30자**여야 합니다.
</Warning>

## 무음 길이 조절

이 기능은 **0.1.11 이상**에서 지원합니다.

`remove_silence_ms`는 제거할 시간이 아니라 **남길 무음 길이**를 지정합니다. `0`부터 `1000`ms까지의 정수를 사용하세요. `0`은 검출된 무음을 제거하며, 생략하거나 `null`을 지정하면 지정 길이에 따른 무음 제거를 적용하지 않습니다.

일반·스트리밍·타임스탬프 TTS는 `output.remove_silence_ms`, Compose는 각 `tts` 세그먼트의 `segments[].output.remove_silence_ms`로 전달합니다. 반환 타임스탬프는 처리 후 오디오를 기준으로 하며, 명시적인 `pause` 세그먼트는 유지됩니다.

스트리밍의 기본 앞부분 무음 트림은 별개입니다. 특히 `0`처럼 작은 값에서는 재생 가능한 청크 수신에 간격이 생길 수 있으므로 충분한 재생 버퍼를 확보하고 실제 콘텐츠로 확인하세요.

아래 출력 설정을 해당 요청의 `output`에 전달하세요. 스트리밍은 스트리밍 전용 출력 타입을 사용합니다.

```ruby
output = Typecast::Models::Output.new(remove_silence_ms: 300)
stream_output = Typecast::Models::OutputStream.new(remove_silence_ms: 300)
```
