Communitygithub.com

nicko1122/auto-subtitle

자동 오디오 추출, Whisper 음성-텍스트 변환, Luna 이중 검증 가사 정렬, 로컬 Edge LLM 교정, CSS 자막 스타일링 및 NVENC GPU 비디오 하드섭 번-인을 지원합니다. 비디오/오디오용 자막 처리, 가사 정렬, 배치 자동 자막 작업, 또는 ASS/CSS 하드카피 비디오 번-인 구성 시 이 스킬을 활성화하세요.

auto-subtitle란 무엇인가요?

이 스킬은 `auto-subtitle` CLI 및 FastAPI 백엔드를 사용하여 자막 추출, 음성-텍스트 변환(Whisper), 가사 강제 정렬(Luna 파이프라인), 로컬 LLM 교정, GPU 가속 비디오 하드섭 번-인을 자동화하는 방법을 안내합니다. Luna 파이프라인은 Whisper 음향 특징 추출, `stable-ts` 정렬, LLM Decision Brain 감사, +0.16초 가독성 패딩의 5단계 이중 검증 프로세스를 실행합니다. 이 스킬은 가사가 있는 노래(스크립트 기반)와 대화/강연(스크립트 없음) 워크플로우를 모두 지원하며, CSS 기반 자막 스타일링을 ASS 형식으로 매핑하고 NVIDIA NVENC GPU 인코딩을 활용하여 효율적으로 비디오에 자막을 입힙니다. 주요 플랫폼은 모든 명령줄 환경이며, FastAPI를 통한 REST API 통합도 지원합니다. 워크플로우는 배치 스크립트와 Python 스크립트 예제를 제공하며, 자세한 CSS-ASS 속성 매핑 테이블, 폰트 관리 명령어, 출력 산출물 목록(SRT, VTT, LRC, ASS, JSON 증거 파일 등)을 포함하여 개발자가 복잡한 자동 자막 파이프라인을 쉽게 구축할 수 있도록 돕습니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/nicko1122/auto-subtitle/tree/HEAD/skills/auto-subtitle

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

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

문서

AutoSubtitle AI - 자동화 및 에이전트 스킬 가이드

이 스킬은 auto-subtitle CLI 및 FastAPI 백엔드를 사용하여 자막 추출, 음성-텍스트 변환, 가사 강제 정렬(Luna 파이프라인), 로컬 LLM 교정, GPU 가속 비디오 하드섭 번-인을 자동화하는 방법을 안내합니다.


📌 워크플로우 결정 매트릭스

입력 에셋에 따라 적절한 명령 또는 파이프라인을 선택하세요:

시나리오 / 목표권장 명령주요 인수
노래 / 가사 정렬 (미디어 + .txt 가사)python src/cli/main.py luna (또는 align)<media> <lyrics.txt> --llm local/api -o <dir>
음성 / 대화 / 비디오를 자막으로 변환 (스크립트 없음)python src/cli/main.py pipeline<media> -d cuda -o <dir>
오디오만 추출python src/cli/main.py extract<video> -o <audio.wav> --sr 16000
오타 / 동음이의어 수정 (Edge LLM 사용)python src/cli/main.py proofread<subtitles.srt> --gpu-layers -1
비디오에 자막 번-인 (하드섭)python src/cli/main.py burn<video> <subtitles.srt> --css "..."
폰트 관리 (오픈소스 / Windows 폰트 설치)python src/cli/main.py fontslist, install <id/path/url>, remove <filename>
웹 스튜디오 실행python src/cli/main.py serve--host 0.0.0.0 --port 8000

🛠️ CLI 명령 참조

1. Luna 가사 파이프라인 (luna / align)

Whisper 음향 특징 추출 + stable-ts 정렬 + LLM Decision Brain 감사 + +0.16초 가독성 패딩의 5단계 이중 검증 파이프라인을 실행합니다:

python src/cli/main.py luna inputclip/test_video.mp4 inputclip/audio-org.txt \
    --llm local \
    --output-dir output_luna

--output-dir의 출력 산출물:

  • lyrics.srt: 표준 SRT 자막 트랙.
  • lyrics.vtt: 웹 플레이어용 WebVTT 형식.
  • lyrics.lrc: 음악 플레이어용 밀리초 타임스탬프가 포함된 향상된 LRC 형식.
  • lyrics.ass: FFmpeg 번-인을 위해 준비된 포맷 ASS 자막.
  • cue_evidence.json: 각 라인별 전체 음향 증거 및 신뢰도 메트릭.
  • review.csv: 비정상 라인 및 LLM 중재 결정의 상세 보고서.
  • run_manifest.json: 소스 미디어 및 출력의 SHA-256 무결성 해시.

