Community라이팅 & 에디팅github.com

muyunxue/dance-mmd-subtitle-kit

ASS/SSA 자막 작성 및 libass를 사용한 자막 합성을 위한 엄격한 규칙, 템플릿, ffmpeg 명령어, 오류 진단 도구입니다. ASS 파일을 작성하기 전, 자막이 나타나지 않거나 위치/크기가 잘못되었을 때, \p1 도면이 오프셋되었을 때, 또는 투명 오버레이 내보내기 레시피가 필요할 때 이 스킬을 로드하세요.

dance-mmd-subtitle-kit란 무엇인가요?

이 스킬은 Claude Code가 ASS(Advanced SubStation Alpha) 자막 파일을 정확하게 작성하고 libass를 사용하여 비디오에 자막을 합성(burn-in)하는 데 필요한 포괄적인 규칙, 템플릿, 명령어 및 문제 해결 가이드를 제공합니다. 주로 ffmpeg와 함께 사용되는 libass는 엄격한 형식 규칙을 따르며, 잘못된 타임스탬프 형식(H:MM:SS.cc), 스타일 색상의 후행 앰퍼샌드(&), 상대 경로가 아닌 fontsdir 사용, UTF-8 BOM 없는 인코딩, Permanent Marker 폰트의 비정상적인 크기 조정, \p1 도면의 앵커 문제, 연속된 \t 태그 무시 등 여러 미묘한 함정이 있습니다. 이 스킬은 이러한 모든 함정을 실제 프로젝트 경험을 바탕으로 문서화하여, '성공'했지만 자막이 보이지 않는 상황을 진단하고 수정하는 방법을 제시합니다. Windows 환경(PowerShell + ffmpeg)에서 최적화되어 있으며, 직접 합성(burn-in), 투명 오버레이(WebM with alpha), 프레임 추출 검증 명령어를 포함합니다. 또한 ASS 생성기 Python 스켈레톤 코드와 스타일/애니메이션 태그(\fad, \move, \t, \clip, \p1 등)에 대한 실용적인 참고 자료를 제공합니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/muyunxue/dance-mmd-subtitle-kit/tree/HEAD/skills/ass-render-playbook

Installed? Explore more 라이팅 & 에디팅 skills: steipete/notion, langchain-ai/langchain, bytedance/podcast-generation · View all 6 →

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

ASS 작성 / libass 합성 실전 매뉴얼

1. 파일 헤더 템플릿 (그대로 사용)

[Script Info]
ScriptType: v4.00+
PlayResX: 2560
PlayResY: 1080
WrapStyle: 2
ScaledBorderAndShadow: yes
YCbCr Matrix: TV.709

