메인 콘텐츠로 건너뛰기
타입캐스트 API를 위한 공식 Dart 및 Flutter SDK입니다. Dart 또는 Flutter 애플리케이션에서 텍스트를 음성으로 변환하고, 스트리밍, 타임스탬프, 캐릭터 조회, 커스텀 보이스 생성 기능을 사용할 수 있습니다.

pub.dev

타입캐스트 Dart SDK

소스 코드

타입캐스트 Dart SDK 소스 코드

설치

pub.dev에서 설치합니다:
dart pub add typecast_dart
Flutter 프로젝트에서는 다음 명령을 사용합니다:
flutter pub add typecast_dart
flutter pub add audioplayers
typecast_dart 0.1.3 이상을 사용하세요. 프로덕션 Flutter 앱에서는 장기 API 키를 배포되는 클라이언트에 직접 포함하지 않는 것을 권장합니다. API 키를 비공개로 유지해야 한다면 백엔드를 통해 요청을 프록시하세요.

빠른 시작

import 'package:audioplayers/audioplayers.dart';
import 'package:typecast_dart/typecast_dart.dart';

final client = TypecastClient(apiKey: 'YOUR_API_KEY');
final player = AudioPlayer();

Future<void> speakAndPlay() async {
  final response = await client.textToSpeech(
    const TtsRequest(
      voiceId: 'tc_672c5f5ce59fac2a48faeaee',
      text: '안녕하세요! 타입캐스트 Dart SDK입니다.',
      model: TtsModel.ssfmV30,
      language: LanguageCode.kor,
      output: Output(audioFormat: AudioFormat.wav),
    ),
  );

  await player.play(BytesSource(response.audioData));
  print('재생 시간: ${response.duration}초, 포맷: ${response.format.value}');
}

Flutter에서 오디오 재생하기

Dart SDK는 생성된 오디오를 바이트 데이터로 반환합니다. Flutter에서는 audioplayers 같은 오디오 재생 패키지에 이 바이트 데이터를 전달해 바로 재생할 수 있습니다. 하나의 AudioPlayer 인스턴스를 공유하고, 각 응답을 메모리에서 바로 재생합니다:
import 'package:audioplayers/audioplayers.dart';
import 'package:typecast_dart/typecast_dart.dart';

final client = TypecastClient(apiKey: 'YOUR_API_KEY');
final player = AudioPlayer();

Future<void> playTts(String text) async {
  final response = await client.textToSpeech(
    TtsRequest(
      voiceId: 'tc_672c5f5ce59fac2a48faeaee',
      text: text,
      model: TtsModel.ssfmV30,
      language: LanguageCode.kor,
      output: const Output(audioFormat: AudioFormat.wav),
    ),
  );

  await player.play(BytesSource(response.audioData));
}
프로덕션 Flutter 앱에서는 장기 API 키를 백엔드에 보관하는 것을 권장합니다. Flutter 앱은 백엔드에서 생성된 오디오 바이트를 받아와도 같은 방식으로 BytesSource에 전달해 재생할 수 있습니다.

기능

  • 다중 음성 모델: ssfm-v30ssfm-v21 AI 음성 모델 지원
  • 다국어 지원: 영어, 한국어, 일본어, 중국어, 스페인어 등 37개 언어
  • 감정 제어: 프리셋 감정 또는 스마트 문맥 인식 추론
  • 오디오 커스터마이징: 음량, 피치, 템포, 출력 포맷 제어
  • 캐릭터 탐색: V2 Voices API로 모델, 성별, 나이, 용도별 필터링
  • 스트리밍: Dart Stream<List<int>>로 스트리밍 TTS 응답 사용
  • 타임스탬프 TTS: SRT/VTT 헬퍼가 포함된 단어·문자 단위 정렬 데이터
  • 즉시 보이스 클로닝: WAV 샘플을 업로드해 커스텀 보이스 ID 생성
  • Dart 및 Flutter 지원: Dart CLI, 서버, Flutter 프로젝트에서 동일 패키지 사용

설정

환경변수 또는 생성자에 API 키를 직접 전달할 수 있습니다:
export TYPECAST_API_KEY="your-api-key-here"
자체 프록시를 통해 요청하는 경우 baseUrl을 프록시 엔드포인트로 설정하고 apiKey를 생략할 수 있습니다. API 키가 비어 있거나 없으면 SDK는 X-API-KEY 헤더를 보내지 않습니다. 기본 Typecast 호스트로 요청할 때는 API 키가 계속 필요합니다.
API 키 없는 프록시
final client = TypecastClient(
  baseUrl: 'https://your-proxy.example.com',
);

고급 사용법

감정 제어 (ssfm-v30)

ssfm-v30은 두 가지 감정 제어 모드를 제공합니다: 프리셋스마트.
AI가 문맥에서 감정을 추론합니다:
final response = await client.textToSpeech(
  const TtsRequest(
    voiceId: 'tc_672c5f5ce59fac2a48faeaee',
    text: '모든 것이 잘 될 거예요.',
    model: TtsModel.ssfmV30,
    prompt: SmartPrompt(
      previousText: '방금 최고의 소식을 들었어요!',
      nextText: '축하하고 싶어요!',
    ),
  ),
);

