Skip to content
Back to skills

Yd Script Editor

ASecurity

시연·데모 영상의 내레이션 대본(md 표)을 웹 에디터로 고치고, 줄별 음성 합성(OmniVoice)·시각 맞춤·장면 렌더·배경음 믹싱·장면 클립까지 레포 설정(script-editor.json) 하나로 돌릴 때. 레포마다 에디터 서버(launchd/systemd)와 공개 터널을 구성한다

  • 13 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added October 7, 2026
developmentpythonnodeapi

Works with

  • cli
  • api

Security analysis

A100/100

Pro scans all 20 files and shows the line behind each finding

Scanned October 7, 2026

npx -y skills add LeeYudok/doksam-skills --skill yd-script-editor --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Yd Script Editor?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Yd Script Editor
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/leeyudok-yd-script-editor/badge)](https://www.skillsdirectory.com/skills/leeyudok-yd-script-editor)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: yd-script-editor
description: 시연·데모 영상의 내레이션 대본(md 표)을 웹 에디터로 고치고, 줄별 음성 합성(OmniVoice)·시각 맞춤·장면 렌더·배경음 믹싱·장면 클립까지 레포 설정(script-editor.json) 하나로 돌릴 때. 레포마다 에디터 서버(launchd/systemd)와 공개 터널을 구성한다
---

# yd-script-editor

## 역할

시연 영상 제작 파이프라인의 **코드 원천**이다. 레포는 설정 파일 하나와 콘텐츠만 가진다.

| 어디에 | 무엇 |
|---|---|
| 이 스킬 | 에디터(Node 서버 + Vite 화면, `assets/app`), 엔진(음성·시각·렌더·믹스·클립, `assets/engine`), 설치기·CLI(`scripts/`) |
| 레포 | `script-editor.json`, 대본 md·합성 입력 json(`content`), 음성·클립·썸네일, 장면 데이터 `.py`(`render.scenes`), 발음 단어 표 |
| 런타임 `~/.local/share/yd-script-editor` | `app`(+node_modules)·`engine` 복사본, `venv`(Pillow), `dist/<name>`(레포별 빌드) |

**레포의 데이터(대본·장면 좌표·녹화 경로·문구·발음 단어)를 이 스킬에 넣지 않는다.** 이 스킬은 공개 저장소에 있다. 예시·테스트 픽스처는 지어낸 내용만 쓴다.

## 레포 설정 `<레포>/script-editor.json`

```json
{
  "name": "demo",
  "content": "docs/editor",
  "prefix": "대본-",
  "base": "/editor",
  "port": 18750,
  "pronounce": "docs/editor/pronounce.tsv",
  "synth": { "python": "~/.cache/omnivoice-venv/bin/python", "cache": "~/.cache/yd-script-editor/demo" },
  "videos": { "dir": "~/Movies/demo", "pattern": "demo-*.mp4" },
  "render": { "scenes": "docs/editor/render/scenes.py", "out": "~/Movies/demo/build", "music": "~/Movies/demo/music.wav" },
  "public": [
    { "ssh": "relay-host", "url": "https://example.com/editor/" },
    { "ssh": "lan-host", "url": "https://editor.lan.example/editor/" }
  ]
}
```

- `name`: 영소문자·숫자·`-`. 서비스 라벨 `com.<사용자>.script-editor.<name>` 이 된다.
- 상대 경로는 레포 기준, `~` 는 홈이다. `name` 말고는 전부 선택이다.
- `prefix`: 대본 파일 이름 앞부분. 라벨은 `<prefix><라벨>.md` 에서 나온다.
- `base`: 공개 경로. 화면은 레포마다 이 base 로 빌드된다.
- `pronounce`: TSV(`자막 낱말<탭>읽는 말`). 영문 낱말은 앞뒤가 영문이 아닐 때만 바꾼다.
- `videos.pattern`: 완성 영상 이름. `*` 자리가 영상 키다. 영상 비교 페이지와 믹스 출력이 쓴다.
- `render.scenes`: 장면 데이터 모듈. 필요한 이름은 `assets/engine/render/render.py` docstring 에 있다.
- `public`: 공개 대상 `{ssh, url}` 하나 또는 그 배열. `--public` 이면 대상마다 역방향 터널(`autossh -R 127.0.0.1:<port>`)을 서비스 `<라벨>.tunnel.<ssh 호스트>` 로 띄운다.
  - `ssh` 는 SSH 호스트 이름만 쓴다. 그 호스트의 리버스 프록시가 `base/` 를 `127.0.0.1:<port>` 로 넘기고 `Host: 127.0.0.1:<port>` 를 넣어야 한다(서버가 Host 를 검사한다).
  - 원격 sshd 의 GatewayPorts 가 꺼져 있으면 터널은 루프백에만 열린다. 컨테이너(k3s 등) 프록시가 받으려면 원격에서 socat 같은 중계를 따로 둔다.
  - 공개 주소는 프록시 쪽 인증을 붙인다. 에디터 자체에는 로그인이 없다.

## 콘텐츠 폴더 구조

```
<content>/
  <prefix><라벨>.md      대본 표: | # | 시각 | 장면 | [화면 자막 |] 자막·대본 | 읽는 말 | [AI 프롬프트 |]
  <prefix><라벨>.json    음성 합성 입력(ref_audio·lines[start·max·say·speak]). 있을 때만 저장 시 재합성
  ids.json               주소 번호 → 대본 파일(서버가 만든다. /<base>/<번호> 로 연다)
  audio/<라벨>/NN.m4a    줄 음성(+NN.json)
  clips/<라벨>/NN.mp4    장면 영상 · frames/<라벨>/NN.jpg 썸네일
```

머리말의 `목표 길이: N초` 는 시각 맞춤과 렌더의 영상 길이가 된다.

## 워크플로

1. **구성**: `sh <스킬경로>/scripts/setup.sh <레포> [--public]`
   - 런타임을 동기화하고 의존성 설치, 레포별 빌드, 서비스 등록, 응답 확인까지 한다.
   - 다시 돌리면 그게 업데이트다.
   - 상태는 `setup.sh <레포> status`, 제거는 `setup.sh <레포> remove`.
   - 포트를 다른 프로세스가 잡고 있으면 멈춘다. 예전 방식으로 띄운 서버는 먼저 내린다.
2. **조회·수정**: `python3 <스킬경로>/scripts/se.py` 를 쓴다. 대본 md 를 손으로 고치지 않는다(서버가 형식을 검증하고 재합성 대기열에 넣는다).
   - `list`: 번호·라벨·줄 수
   - `show <대본>`: 줄 표
   - `set <대본> <줄> <칸> <값>`: 칸은 `time scene screen say speak prompt same`. 값 안의 줄바꿈은 `\n`.
   - `<대본>` 은 주소 번호·라벨·파일 이름 어느 것이나 된다.
   - `say` 만 고치면 읽는 말은 따라 바뀌지 않는다. 화면에서는 따라가지만 CLI 에서는 `speak` 를 같이 주거나 `same 1` 로 둔다.
3. **음성**: `se.py synth <대본> [줄…|all]` 를 쓴다.
   - 설정 `synth.python` 의 OmniVoice venv 로 돈다.
   - 재전사 유사도가 0.85 미만이면 다시 만든다. 결과 `NN.json` 의 `sim` 을 보고한다.
4. **시각**: `se.py fit <대본>` 로 미리 본 뒤 `--apply` 한다. 실제 음성 길이에 여유를 똑같이 나눠 마지막 줄이 목표 길이에서 끝나게 한다.
5. **영상**:
   - `se.py render <대본> --check`: 줄마다 확인 프레임 `check.jpg` 만 만든다.
   - `se.py render <대본>`: `video-only.mp4` 를 만든다.
   - `se.py intro <대본> <html> <초>`: 1장 HTML 을 녹화해 둔다(선택).
   - `se.py mix <대본>`: 완성 영상을 만들고 장면 클립까지 다시 자른다.
   - 썸네일은 `render --thumbs`.
6. **확인**: `se.py url <대본>` 의 주소를 사용자에게 준다. 공개 주소가 있으면 그것도 준다.

## 엔진을 고칠 때

- 그리기·합성 로직은 `assets/engine/render/render.py`, 공용 바탕은 `base.py` 에 있다.
- 새 연출에 필요한 값(좌표·문구·경로)은 엔진에 상수로 넣지 말고 장면 데이터 모듈의 이름으로 받는다. 엔진 기본값은 빈 문자열·중립 값이다.
- 렌더를 바꾸면 이관 전후 `render --check` 의 `check.jpg` md5, 또는 `--only N` 결과 mp4 의 `ffmpeg -f framemd5` 를 비교해 의도한 차이만 났는지 본다.

## 테스트로 지키는 규칙

- 설정의 상대 경로는 레포 기준이고, 대본은 주소 번호·라벨·파일 이름 어느 것으로도 찾는다
- 설정 파일은 현재 폴더에서 위로 올라가며 찾는다
- `~/` 는 홈으로 편다
- 대본 표의 시각·화면 자막·AI 프롬프트와 목표 길이를 읽고, 인트로는 0초·마지막 줄은 목표 길이까지로 둔다
- 머리말에 목표 길이가 없으면 렌더를 시작하지 않는다
- `se.py set` 은 서버 API 로 etag 와 함께 문서 전체를 저장하고 다른 줄은 건드리지 않는다
- 읽는 말을 직접 주면 '자막과 같음' 을 끈다
- 모르는 칸·없는 줄은 저장하지 않고 실패한다
- 없는 대본은 실패한다
- 설정 파일이 없으면 런타임을 만들기 전에 멈춘다
- 서비스 이름(name)은 영소문자·숫자·- 만 받는다
- `public` 은 대상 하나(객체)나 여러 개(배열)를 받고, 대상마다 터널 서비스를 하나씩 둔다
- 예전 형식(객체 하나)도 그대로 받는다
- `public.ssh` 는 SSH 호스트 이름(영문·숫자·`._@-`)만 받는다

## 완료 조건

- `setup.sh <레포> status` 에서 서비스 running, 로컬 응답. `--public` 이면 대상마다 터널 응답도.
- 수정한 대본은 `se.py show` 로 다시 읽어 바뀐 칸을 확인했다. 재합성이 걸렸으면 `api/synth` 오류가 없다.
- 렌더·믹스 결과 경로와 길이, 음량(믹스 로그의 `output_i`)을 보고했다.

Files in this skill

  • SKILL.md7.8 KB
  • agents/antigravity.md493 B
  • agents/claude.md393 B
  • agents/codex.toml351 B
  • agents/openai.yaml254 B
  • assets/app/fixtures/대본-5칸.md570 B
  • assets/app/fixtures/대본-6칸.md497 B
  • assets/app/fixtures/대본-프롬프트.md368 B
  • assets/app/package.json649 B
  • assets/app/pnpm-lock.yaml28.5 KB
  • assets/app/src/client/common/inline-player.ts6.6 KB
  • assets/app/src/client/common/styles/base.css13.6 KB
  • assets/app/src/client/common/timing.test.ts1 KB
  • assets/app/src/client/common/timing.ts1.2 KB
  • assets/app/src/client/compare/index.html1.7 KB
  • assets/app/src/client/compare/main.ts6.9 KB
  • assets/app/src/client/compare/styles/compare.css2 KB
  • assets/app/src/client/editor/index.html4.2 KB
  • assets/app/src/client/editor/main.ts41.4 KB
  • assets/app/src/client/player/index.html1 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.