TAS — 텍스트와 음성, 양방향 (Speakee API)
하나의 스크립트가 양방향을 처리합니다:
- 텍스트 → 음성 (TTS): 40개 이상의 언어, 100개 이상의 음성, 사용자 정의 음성 UID, 긴 텍스트 분할, 다중 음성 대화 모드, ffmpeg 병합, 오디오 QA.
- 음성 → 텍스트 (STT): 모든 오디오/비디오 파일을 텍스트, 단어 타임스탬프, SRT/WebVTT 자막으로 변환하며, 긴 녹음 파일을 자동으로 분할합니다.
모든 작업은 번들 스크립트로 수행됩니다 — 절대 인라인으로 재구현하지 말고 아무것도 설치하지 마세요 (Whisper, torch, faster-whisper, pip 없음):
<스킬 기본 디렉토리>/scripts/tas.py
일반적인 설치 위치:
~/.config/opencode/skills/tas/scripts/tas.py (opencode),
~/.claude/skills/tas/scripts/tas.py (Claude Code),
~/.agents/skills/tas/scripts/tas.py (skills CLI, npx skills add).
스킬 이름은 tas 입니다 — tts가 아닌 tas 이름으로 로드하세요.
양보할 수 없는 규칙 (모든 요청에 적용)
- 번들 스크립트를 사용하세요. TTS나 STT를 위해 임시 curl/python 코드를 사용하지 마세요.
- 아무것도 설치하지 마세요.
pip install faster-whisper,pip install whisper,pip install torch를 실행하거나 모델을 다운로드하지 마세요. 스크립트는 Python 표준 라이브러리만으로 Speakee API를 통해 STT를 수행합니다 — 로컬 모델, 로컬 다운로드, pip가 전혀 필요 없습니다. - 전달하기 전에 검증하세요.
tts와conversation은 자동으로 오디오 QA를 실행합니다.QA: FAIL은 반드시 수정하고 절대 그대로 전달하지 마세요. - 결과를 보고하세요: 최종 경로, 길이, 크기, QA 상태(TTS); 최종 SRT/VTT/텍스트 경로와 큐 개수(STT).
- 항상 사전 점검하세요. 언어, 모델, 음성은 모든 요청 전에 검증됩니다. 추측한 음성을 보내지 마세요.
- 사용자가 다른 요청을 하지 않는 한 캐시를 켜두세요. 재실행 속도를 높이고 실패한 대화를 재개합니다.
- 절대 음성 이름을 추측하지 마세요.
voices/suggest로 확인하거나 UUID를 전달하세요. - 무료 API를 존중하세요: 기본
--workers 4; HTTP 429 오류 시 값을 낮추세요. - 스크립트가 텍스트를 정규화하도록 두세요. 마크다운, URL, HTML, 이모지는 기본적으로 제거됩니다. 사용자가 문자 그대로의 텍스트를 원할 때만
--raw를 사용하세요. - 긴 텍스트를 미리 분할하지 마세요. 스크립트가 문장 경계에서 자동으로 분할하고 병합합니다.
- STT에 언어가 알려진 경우 항상
-l <코드>를 전달하세요. 자동 감지는 신뢰할 수 없습니다(Whisper가 벵골어/구자라트어를 혼동합니다). 정확한 벵골어 처리를 위해서는-l bn이 필요합니다. - 다른 도구나 스크립트가 결과를 소비할 때는
--json을 사용하세요.
명령어
| 명령어 | 용도 |
|---|---|
tts | 하나의 텍스트 블록 합성(TTS) |
uid | 사용자 정의 음성 UID로 합성(language=uid) |
conversation | 여러 화자 대화 → 하나로 병합된 검증된 MP3 |
stt | 오디오/비디오 파일 받아쓰기 → 텍스트 (+ 선택적 SRT/VTT) |
transcribe | stt의 별칭 |
subtitle | 받아쓰기 및 SRT 생성 |
verify | 모든 파일의 오디오 QA 실행 |
voices -l <코드> | 특정 언어의 음성 목록 표시 |
suggest -l <코드> | 추천 표시와 함께 음성 목록 표시 |
presets | 내장 음성 프리셋 목록 |
languages | 지원 언어 목록 |
models | 모델 목록 (sonic-3.5 기본값) |
cache-clear | 합성 캐시 삭제 |
워크플로 A — 텍스트를 음성으로 (TTS)
1단계 — 범위 설정
식별: 언어(또는 자동 감지), 어조(뉴스 / 스토리 / 어시스턴트 / 오디오북), 단일 화자 또는 대화, 원하는 출력 경로, 자막(--srt) 또는 메타데이터(--title/--artist) 필요 여부.
2단계 — 언어와 음성 선택
python3 "$S" languages # 43개 코드
python3 "$S" suggest -l bn # 추천 음성 우선
python3 "$S" presets # 큐레이션된 음성 세트
사용자에게 사용자 정의 음성 UID가 있으면 uid 모드를 사용하세요. 그렇지 않으면 기본값보다 프리셋 또는 추천 음성을 선호하세요.
3단계 — 합성
단일 화자:
python3 "$S" tts "당신의 텍스트" -l ko -o out.mp3
python3 "$S" tts --text-file article.md -l en --preset news -o article.mp3
대화:
python3 "$S" conversation dialog.txt -l bn \
--map "사람=Nayem,AI=Pooja - Everyday Assistant" \
--loudnorm --srt dialog.srt -o dialog.mp3
길거나 비용이 많이 드는 실행의 경우 먼저 --dry-run을 사용하세요.
4단계 — 검증
QA가 자동으로 실행됩니다. 파일을 다시 확인하려면:
python3 "$S" verify out.mp3
검사 항목: 디코딩, 길이, 통합 라우드니스(ebur128), 실제 피크/클리핑, 앞/뒤/내부 무음. 종료 코드 5는 실패를 의미합니다.
5단계 — 전달
보고:
out.mp3 — 2.8초, 0.04 MB, QA 통과 (-18.9 LUFS, 피크 -4.2 dBFS)
요청하지 않으면 원시 JSON을 붙여넣지 마세요.
6단계 — 재사용
재실행은 캐시를 사용합니다(~/.cache/speakee-tas). --force를 사용하여 재생성하고, cache-clear를 사용하여 삭제하세요.
워크플로 B — 음성을 텍스트로 (STT)
사용자가 오디오 또는 비디오 파일을 가지고 있고 대본, 자막, 캡션 또는 SRT를 원할 때 사용하세요. Whisper를 설치하지 마세요 — 번들 스크립트가 Speakee /api/stt 엔드포인트를 직접 호출합니다.
1단계 — 파일 확인
python3 "$S" verify /path/to/audio.mp3 # 선택 사항: 디코딩 확인
ls -la /path/to/audio.mp3
2단계 — 언어 선택
# 자동 감지 (신뢰할 수 없음 — Whisper가 벵골어/구자라트어 혼동):
python3 "$S" stt audio.mp3
# 언어를 알 때는 항상 명시적 언어를 선호:
python3 "$S" stt audio.mp3 -l bn
중요: 올바른 문자 체계를 위해 -l <코드>를 전달하세요. 벵골어는 -l bn을 사용하세요. 자동 감지는 벵골어 오디오에 대해 구자라트어를 반환합니다. 낮은 신뢰도(< 0.5) 경고는 감지된 언어가 틀렸을 가능성이 높음을 의미합니다.
3단계 — 받아쓰기 + 자막 만들기
# 입력 파일 옆에 SRT + VTT를 쓰고 대본 저장:
python3 "$S" stt audio.mp3 -l bn \
--srt --srt-path audio.srt --vtt --vtt-path audio.vtt \
-o audio.txt
# 단축: SRT만 (subtitle 명령어):
python3 "$S" subtitle audio.mp3 -l bn -o audio.srt
# 기계가 읽을 수 있는 JSON (다른 도구용):
python3 "$S" stt audio.mp3 -l bn --json -o result.json
# 긴 녹음: 약 120초 단위 자동 분할; 더 작은 청크 또는 한 번 업로드 강제:
python3 "$S" stt audio.mp3 -l bn --chunk-seconds 60
python3 "$S" stt audio.mp3 -l bn --no-chunk # 약 3.5 MB 미만인 경우에만
4단계 — 전달
보고:
audio.srt — 111개 큐 (8.05분, 벵골어)
audio.txt — 대본 저장됨
STT 플래그: --srt, --srt-path, --vtt, --vtt-path, --no-word-timestamps(더 빠름, 예상 시간), --chunk-seconds, --no-chunk, --workers, --max-chars, --max-line-seconds.
대화 모드 (TTS)
스크립트 형식, 한 줄에 한 턴:
쇼가 시작됩니다. <- "화자:" 접두사 없음 -> 내레이터 음성
사람: 형, 2+2가 뭐야?
AI: 질문이 접수되었습니다.
- 화자 레이블은
:앞의 짧은 토큰입니다(최대 16자, 공백 없음). 화자:접두사가 없는 줄은 내레이터/해설자입니다. 내레이터는 특수 키narrator로 매핑되므로, 세 번째 고유 음성은--map "narrator=VoiceC,사람=VoiceA,AI=VoiceB"와 같습니다.--map "화자=음성"은 음성 이름(퍼지 검색) 또는 UUID를 허용합니다.--map이 없으면 고유 음성이 자동으로 할당됩니다.- 음성은 고유해야 합니다. 두 화자가 동일한 음성으로 확인되면 스크립트가
WARNING을 출력합니다. 각 화자를 다른 음성에 매핑하세요. 항상 AI와 사람에게 다른 음성을 지정하고(해설자/내레이터 줄이 있을 경우 내레이터에게 세 번째 음성 지정). --silence 0.35턴 사이의 간격;--loudnorm은 -16 LUFS로 정규화합니다.--manifest FILE은 모든 세그먼트를 기록합니다;--srt FILE은 자막을 씁니다.--no-stitch는 하나의 MP3 대신 개별 세그먼트 파일을 유지합니다.--workers는 병렬 요청을 제어합니다(기본값 4).
옵션 (가장 많이 사용됨)
| 플래그 | 기본값 | 의미 |
|---|---|---|
-l, --language | 자동 감지 | ISO 코드 또는 uid |
-m, --model | sonic-3.5 | sonic-3.5 / sonic-3 / sonic-turbo / sonic-2 |
-v, --voice_id | 프리셋/기본값 | 음성 이름 또는 UUID |
-o, --out | 자동 | 출력 파일 / 디렉토리 (--no-stitch) |
-s, --speed | 1.2 | 0.5–2.0 |
--preset | — | news, story, assistant, audiobook |
--chunk-limit | 1200 | 요청당 문자 수 |
--retries | 4 | 지수 백오프 재시도 |
--workers | 4 | 병렬 요청 |
--no-cache / --force | 꺼짐 | 캐시 우회 / 재생성 |
--no-verify | 꺼짐 | 자동 QA 건너뛰기 (권장하지 않음) |
--dry-run | 꺼짐 | 계획 출력, 요청하지 않음 |
--json | 꺼짐 | 기계가 읽을 수 있는 출력 |
STT 옵션
| 플래그 | 기본값 | 의미 |
|---|---|---|
-l, --language | auto | ISO 코드 (벵골어는 bn 사용) |
--chunk-seconds | 120 | 업로드당 오디오 초 |
--no-chunk | 꺼짐 | 한 번에 요청 (최대 약 3.5 MB) |
--workers | 2 | 병렬 업로드 |
--srt / --srt-path | 꺼짐 | SRT 파일 생성 |
--vtt / --vtt-path | 꺼짐 | WebVTT 파일 생성 |
--no-word-timestamps | 꺼짐 | 더 빠름; 자막 시간은 예상됨 |
--max-chars | 42 | 최대 큐 문자 수 |
--max-line-seconds | 6.0 | 최대 큐 초 |
--timeout / --retries | 300 / 3 | 요청별 타임아웃 / 재시도 |
캐싱 및 안전
- 세그먼트는 콘텐츠 해시로
~/.cache/speakee-tas에 캐시됩니다. 재실행 및 재시도는 자동으로 재개됩니다. - 임시 연결 파일은 항상 제거됩니다.
--no-cache임시 디렉토리는 종료 시 정리됩니다. - 응답은 검증됩니다(
Content-Type: audio/*+ MP3 헤더). 오류 JSON이 오디오로 저장되지 않습니다. - HTTP 429는
Retry-After를 존중합니다. 5xx/타임아웃은 백오프로 재시도합니다. 영구 4xx는 서버 메시지와 함께 즉시 실패합니다. - STT는 전적으로 Python 표준 라이브러리로 인프로세스에서 실행됩니다 — 네트워크 설치, 모델 다운로드, pip가 필요 없습니다.
- 종료 코드:
0정상,1오류,2사용법,3검증,4네트워크/API,5오디오 QA 실패.
참고 파일
references/api.md— 엔드포인트, 페이로드, 검증, 재시도, 캐싱.references/voices.md— 언어/음성 카탈로그, UID 모드, 프리셋.references/troubleshooting.md— 증상, 수정, 일반적인 실패 모드.assets/presets.json— 큐레이션된 음성 프리셋 (편집하여 자신만의 것을 추가).