2. 종단간 음성 파이프라인 (pipeline)

토크쇼, 팟캐스트, 강의용 자동 음성 파이프라인:

python src/cli/main.py pipeline inputclip/test_video.mp4 \
    --device cuda \
    --prompt "繁體中文" \
    --max-chars 16 \
    --pause 0.45 \
    --output-dir output/

3. Edge LLM 교정 (proofread)

로컬 Qwen2.5-3B-Instruct GGUF를 GPU 오프로드와 함께 실행하여 음성 인식 오류를 수정합니다:

python src/cli/main.py proofread output/video.srt \
    --gpu-layers -1 \
    --batch-size 8 \
    --output output/video.proofread.srt

4. GPU 하드섭 비디오 번-인 (burn)

스타일이 지정된 ASS 자막을 NVIDIA NVENC GPU 가속과 함께 비디오 프레임에 직접 번-인합니다:

# 인라인 CSS 문자열 사용 (불투명도, 외곽선, 글꼴, 박스 모델 패딩, 색상 지원)
python src/cli/main.py burn inputclip/test_video.mp4 output/lyrics.srt \
    --css "font-family: 'Noto Sans CJK TC'; font-size: 36px; color: #FFD700; opacity: 0.85; -webkit-text-stroke: 3px #000; text-shadow: 2px 2px 3px #000; padding: 40px 40px 60px 40px;" \
    -o output/final_burned.mp4

# 또는 외부 CSS 스타일시트 사용:
python src/cli/main.py burn inputclip/test_video.mp4 output/lyrics.srt \
    --css-file styles/youtube_style.css \
    -o output/final_burned.mp4

# 또는 명시적 플래그 사용:
python src/cli/main.py burn inputclip/test_video.mp4 output/lyrics.srt \
    --font "jf-openhuninn-2.0" \
    --size 38 \
    --color "#FFFFFF" \
    --opacity 0.9 \
    --outline 3.0 \
    --outline-color "#000000" \
    --direction horizontal \
    --valign bottom \
    --halign center

5. 폰트 관리 (fonts)

# 사용 가능, 설치됨 및 Windows 시스템 폰트 모두 나열
python src/cli/main.py fonts list

# 사전 설정 ID로 인기 오픈소스 폰트 설치:
# 옵션: openhuninn (粉圓體), lxgw-wenkai (霞鶩文楷), iansui (芫荽體), win-msjhbd (微軟正黑粗體)
python src/cli/main.py fonts install openhuninn

# URL 또는 로컬 파일에서 설치:
python src/cli/main.py fonts install https://example.com/font.ttf
python src/cli/main.py fonts install /path/to/custom_font.otf

🤖 자동화 레시피

레시피 1: 디렉터리의 모든 비디오 일괄 처리 (Bash)

#!/usr/bin/env bash
set -e
INPUT_DIR="./raw_videos"
OUTPUT_DIR="./dist_videos"
mkdir -p "$OUTPUT_DIR"

