본문으로 건너뛰기
VIDIA고수의 노하우로 만드는 영상

TTS 생성

TTS·음성

비디아 · v1 · 0회 사용 · 패키지 13개

장면별 내레이션 음성과 발화 시간표를 만듭니다.

설명서

하는 일 화자별 목소리·속도로 장면마다 tts_generate 를 부르고, 장면 사이 쉼(audio.sceneGapMs)과 여유(tailSec)를 반영해 장면 길이를 정합니다.

입력 blueprint.scenes[].utterances, blueprint.speakers, blueprint.audio.

출력 assets["tts:<장면>"], timeline{utterances, scenes, narration, totalSec, order}. 자막·영상 길이·렌더링이 이 시간표를 씁니다.

비용 100자당 과금(글자 수 비례). 이미 만든 음성은 다시 만들지 않습니다.

지시서(스킬 txt)

txt 내려받기
[이 모듈이 하는 일]
설계도의 장면별 발화(ttsText)로 한국어 내레이션 음성을 만들고, 발화마다 영상 전체 기준의 시작·끝 시각을 계산해 시간표(timeline)를 만든다.
이 시간표는 자막·영상 길이·최종 렌더링이 모두 기준으로 쓴다.

[입력]
이전 단계 JSON(vidia.doc@1).
- blueprint.scenes[]: id, utterances[{id, speakerId, ttsText, pauseAfter}], durationSec, tailSec
- blueprint.speakers[]: {id, voiceId, tempo}
- blueprint.models.tts: {defaultVoiceId, tempo}
- blueprint.audio.sceneGapMs: 장면 사이 쉼(기본 200ms)
- assets: 이미 만든 음성("tts:<장면id>" 키)이 있으면 다시 만들지 않는다.
- timeline: 이전 시간표(재실행일 때)

[할 일]
1. 준비
   - 화자 표: speakerId → voiceId, tempo. 화자의 tempo 가 없으면 models.tts.tempo, 그것도 없으면 1.0. 발화에 speakerId 가 없으면 첫 화자.
   - 장면 사이 쉼 gapSec = (audio.sceneGapMs 또는 200) ÷ 1000.
2. 장면마다 설계도 순서대로 음성을 만든다.
   - 발화가 없는 장면은 음성을 만들지 않는다.
   - 한 장면의 발화를 순서대로 훑어 "같은 화자가 이어지는 묶음(part)"으로 나눈다. 화자가 한 명이면 장면 전체가 part 하나다.
   - part 마다 tts_generate 를 부른다.
     voice_id = 그 화자의 voiceId, tempo = 그 화자의 tempo,
     utterances = [{"id": 발화 id, "text": ttsText, "pause_after": pauseAfter(있을 때만)}],
     label = "<장면id> 내레이션"(part 가 2개 이상이면 "<장면id> 내레이션 2" 처럼 번호).
   - 결과의 asset_id·duration_sec·utterances[{id,start_sec,end_sec}] 를 기록한다.
   - 자산 키: 첫 part 는 "tts:<장면id>", 두 번째부터 "tts:<장면id>:p2", "tts:<장면id>:p3" …
   - assets 에 그 키가 이미 있고 timeline.narration 에 같은 키의 기록이 있으면 도구를 다시 부르지 않고 그 기록을 쓴다.
   - ttsText 에 숫자·영문·기호가 남아 있어도 고치지 않는다(대본 수정은 이 단계의 일이 아니다). 도구가 거절하면 "error" 에 발화 id 와 이유를 적는다.
3. 시간표를 계산한다(초 단위, 소수 셋째 자리까지 반올림).
   - 첫 장면 startSec = 0, 그 뒤 장면은 startSec = 앞 장면 startSec + 앞 장면 durationSec (장면은 빈틈 없이 이어진다).
   - 장면 안 내레이션 시작 여유 leadSec: 첫 장면은 0.1, 그 뒤 장면은 gapSec.
   - part 는 장면 안에서 앞 part 가 끝나는 곳에 이어 붙인다: part 시작(장면 기준) = leadSec + 앞 part 들의 duration_sec 합.
   - 발화 절대 시각 = 장면 startSec + part 시작 + 도구가 준 start_sec / end_sec.
   - 장면 길이 durationSec = max(마지막 part 끝(장면 기준) + tailSec, 설계도 durationSec). tailSec 은 장면 값, 없으면 0.5. 발화가 없는 장면은 설계도 durationSec(없으면 3).
   - totalSec = 마지막 장면 startSec + durationSec.
4. timeline 을 채운다.
   - timeline.scenes["<장면id>"] = {"startSec": …, "durationSec": …, "narrationStartSec": 장면 startSec + leadSec, "narrationEndSec": 마지막 발화 절대 끝}
   - timeline.utterances["<발화id>"] = {"sceneId": "<장면id>", "startSec": …, "endSec": …}
   - timeline.narration = [{"key": "tts:<장면id>", "sceneId": "<장면id>", "assetId": 음성 asset_id, "startSec": part 절대 시작, "durationSec": duration_sec}, …] (영상 순서)
   - timeline.totalSec = 전체 길이
   - timeline.order = 장면 id 배열(설계도 순서)

[출력]
다음 최상위 필드만 담은 JSON 객체 하나(적지 않은 최상위 필드는 입력값이 그대로 이어지므로 다시 적지 않는다. 바꾸는 필드는 값 전체를 적는다.)
- assets: 기존 값에 "tts:<장면id>"(와 "tts:<장면id>:p2" …) 키를 더한다.
- timeline: 위에서 만든 {utterances, scenes, narration, totalSec, order}
예: "assets":{"tts:s01":41,"tts:s02":42}, "timeline":{"utterances":{"s01_u1":{"sceneId":"s01","startSec":0.1,"endSec":2.84}},"scenes":{"s01":{"startSec":0,"durationSec":6.12,"narrationStartSec":0.1,"narrationEndSec":5.72}},"narration":[{"key":"tts:s01","sceneId":"s01","assetId":41,"startSec":0.1,"durationSec":5.62}],"totalSec":58.4,"order":["s01","s02"]}

[주의]
- tts_generate 는 글자 수에 비례해 비용이 드는 도구다. 장면(또는 part)마다 한 번만 부르고, 이미 만든 음성은 다시 만들지 않는다.
- 도구가 준 발화 시각을 그대로 쓴다. 시각을 추정해 지어내지 않는다.
- 설계도(blueprint)는 바꾸지 않는다.
- 설명·마크다운 없이 JSON 객체 하나만 답한다.

버전 기록 1개

고칠 때마다 새 버전으로 쌓이고 지난 버전은 지워지지 않습니다. 패키지는 넣을 때의 버전으로 고정되어 동작합니다.

  1. v1현재2026.09.29 14:57 · 4.6KB

    시스템 모듈 등록

이 모듈을 쓰는 패키지

리뷰와 반응

불러오는 중…

사용 -건 · 사용 건수는 이 모듈을 실제로 실행한 제작 수입니다(성공률이 아닙니다). 별점은 실제 사용한 회원만 남길 수 있고, 좋아요·싫어요와는 따로 셉니다.

    신고하기

    신고하신 분의 정보는 작성자에게 알리지 않습니다. 접수만으로 제재가 확정되지는 않습니다. 결과 불만·환불은 1:1 문의로도 알려 주세요.