[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
Style: X,Microsoft YaHei,100,&H00F4F1EA,&H00F4F1EA,&H00140F11,&HFF000000,0,0,0,0,100,100,0,0,1,0,0,5,30,30,30,1

[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
Dialogue: 0,0:00:00.39,0:00:03.75,X,,0,0,0,,{\an5\pos(500,300)\fnAnton\fs150\1c&H00F4F1EA&\bord3\3c&H00140F11&\frz-4\fscx118\fscy118\t(0,130,\fscx100\fscy100)\fad(100,100)}WALK

2. 네 가지 치명적인 형식 함정 (이 프로젝트에서 모두 경험)

  1. 타임스탬프는 반드시 H:MM:SS.cc 형식
    • 올바름: 0:00:01.50, 0:01:02.30
    • 틀림: 0:01.50 (libass에서 Bad timestamp 오류 발생, 해당 줄이 무시됨 → 전체 비디오에 자막 없음, 하지만 ffmpeg는 0 반환)
  2. Style 행 색상 끝에 &를 붙이지 말 것
    • 올바름: &H00F4F1EA,&H00F4F1EA,&H00140F11,&HFF000000
    • 틀림: &H00F4F1EA&,... → Style 행 파싱 실패 → 마찬가지로 '성공했지만 자막 없음'
    • 이벤트 내 인라인 태그 색상은 &를 포함: \1c&H00F4F1EA&
  3. 글꼴 디렉토리 fontsdir는 상대 경로 + 작업 디렉토리 사용
    • 출력 디렉토리에 fonts/ 폴더를 만들고, 해당 디렉토리로 cd한 후 ass=x.ass:fontsdir=fonts 사용.
    • 절대 경로는 드라이브 문자와 콜론이 필터그래프(filtergraph)에서 문제를 일으킬 수 있음; 상대 경로(중국어 포함)는 괜찮음(cwd는 중국어 가능하지만 필터 파라미터는 ASCII 권장).
  4. ASS 파일은 utf-8-sig로 저장, 파일명은 ASCII 사용
    • 중국어 파일명은 필터 파라미터에서 불안정함; _s4.ass와 같은 형식 사용.

진단 명령어 (libass가 실제로 읽는 내용 확인):

& $ff -hide_banner -v verbose -f lavfi -i "color=c=0x303040:s=2560x1080:r=30:d=2" `
  -vf "ass=_s4.ass:fontsdir=fonts" -c:v libx264 -crf 22 -pix_fmt yuv420p _t.mp4 2>&1 | Select-String 'Bad timestamp|Style|font file'

3. 색상 / 알파(alpha) 의미

  • 색상: &HBBGGRR& (파랑-초록-빨강 순서), 예: 흰색 &H00F4F1EA&, 먹색 &H00140F11&, 분홍 &H00B35CFF&, 라벤더 &H00FFA4C4&, 크림 &H00D7EEF8&, 금색 &H0054C9FF&.
  • 투명도 \1a: &H00& 완전 불투명; &HFF& 완전 투명 (16진수 값이 높을수록 더 투명). 초기 버전에서 깜빡임 효과가 실패한 원인은 알파 의미가 반대였기 때문.
  • Style 행의 PrimaryColour는 &HAABBGGRR (AA가 앞에 오고, 끝에 & 없음).

4. 글꼴

  • libass는 fontconfig/directwrite를 사용하므로 family name이 정확해야 함. PIL로 확인:
from PIL import ImageFont
ImageFont.truetype(r"...\fonts\Anton-Regular.ttf", 40).getname()  # ('Anton','Regular')
  • 이 프로젝트 사용 글꼴: Anton / Archivo Black / Bebas Neue / Permanent Marker / Silkscreen / Rubik Glitch / Bungee / Monoton / Pirata One / UnifrakturCook; 시스템 Georgia, Microsoft YaHei는 \fnGeorgia, \fnMicrosoft YaHei로 직접 사용 가능.
  • Permanent Marker는 libass에서 실제 크기가 약 0.79×fs이므로, 이 계수만큼 글자 크기/색상 블록 크기를 키워야 함.
  • 글리프 누락(예: ♥ ★) 시 자동으로 ArialMT로 대체되어 표시는 되지만 글리프가 다름; 정확하게 표시하려면 \fnMicrosoft YaHei 사용.

5. 애니메이션 태그 빠른 참조

태그사용법
\fad(in,out)밀리초 단위 페이드 인/아웃
\move(x1,y1,x2,y2,t1,t2)위치 이동 (\pos와 함께 사용 불가, move 우선)
\t(t1,t2,\tag...)시간 기반 보간, 예: \t(0,130,\fscx100\fscy100\blur(0))
\frz / \fscx / \fscy회전/크기 조정 (음수 값으로 뒤집기 가능)
\blur(n)흐림 효과 (큰 글자가 나타날 때 흐림→선명 효과에 유용)
\clip(x1,y1,x2,y2)직사각형 클리핑 (조각/스캔라이트/나타내기 효과)
\org(x,y)회전/크기 조정의 중심점 설정
\p1 + 그리기m 0 0 l w 0 w h 0 h 직사각형 등

주의: 동일 속성에 연속된 두 개의 \t는 하나만 적용됨 (예: 규칙 선 수축 애니메이션). 두 개의 이벤트/두 번의 다시 그리기로 해결. 주의: \p1 그리기 좌표는 왼쪽 위 모서리 앵커이며, libass는 블록 전체를 높이의 h/2만큼 위로 이동시킴; \an7\pos(왼쪽위) + 절대 좌표 사용이 가장 안정적이며, 회전/스윕 효과는 \org로 원점 설정. 주의: 하이라이트 펜 색상 블록을 단어 뒤에 '스윕'하려면 그리기 레이어에서 \fscx0 → \t(0,150,\fscx100) 사용, 원점은 \org 사용.

6. 렌더링 명령어

6.1 직접 합성 (가장 자주 사용)

cd 출력_디렉토리
& $ff -v error -y -i _base_30s.mp4 -vf "ass=_s4.ass:fontsdir=fonts" `
  -c:v libx264 -preset medium -crf 16 -pix_fmt yuv420p -movflags +faststart OUT.mp4

30초 / 2560×1080 / 중국어 자막량 기준 약 1–3분 소요.

6.2 투명 오버레이 (편집 소프트웨어 사용)

& $ff -v error -y -f lavfi -i "[email protected]:s=2560x1080:r=30,format=rgba" `
  -vf "fps=30,ass=_sub.ass:alpha=1" -t 154.6 `
  -c:v libvpx-vp9 -pix_fmt yuva420p -b:v 0 -crf 30 -row-mt 1 -auto-alt-ref 0 `
  -metadata:s:v:0 alpha_mode=1 OUT_alpha.webm
  • 디코딩은 반드시 -c:v libvpx-vp9 사용; 기본 vp9 디코더는 알파 채널을 잃음.
  • 호환성 우선 '스크린 합성' mp4: 검은 배경 + 밝은 글자, 편집 소프트웨어에서 Screen/Lighten 혼합 모드 사용.

6.3 프레임 추출 검증 (렌더링 로그 대신 이미지 확인)

& $ff -v error -ss 12.4 -i OUT.mp4 -frames:v 1 -q:v 2 -y _check.jpg

참고: -ss를 -i 앞에 (입력 seek) 두면, 특정 상황에서 ASS 타임라인이 출력 기준으로 리디렉션되어 미리보기가 비어 보일 수 있음; 검증 프레임 추출은 출력 측 seek (-i OUT.mp4 -ss 12.4) 또는 전체 구간을 추출한 후 선택하는 것이 좋음.

7. 문제 해결 빠른 참조표

현상원인해결 방법
전체 영상에 글자 없음타임스탬프 형식 / Style 색상 끝 &H:MM:SS.cc 형식으로 변경; Style 색상 끝 & 제거
일부 문장 없음해당 문장 타임스탬프 오류 또는 start>end문장별로 확인
글자가 매우 작거나 글꼴 틀림글꼴 family 이름 오류PIL getname()으로 확인
\p1 색상 블록이 위/아래로 치우침그리기 앵커 + libass 상단 이동 h/2\an7 + 왼쪽 위 절대 좌표 + 실제 측정 기준 프레임 사용
회전 중심이 맞지 않음기본 중심이 원하는 위치가 아님\org(x,y) 추가
페이드 아웃 효과 없음/깜빡임 반대알파 의미 반대&H00 불투명, &HFF 투명
30초 렌더링에 처음 4문장만 표시됨루프가 처음 몇 문장만 처리이벤트 생성 루프 범위 확인
중국어 경로/파일명 렌더링 실패필터 파라미터에 비ASCII 문자 포함ASS와 소스 파일은 ASCII 파일명 사용 + 중국어 cwd는 허용

8. 생성기 스켈레톤 (Python)

def ts(sec):
    h=int(sec//3600); m=int(sec%3600//60)
    return "%d:%02d:%05.2f" % (h,m,sec-h*3600-m*60)

class Ass:
    def __init__(self,path,w=2560,h=1080): self.ev=[]; self.path=path; self.w=w; self.h=h
    def add(self,layer,t0,t1,tags,text): self.ev.append((layer,t0,t1,tags,text))
    def write(self):
        head = open("template_header.ass",encoding="utf-8").read()  # 또는 코드에 직접 포함
        lines=[]
        for layer,t0,t1,tags,text in sorted(self.ev,key=lambda e:(e[0],e[1])):
            lines.append("Dialogue: %d,%s,%s,X,,0,0,0,,{%s}%s"%(layer,ts(t0),ts(t1),tags,text))
        open(self.path,"w",encoding="utf-8-sig",newline="\n").write(head+"\n".join(lines)+"\n")

참고 구현: 字幕/build/styles_anim.py (S2/S4/S6), flare_wide.py, neon_wide.py, avoid_side2.py.

Individual skills in this repo

This repo contains 4 individual skills — each has its own dedicated page.

muyunxue/dance-mmd-subtitle-kit

Character-avoiding subtitle layout for the MMD dance videos — measure the dancer's per-frame bounding box, compute a per-cue union, place text in safe side/top columns, and verify zero overlap on every frame. Load this when asked 字幕不要挡住人物/完全不挡/避让, or when text overlaps wings/body and you need a verified-free layout with measured overlap counts.

muyunxue/dance-mmd-subtitle-kit

End-to-end recipe for making subtitles for the MMD dance videos in this workspace (字幕/ project) — probe the source, pick a segment, map LRC cues, choose a style, build ASS, burn, verify, and deliver. Load this when starting or resuming any subtitle task (静态稿/5s小样/30s小样/全片/透明叠加层), when a render "succeeded" but the video has no text, or when you need this project's paths, font list, cue sheet and acceptance criteria.

muyunxue/dance-mmd-subtitle-kit

Design and deliver subtitle style mockups and animated comparison samples for the MMD/K-pop dance videos — S1–S6 style catalogue (Y2K chrome, minimal kinetic, glitch, mix&match editorial, graphic emphasis, hand-marker), PIL/numpy effect recipes, font list, contact-sheet/comparison video conventions, and the parallel-subagent workflow used for S4 vs S6. Load this when asked 出几个静态帧方案/参考女团PV字幕/做个小样/对比几个风格, or when choosing a visual direction before building a full-length subtitle track.

muyunxue/dance-mmd-subtitle-kit

Subject-aware colour grading for the MMD dance videos in this workspace — make the dancer stand out (background dim/cool/desat, subject lift/warm/sharpen/bloom) using either a soft stage-light ellipse or a hard character matte, with ffmpeg recipes, measured parameter sets and known failure modes (cast-shadow matte contamination, banding, truncated sources). Load this when asked to 调色/突出人物/压背景/统一色调, or when a graded clip shows weird bright blobs around the dancer.

관련 스킬