await player.play(BytesSource(response.audioData));

오디오 커스터마이징

음량, 피치, 템포, 출력 포맷을 제어합니다:
final response = await client.textToSpeech(
  const TtsRequest(
    voiceId: 'tc_672c5f5ce59fac2a48faeaee',
    text: '커스터마이징된 오디오 출력!',
    model: TtsModel.ssfmV30,
    output: Output(
      targetLufs: -14.0,
      audioPitch: 2,
      audioTempo: 1.2,
      audioFormat: AudioFormat.mp3,
    ),
    seed: 42,
  ),
);

await player.play(BytesSource(response.audioData));

파일로 바로 생성하기

generateToFile은 음성 합성과 파일 저장을 한 번에 처리합니다. model은 기본값으로 ssfm-v30을 사용하고, .mp3 또는 .wav 확장자로 출력 형식을 결정합니다.
await client.generateToFile(
  'output.mp3',
  GenerateToFileRequest(
    text: '안녕하세요, 타입캐스트입니다.',
    voiceId: 'tc_672c5f5ce59fac2a48faeaee', // voice_id는 https://typecast.ai/developers/api/voices 에서 확인하세요.
  ),
);

캐릭터 탐색 (V2 API)

향상된 메타데이터와 함께 사용 가능한 캐릭터를 조회합니다:
final voices = await client.getVoicesV2();

final filtered = await client.getVoicesV2(
  const VoicesV2Filter(
    model: TtsModel.ssfmV30,
    gender: 'female',
    age: 'young_adult',
  ),
);

for (final voice in voices) {
  print('ID: ${voice.voiceId}, 이름: ${voice.voiceName}');
  print('성별: ${voice.gender}, 나이: ${voice.age}');
}

final voice = await client.getVoiceV2('tc_672c5f5ce59fac2a48faeaee');
print(voice.voiceName);

스트리밍

Dart 스트림으로 오디오를 수신하고 파일 저장 없이 재생합니다:
import 'dart:typed_data';

final stream = await client.textToSpeechStream(
  const TtsRequestStream(
    voiceId: 'tc_672c5f5ce59fac2a48faeaee',
    text: '이 텍스트를 실시간으로 오디오로 스트리밍합니다.',
    model: TtsModel.ssfmV30,
    output: OutputStream(audioFormat: AudioFormat.wav),
  ),
);

final audioBytes = <int>[];
await for (final chunk in stream) {
  audioBytes.addAll(chunk);
}

await player.play(BytesSource(Uint8List.fromList(audioBytes)));
WAV 스트리밍 형식: 32000 Hz, 16비트, 모노 PCM. 첫 번째 청크에 44바이트 WAV 헤더(size = 0xFFFFFFFF)가 포함되며, 이후 청크는 원시 PCM 데이터만 포함합니다. 위 예제는 파일 저장을 피하고 전체 스트림을 메모리에서 재생합니다. 진짜 저지연 청크 단위 재생이 필요하다면 audioplayers 대신 PCM 청크를 직접 공급할 수 있는 스트리밍 오디오 엔진을 사용하세요.

타임스탬프 TTS

textToSpeechWithTimestamps()POST /v1/text-to-speech/with-timestamps를 래핑하며, 오디오와 함께 단어·문자 단위 정렬 데이터를 반환합니다.
final result = await client.textToSpeechWithTimestamps(
  const TtsRequest(
    voiceId: 'tc_60e5426de8b95f1d3000d7b5',
    text: '안녕하세요. 반갑습니다.',
    model: TtsModel.ssfmV30,
    language: LanguageCode.kor,
  ),
);

await player.play(BytesSource(result.audioBytes()));
print('재생 시간: ${result.audioDuration}초');

for (final word in result.words) {
  print('[${word.startTime}초 - ${word.endTime}초] ${word.word}');
}

정밀도(Granularity) 설정

granularity: 'word'(기본값) 또는 granularity: 'char'를 설정해 정렬 단위를 제어합니다.
final result = await client.textToSpeechWithTimestamps(
  const TtsRequest(
    voiceId: 'tc_60e5426de8b95f1d3000d7b5',
    text: '안녕하세요. 반갑습니다.',
    model: TtsModel.ssfmV30,
    language: LanguageCode.kor,
  ),
  granularity: 'char',
);

자막 내보내기

await File('output.srt').writeAsString(result.toSrt());
await File('output.vtt').writeAsString(result.toVtt());

즉시 보이스 클로닝

짧은 WAV 샘플을 업로드해 커스텀 보이스를 생성합니다:
final voice = await client.cloneVoice(
  audio: await File('sample.wav').readAsBytes(),
  filename: 'sample.wav',
  name: 'My Voice',
  model: TtsModel.ssfmV30,
);

print('커스텀 보이스 ID: ${voice.voiceId}');
보이스 클로닝 오디오는 25 MB 이하여야 하며, 커스텀 보이스 이름은 1-30자여야 합니다.