내레이션
npm run tts는 src/timeline.ts의 모든 라인을 public/audio/<lang>/<key>.wav로 음성 변환하고, Cartesia의 단어 타임스탬프를 <key>.words.json에 저장하며, 실제 라인 길이로 src/audio.generated.ts를 다시 작성합니다. 라인은 엔진, 음성, 모델, 속도 및 텍스트별로 캐시되어 새로 추가되거나 편집된 라인만 다시 음성화됩니다. npm run tts -- en 또는 -- es를 사용하면 하나의 언어로 제한할 수 있습니다.
Cartesia 설정
- 설정은
video.config.mjs(tts)에 있습니다: 모델sonic-3.6-2026-08-27, 속도1. - EN 음성:
5568a7df-e5ab-4442-9fae-2e9ba1b15ad8(en-GB). CARTESIA_API_KEY는 다음 순서로 조회됩니다:- 환경 변수;
- 비디오 폴더의
.env(gitignore 처리됨;.env.example복사); ~/Documents/repos/.env.
- 키를 출력하거나, 에코하거나, 커밋하지 마십시오. 키가 존재하는지 확인할 때는 표시하지 않고, 예를 들어
test -n "$CARTESIA_API_KEY" && echo set와 같이 사용하십시오.
엔진 및 Kokoro 대체
video.config.mjs의 tts.engine:
auto(기본값): 키가 있고 서비스가 응답하면 Cartesia 사용; 그렇지 않으면 전체 언어가 Kokoro(로컬, 무료)로 음성화되고 경고가 출력됩니다. 하나의 언어가 두 음성으로 혼합되지 않습니다: Cartesia가 중간에 중단되면 전체 언어가 Kokoro로 다시 생성되고, Cartesia가 다시 연결되면 다음 실행 시 다시 생성됩니다.cartesia: 대체 없이 실패 처리.kokoro: 오프라인 상태 유지. 음성:af_bella(EN),ef_dora(ES). Kokoro는 단어 타임스탬프를 제공하지 않으므로 자막은 비례적으로 시간이 할당됩니다.
출력에 Kokoro에 대한 경고가 표시되면 비디오에 Cartesia 음성이 없다는 의미입니다: 비디오를 전달할 때 이 점을 알리십시오.
스페인어 음성
voices.es는 스페인어 버전이 만들어질 때까지 null입니다. Cartesia 음성 라이브러리에서 스페인어 음성을 선택하고, 스크립트의 샘플 라인을 들어본 후, 해당 ID를 video.config.mjs에 기록하십시오 (es: { id: '<voice-id>', language: 'es' }). 그런 다음 SETTINGS.voices에 'es'를 추가하고, 스페인어 자막이 필요한 경우 SETTINGS.subtitles에도 추가하십시오.
발음
TTS는 내레이션 텍스트를 음성화하고, 자막은 작성된 텍스트를 표시합니다. TTS가 숫자나 기호를 잘못 읽는 경우, 해당 라인에 say의 네 번째 인자로 spoken form을 제공하고, 기사의 작성된 형식은 자막으로 유지하십시오:
say(0.3, 'It solved 14/20 tasks.', 'Resolvió 14/20 tareas.', {
en: 'It solved fourteen out of twenty tasks.',
es: 'Resolvió catorce de veinte tareas.',
})
- TTS는 spoken form을 음성화하고(캐시는 spoken form이 변경될 때 라인을 다시 음성화함); 라인 길이는 spoken form에서 가져옵니다.
- 자막은 작성된 텍스트를 표시하며, 라인에 비례하여 시간이 할당됩니다(단어 타임스탬프는 spoken 단어에 속하므로 해당 라인에는 사용되지 않습니다).
- 라인을 평범하게 작성하고("14/20", "83 %", "p = 0.0018"), 듣기 결과 TTS가 잘못 읽는 경우에만 spoken form을 추가하십시오.
- 슬래시, 버전 문자열("gpt-5.6"), 파일 이름 및 약어가 일반적인 문제입니다. 이러한 요소가 포함된 각 라인을 들어보십시오.
오디오 QA
npm run audio-qa (out/audio-qa.md 생성):
- 모든 라인을 동일한 음량으로 정규화합니다(파일 버전당 한 번);
- 소스 피크가 -0.1 dBFS에 도달하면 라인을 클리핑으로 표시합니다;
- 라인이 텍스트 길이 기준 예상 시간보다 1.6배 이상 길면 너무 긴 것으로 표시합니다: 이는 깨지거나 반복된 음성의 신호입니다. 표시된 각 라인을 듣고, 잘못된 경우 다시 음성화하십시오(텍스트를 약간 편집하거나 wav 파일을 삭제).
npm run render후,out/의 각 믹스를 -16 LUFS 통합, ±1 LU(트루 피크 -1.5 dBTP)에 대해 측정하고, 하나라도 목표에서 벗어나면 종료 코드 1을 반환합니다.
내레이션 후 npm run lint를 다시 실행하십시오: 실제 길이가 예상 길이를 대체하여 비디오가 목표 길이를 초과하거나 자막이 초당 17자를 초과할 수 있습니다.
배경 음악
부드러운 배경 음악은 로컬에서 생성됩니다(npm run music, npm run render에서 없을 경우 자동으로 생성됨; python3와 numpy 또는 uv 필요). 라인이 재생되는 동안 볼륨이 30%로 줄어듭니다. 음악을 원하지 않으면 SETTINGS.music을 null로 설정하십시오.