for video in "$INPUT_DIR"/*.mp4; do
  [ -f "$video" ] || continue
  filename=$(basename "$video")
  stem="${filename%.*}"
  lyrics="$INPUT_DIR/$stem.txt"
  
  echo "🚀 처리 중: $filename"
  
  if [ -f "$lyrics" ]; then
    # 스크립트 가사 파이프라인
    python3 src/cli/main.py luna "$video" "$lyrics" --output-dir "$OUTPUT_DIR/$stem" --llm local
    sub_file="$OUTPUT_DIR/$stem/lyrics.srt"
  else
    # 스크립트 없는 음성 파이프라인
    python3 src/cli/main.py pipeline "$video" -d cuda --output-dir "$OUTPUT_DIR/$stem"
    sub_file="$OUTPUT_DIR/$stem/$stem.srt"
  fi
  
  # 브랜딩 스타일로 하드섭 번-인
  python3 src/cli/main.py burn "$video" "$sub_file" \
    --css "font-size: 34px; color: #FFFFFF; opacity: 0.9; -webkit-text-stroke: 2.5px #000; text-shadow: 2px 2px #000;" \
    -o "$OUTPUT_DIR/${stem}_subtitled.mp4"
    
  echo "✔ 완료: $stem"
done

레시피 2: Python 자막 생성 스크립트

from pathlib import Path
from src.core.luna_pipeline import run_luna_pipeline
from src.core.video_burner import burn_subtitles_to_video
from src.schemas.subtitle import SubtitleStyle

media_file = "inputclip/test_video.mp4"
lyrics_file = "inputclip/audio-org.txt"
out_dir = Path("output_automation")

# 1. Luna 이중 검증 파이프라인 실행
track = run_luna_pipeline(
    audio_path=media_file,
    lyrics_source=lyrics_file,
    output_dir=str(out_dir),
    llm_provider="local"
)

# 2. 불투명도 및 외곽선이 있는 자막 스타일 정의
style = SubtitleStyle.from_css(
    "font-size: 36px; color: #FFD700; opacity: 0.85; -webkit-text-stroke: 3px #000;"
)

# 3. NVENC GPU로 직접 자막 번-인
burned_mp4 = burn_subtitles_to_video(
    video_path=media_file,
    subtitles_source=str(out_dir / "lyrics.srt"),
    output_path=str(out_dir / "burned_output.mp4"),
    style=style,
    use_gpu=True
)
print(f"번-인된 비디오 생성됨: {burned_mp4}")

레시피 3: REST API 통합 (FastAPI)

서버는 http://localhost:8000에서 실행됩니다:

  • Transcribe / Unscripted: POST /api/ai/transcribe (Form 필드 media_path=..., auto_proofread=true)
  • Align / Luna 파이프라인: POST /api/ai/align (JSON {"media_path": "...", "script_text": "...", "script_mode": "reference", "llm_provider": "local"})
  • CSS 파싱: POST /api/style/parse-css (JSON {"css": "font-size: 36px; opacity: 0.8;"})
  • 비디오 번-인: POST /api/burn (JSON {"video_path": "...", "subtitle_path": "...", "css": "..."})

🎨 CSS 박스 모델 및 ASS 스타일링 매핑

--css로 자막 스타일을 디자인할 때:

CSS 속성ASS 형식 변환참고
opacity: 0.85반전 알파 16진수 &H26FFFFFF&Alpha = round((1 - opacity) * 255). 0=불투명, 255=투명.
-webkit-text-stroke: 4px #000Outline: 2.0, OutlineColour: &H00000000&paint-order: stroke fill;와 함께 사용 시 외곽선이 바깥쪽으로만 확장됨.
text-shadow: 2px 2px 3px #000Shadow: 2.0, BackColour: &H80000000&더 큰 절대 축 오프셋을 사용함; 동일 축 CSS는 드리프트 없이 왕복 가능.
writing-mode: vertical-rl\N 줄바꿈이 있는 세로 열 레이아웃뷰포트 높이를 초과하면 오른쪽에서 왼쪽으로 자동 줄바꿈.
text-align: center/left/right9궁 정렬 매핑 (1~9)하단-중앙 = 2, 상단-중앙 = 8, 중간-중앙 = 5.
padding: 50px 40px 60px 40pxMarginV, MarginL, MarginRPlayRes 해상도를 기준으로 ASS 픽셀 여백으로 변환됨.

⚠️ 중요한 구현 참고 사항

  1. GPU 가속:
    • Whisper: 모든 스크립트 기반, 비스크립트 및 고정 타임라인 추론은 네이티브 Whisper large-v3-turbo를 사용합니다. 모델과 백엔드는 고정되어 있으므로 모델 또는 컴퓨팅 유형 옵션을 전달하지 마십시오.
    • 비디오 번-인: 기본값 use_gpu=True는 FFmpeg h264_nvenc를 시도합니다. 런타임에 NVENC를 사용할 수 없는 경우 CLI --cpu를 사용하여 libx264로 대체합니다.
  2. 가사 여러 줄 문자열 vs 파일 경로:
    • run_luna_pipeline은 파일 경로(.txt) 또는 원시 여러 줄 가사 문자열을 모두 허용합니다. CLI는 TXT 경로를 사용합니다. 여러 줄 문자열은 파일 시스템 경로 검사 없이 직접 구문 분석됩니다.
  3. 소스 자막 덮어쓰기 금지:
    • .srt 또는 .vtt를 생성할 때 출력은 대상 출력 디렉토리에 작성되거나, 동일한 이름의 파일이 존재하는 경우 .generated.srt 접미사가 추가됩니다.

관련 스킬