Fish TTS API를 사용하여 앱에 비동기 텍스트 음성 변환(Text-to-Speech)을 추가하는 방법
요약
Ace Data Cloud의 Fish TTS API를 사용하여 앱에 비동기 텍스트 음성 변환 기능을 통합하는 방법을 설명합니다. 기존 Fish Audio API와 호환되는 요청 형식을 유지하면서 인증 방식과 엔드포인트 변경을 통해 효율적인 오디오 생성 워크플로를 구축할 수 있습니다.
핵심 포인트
- Fish Audio API와 호환되는 JSON 요청 형식 지원
- Ace Data Cloud 베어러 토큰을 통한 인증 방식 사용
- 생성된 오디오를 즉시 활용 가능한 audio_url 반환
- callback_url을 통한 비동기 확장 기능 제공
- 기존 Fish Audio 기반 앱의 손쉬운 마이그레이션 가능
긴 텍스트 음성 변환 (Text-to-speech) 작업은 프로토타입을 만들기는 쉽지만, 오디오가 생성되는 동안 앱이 요청을 계속 유지해야 하는 프로덕션 환경에서는 어색한 상황이 발생할 수 있습니다.
할 수 있는 것
Ace Data Cloud의 Fish TTS 엔드포인트는 Fish Audio 텍스트 음성 변환 (Text-to-speech) API와 호환되는 요청 형식을 유지하면서 텍스트를 오디오로 변환할 수 있는 간단한 방법을 제공합니다. 실제로 이는 익숙한 JSON 본문을 보내고, Ace Data Cloud 베어러 토큰 (Bearer token)으로 인증하며, 앱이 재생하거나 다운로드하거나 워크플로의 다음 단계로 전달할 수 있는 audio_url을 받을 수 있음을 의미합니다.
기본 요청은 의도적으로 작게 구성되었습니다:
- Base URL / 엔드포인트 (endpoint):
POST https://api.acedata.cloud/fish/tts - 인증 (Authentication):
Authorization: Bearer {token} - 콘텐츠 타입 (Content type):
application/json - 모델 헤더 (Model header):
model: s2-pro또는model: s1(s2-pro가 기본값) - 필수 본문 필드 (Required body field):
text - 선택적 음성 필드 (Optional voice field):
reference_id - 선택적 출력 필드 (Optional output fields):
format,sample_rate,mp3_bitrate - 비동기 확장 (Async extension):
callback_url - 전형적인 결과 필드 (Typical result field):
audio_url
이를 통해 이 엔드포인트는 제품 내레이션, 음성 메모, 생성된 학습 콘텐츠, 내부 도구, 또는 출력이 단순한 브라우저 측 데모가 아닌 실제 오디오 파일이 되어야 하는 모든 워크플로에 유용하게 사용될 수 있습니다.
작동 방식
동기식 (Synchronous) 버전은 가장 작고 유용한 호출 방식입니다. 텍스트를 보내고, 토큰을 포함하며, 요청 헤더에서 모델을 선택한 다음 반환된 audio_url을 읽으면 됩니다:
curl -X POST 'https://api.acedata.cloud/fish/tts' \
-H 'accept: application/json' \
-H 'authorization: Bearer {token}' \
...
성공적인 응답은 오디오 파일 URL을 반환합니다:
{
"audio_url": "https://platform.r2.fish.audio/task/8a72ff9840234006a9f74cb2fa04f978.mp3"
}
만약 귀하의 앱이 이미 Fish Audio의 공식 요청 본문(request body)을 기준으로 작성되어 있다면, 중요한 마이그레이션(migration) 세부 사항은 본문 구조가 동일하게 유지된다는 점입니다. 주요 변경 사항은 인증(authentication)입니다. Ace Data Cloud에서 제공하는 토큰을 사용하여 Authorization: Bearer {token} 형식을 사용하세요. 엔드포인트(endpoint)는 또한 text, reference_id, references, prosody, format, sample_rate, mp3_bitrate, chunk_length, temperature, top_p와 같은 Fish 요청 필드들을 수용합니다.
복제된 목소리 또는 명시적인 오디오 형식 추가
많은 실제 앱에서 단순한 TTS(Text-to-Speech)는 첫 번째 단계에 불과합니다. 귀하는 알려진 목소리, 예측 가능한 파일 유형, 또는 다운스트림(downstream) 미디어 파이프라인을 위한 고정된 샘플 레이트(sample rate)를 원할 수 있습니다. 엔드포인트는 JSON 본문에서 reference_id, format, sample_rate를 지원합니다:
curl -X POST 'https://api.acedata.cloud/fish/tts' \
-H 'accept: application/json' \
-H 'authorization: Bearer {token}' \
...
이것은 생성된 오디오 자산을 저장하는 서비스에 TTS를 통합할 때 제가 사용할 형태입니다. 귀하의 백엔드(backend)는 텍스트를 제출하고, 결과물인 audio_url을 저장하며, 이를 원래의 콘텐츠 레코드와 연결할 수 있습니다.
긴 작업에는 콜백(callback) 사용
짧은 문구의 경우 직접적인 요청(direct request)으로도 충분합니다. 하지만 긴 텍스트의 경우, HTTP 연결을 계속 열어두는 것은 시스템의 나머지 부분을 더 취약하게 만들 수 있습니다. 워커(worker)가 타임아웃(time out)되거나, 클라이언트가 재시도(retry)를 하게 되어 중복 작업에 대한 추론이 어려워질 수 있기 때문입니다.
Ace Data Cloud는 callback_url을 통해 비동기 콜백(async callback) 확장 기능을 추가합니다. 이 필드를 포함하면 API는 즉시 task_id와 started_at 타임스탬프(timestamp)를 반환합니다. 이후 생성이 완료되면, 최종 페이로드(payload)가 동일한 task_id 및 생성된 audio_url과 함께 귀하의 콜백 URL로 포스트(post)됩니다.
curl -X POST 'https://api.acedata.cloud/fish/tts' \
-H 'accept: application/json' \
-H 'authorization: Bearer {token}' \
...
즉각적인 응답:
{
"task_id": "2725a2d3-f87e-4905-9c53-9988d5a7b2f5",
"started_at": "2025-05-09T12:34:56.789Z"
...
콜백 페이로드:
{
"task_id": "2725a2d3-f87e-4905-9c53-9988d5a7b2f5",
"audio_url": "https://platform.r2.fish.audio/task/b627c2f7d38a4083a837570ba6d0962f.mp3"
...
실제 운영 환경의 앱(production app)에서는 첫 번째 응답이 도착하는 즉시 task_id를 저장하세요. 웹훅(webhook)이 콜백을 받으면, 대기 중인 작업을 조회하여 audio_url을 저장하고 해당 작업을 완료 상태로 표시합니다. 만약 능동적인 상태 확인(active status checks)이 필요하다면, 문서에 명시된 대로 task_id를 Fish Tasks API와 함께 사용할 수도 있습니다.
워크플로의 일부로서 에러 처리하기
TTS를 단순히 실행 후 잊어버리는(fire-and-forget) 부수 효과(side effect)로 취급하지 마세요. 엔드포인트(endpoint)는 상위 HTTP 상태 동작을 유지하며 통합된 플랫폼 에러 형식을 반환합니다. 처리해야 할 일반적인 케이스는 400 token_mismatched, 400 api_not_implemented, 401 invalid_token, 429 too_many_requests, 그리고 500 api_error입니다.
전형적인 에러 응답은 다음과 같습니다:
{
"success": false,
"error": {
...
로그에 trace_id를 남겨두세요. 이는 나중에 미디어 생성 작업이 실패했을 때 디버깅 시간을 단축해 주는 작은 디테일입니다.
실용적인 통합 패턴
개발자 친화적인 구현을 위해, 저는 자체 데이터베이스에 queued(대기), processing(처리 중), ready(완료)라는 세 가지 상태를 두는 것으로 시작할 것입니다. 사용자가 텍스트를 제출하면 앱은 행(row)을 생성하고, callback_url과 함께 POST /fish/tts를 호출하며, 반환된 task_id를 저장한 뒤 해당 행을 processing 상태로 변경합니다. 웹훅은 페이로드(payload)를 검증하고, audio_url을 저장한 뒤 행을 ready 상태로 표시합니다.
이 방식은 UI의 응답성을 유지하며 사용자가 긴 요청을 기다리게 만드는 것을 방지합니다. 또한 깔끔한 재시도 경계(retry boundary)를 제공합니다. 즉, 초기 요청이 실패하면 작업 제출을 재시도하고, 자체 서버에 일시적인 문제가 발생하면 웹훅 처리를 재시도할 수 있습니다.
정확한 호환성 참고 사항과 필드 목록을 확인하려면 Ace Data Cloud의 전체 Fish TTS 통합 가이드를 읽어보세요: https://platform.acedata.cloud/documents/fish-tts-integration
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기