Community코딩 & 개발github.com

dsh-bilibili-subtitles

Bilibili 영상 링크(BV/av/ep/ss, b23.tv 단축 링크)나 로컬 동영상에서 자막을 추출하여 Markdown/Word/PDF/TXT/SRT 문서로 정리합니다. 플랫폼/외장 자막을 우선 사용하고, ASR/OCR은 최후의 수단으로 활용합니다.

dsh-bilibili-subtitles란 무엇인가요?

이 스킬은 Bilibili 영상이나 로컬 동영상에서 자막을 추출하여 다양한 문서 형식(Markdown, Word, PDF, TXT, SRT)으로 변환하는 전문 도구입니다. 핵심 원칙은 '기존 자막을 먼저 사용하고, 음성 인식(ASR)이나 OCR은 최후의 수단으로 활용'하는 것입니다. Bilibili 플랫폼 자막(AI 자막 포함)은 일반적으로 Whisper 음성 인식보다 품질이 높고 처리 속도가 빠르기 때문에, 무턱대고 영상/오디오를 다운로드하여 Whisper를 실행하지 않습니다. 이 스킬은 외장 자막 → Bilibili 플랫폼 자막 → 내장 자막 → OCR → Whisper 순서로 자막 소스를 자동으로 탐색하며, 각 단계에서 실패하면 다음 단계로 자동 폴백(fallback)합니다. 또한 자막 품질 보고서(quality.json)를 생성하여 커버리지, 신뢰도, 중복, 간격 등을 분석하고, 이중 언어 대조, 분할 영상(P) 병합, 용어 치환 등의 고급 기능을 제공합니다. DSH(Desktop Shell) 환경에서 실행되며, SESSDATA 쿠키를 통해 로그인 세션을 사용하면 Bilibili 플랫폼 자막에 접근할 수 있습니다.

지원 대상✓Claude Code~Codex CLI~Cursor
npx skills add Chenfan2/dsh-bilibili-subtitles

Installed? Explore more 코딩 & 개발 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

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

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

문서

dsh-bilibili-subtitles은(는) 무엇을 하나요?

Bilibili 영상 링크를 읽고 검색 가능하며 제공할 수 있는 자막 문서로 변환합니다.

핵심 원칙: 기존 자막을 먼저 확보하고, 그다음에 음성 인식이나 OCR을 고려하세요. 무턱대고 영상/오디오를 다운로드하여 Whisper를 실행하지 마십시오. Bilibili 플랫폼 자막(AI 자막 포함)은 일반적으로 품질이 더 좋고 처리 속도도 빠릅니다.

사용 시기

적용 가능:

  • 사용자가 Bilibili 영상 링크, BV 번호, av 번호, 애니메이션 ep/ss 링크 또는 b23.tv 단축 링크를 제공하며 "자막 추출/문서 정리/Word/Markdown 내보내기"를 요청하는 경우.
  • 사용자가 로컬 동영상과 외장 자막을 가지고 있으며, 이를 일괄 변환하여 문서로 만들고자 하는 경우.
  • 사용자가 타임스탬프, 이중 언어 대조, 분할 영상 병합이 포함된 자막 원고가 필요한 경우.
  • 사용자가 수동 교정이 필요할지 판단할 수 있는 자막 품질 보고서가 필요한 경우.

적용 불가:

  • 자막 "번역"이 필요한 경우: 이 스킬은 이중 언어 정렬만 수행하며, 기계 번역은 하지 않습니다.
  • 정확한 화자 분리가 필요한 경우: 자동 화자 분리(diarization)는 아직 활성화되지 않았습니다. 자막에 이미 있는 [화자] 표시만 유지합니다.
  • Bilibili 로그인/유료/지역 제한을 우회해야 하는 경우: 사용자에게 사용 권한이 있는 Cookie를 제공하도록 요청하거나, 로컬 파일을 대신 사용하십시오.

설치 및 호출

  • 플러그인: https://github.com/Chenfan2/dsh-bilibili-subtitles (DSH 데스크톱의 '플러그인 → 플러그인 추가'에서 주소를 붙여넣거나, dsh plugin --profile web add github:Chenfan2/dsh-bilibili-subtitles 실행).
  • 순수 스킬: 전체 디렉터리를 DSH skills 디렉터리에 복사하거나 install.ps1을 실행합니다.

설치 후 디렉터리 안에서 다음을 실행합니다:

python main.py "https://www.bilibili.com/video/BV1xx411c7mD" --format md,docx

임시로만 사용하려면 설치하지 않고 스킬 디렉터리에서 main.py를 직접 실행해도 됩니다.

한 줄 명령어

python main.py "https://www.bilibili.com/video/BV1xx411c7mD" --format md,docx

출력은 output/ 디렉터리에 저장됩니다:

  • 제목_BV번호.md
  • 제목_BV번호.docx
  • 제목_BV번호.quality.json (품질 보고서)
  • 제목_BV번호.segments.json (정제된 구조화된 자막)
  • _manifest.json (이번 실행의 전체 목록)

입력 / 출력 계약

입력

유형예시
Bilibili 영상https://www.bilibili.com/video/BV1xx411c7mD?p=2
BV / av 번호BV1xx411c7mD, av80433022
애니메이션https://www.bilibili.com/bangumi/play/ep123456, .../ss28747
단축 링크https://b23.tv/xxxxxx
로컬 동영상input.mp4, input.mkv
외장 자막--subtitle input.srt (.ass/.vtt/.json/.txt도 지원)
디렉터리/일괄python main.py ./videos --format md,docx

출력

  • 문서 파일 경로 (Markdown/Word/PDF/TXT/SRT).
  • 구조화된 자막: [{start, end, text, speaker?, lang?, confidence?, translation?}].
  • 품질 보고서: 자막 출처, 언어, 커버리지, 낮은 신뢰도 구간, 경고, 앞/중간/뒤 샘플.
  • 처리 시도 기록: 각 provider의 성공/실패/건너뜀 및 사유.

자막 출처 우선순위

다음 순서로 시도하며, 실패 시 명시적으로 비활성화하지 않는 한 자동으로 다음 단계로 넘어갑니다:

  1. 사용자 외장 자막 (--subtitle): 품질이 가장 높고 완전히 제어 가능합니다.
  2. Bilibili 플랫폼 자막 / AI 자막: x/player/v2 API를 통해 읽으며, SESSDATA가 필요합니다.
  3. 로컬 동영상 내장 자막: ffprobe로 감지하고 ffmpeg로 SRT 형식으로 추출합니다.
  4. 하드코딩 자막 OCR: 로컬 동영상만 해당되며, --ocr 옵션을 켜야 합니다. 실험적 기능입니다.
  5. Whisper 음성 인식: --asr 옵션을 켜거나 자동 폴백으로 사용됩니다. 처음 실행 시 모델을 다운로드합니다.

로그인하지 않은 경우, Bilibili는 일반적으로 자막 목록을 반환하지 않습니다. 이 경우 LOGIN_REQUIRED 오류가 발생하며, Cookie를 제공하거나 ASR을 활성화하라는提示이 표시됩니다. 이는 플랫폼 제한 사항이며 링크 오류가 아닙니다.

Bilibili 로그인 (플랫폼 자막 필수)

플랫폼 자막 API는 로그인 세션에서만 subtitle_url을 반환합니다. 명령 기록에 남지 않도록 환경 변수를 사용하는 것이 좋습니다:

$env:BILIBILI_SESSDATA = "자신의 SESSDATA"
python main.py "https://www.bilibili.com/video/BV1xx411c7mD" --format md,docx

획득 방법: 브라우저에서 bilibili.com에 로그인 → 개발자 도구 → Application/애플리케이션 → Cookies → bilibili.com → SESSDATA 값을 복사합니다.

다음 방식도 지원합니다:

python main.py URL --sessdata "SESSDATA 값"
python main.py URL --cookie "SESSDATA=...; bili_jct=..."
python main.py URL --cookies cookies.txt
  • Cookie는 계정 자격 증명과 동일하므로, 저장소, 문서 또는 공개 채널에 기록하지 마십시오.
  • 이 스킬은 메모리에서만 Cookie를 사용하며, 로그와 보고서에서는 마스킹 처리됩니다.
  • Cookie가 만료되면 다시 복사하여 사용하십시오.

자주 사용하는 매개변수

매개변수설명
--format md,docx,pdf,txt,srt,json출력 형식, 쉼표로 구분; 기본값 md
-o, --output PATH단일 입력 + 단일 형식일 때 출력 파일 지정
--out-dir DIR출력 디렉터리, 기본값 output
--title TEXT문서 제목 재정의 (기본값은 영상 제목/파일 이름 사용)
--subtitle PATH외장 자막 파일 또는 디렉터리 (최우선 순위)
--language zh선호하는 자막/인식 언어; 플랫폼 자막은 언어별로 매칭
--bilingual이중 언어 대조; 두 개의 자막 트랙이 있으면 시간별로 정렬, 단일 트랙이면 줄 단위로 분할 시도
--timestamps / --no-timestamps본문에 [00:12] 표시 여부, 기본값 표시
--merge-sentences / --no-merge-sentences잘린 짧은 문장 병합 여부, 기본값 병합
--no-auto-punctuationASR/OCR의 자동 구두점 추가 비활성화 (기본값 활성화)
--pages auto/all/1,3-5분할 영상(P) 선택; 기본값은 링크에 지정된 P만 처리, 지정되지 않으면 P1
--template default/minimal/파일.mdMarkdown 템플릿
--quality-report PATH품질 보고서 JSON 경로
--no-quality품질 보고서를 생성하지 않으며, 문서에 처리 정보도 첨부하지 않음
--glossary terms.json용어 치환, 예: {"DeepSeek":"심층구"}
--json-summarystdout에 기계가 읽을 수 있는 요약 출력 (agent가 읽기에 적합)
--asr / --no-asrWhisper 폴백 허용/금지; 기본값 자동 (설치된 경우에만 시도)
--asr-model smalltiny/base/small/medium; 기본값 small
--model-dir DIRWhisper 모델 캐시 디렉터리 (기본값 ./.vsub-models-cache)
--ocr로컬 동영상의 하드코딩 자막 OCR (실험적)
--ffmpeg PATHffmpeg/ffprobe 경로 지정
--strict입력 중 하나라도 실패하거나 품질이 fail이면 0이 아닌 종료 코드 반환

전체 매개변수: python main.py --help.

권장 워크플로우 (agent)

  1. 입력 판단:

    • Bilibili 링크/BV/av → 바로 실행.
    • 로컬 동영상 → 동일한 이름의 .srt/.vtt/.ass 파일이 있는지 확인, 있으면 --subtitle 우선; 없으면 내장 자막 시도.
    • 자막 파일만 있는 경우 → 직접 입력으로 사용 가능.
  2. 품질 보고서를 확인하지 않고 ASR을 실행하지 말고, 먼저 기본 출력으로 실행합니다:

    python main.py "<링크>" --format md,docx --out-dir output
    
  3. LOGIN_REQUIRED 오류 발생 시:

    • 사용자에게 플랫폼 자막을 이용하려면 SESSDATA가 필요하다고 알리고 설정 방법을 안내합니다. 반복해서 재시도하지 마십시오.
    • 사용자에게 Cookie가 없는 경우, 그때 --asr을 제안합니다 (처음 모델 다운로드, 시간 소요, 인식 오류 가능성 설명).
  4. <stem>.quality.json 파일 확인:

    • status=ok: 바로 전달.
    • status=warn: warnings를 확인하고, 특히 커버리지, 중복, 낮은 신뢰도에 주의하며 전달 시 참고 사항을 알립니다.
    • status=fail: 성공인 척하지 마십시오. 실패 원인을 보고하고 외장 자막/ASR/OCR을 제안합니다.
  5. present를 사용하여 .md / .docx 파일을 최종 파일로 전달합니다. 품질 보고서는 사용자가 필요로 할 때만 첨부합니다.

실행 환경:

  • load_workspace_dependencies가 반환하는 Python을 우선 사용합니다 (python-docx 포함).

  • Windows PowerShell 호출 예시:

    & "C:\...\python.exe" main.py "<링크>" --format md,docx --out-dir output
    
  • 모든 출력 및 임시 파일은 세션 작업 공간 내에 저장해야 합니다. 시스템 임시 디렉터리를 사용하지 마십시오 (샌드박스에서 거부될 수 있음).

품질 보고서 필드

{
  "status": "ok | warn | fail",
  "score": 96.5,
  "source": "bilibili",
  "language": "zh",
  "segments": 320,
  "paragraphs": 86,
  "duration": 1260.0,
  "duration_covered": 0.96,
  "coverage_span": 0.99,
  "overlaps": 0,
  "low_confidence_segments": 3,
  "duplicate_segments": 1,
  "gaps_over_10s": 2,
  "warnings": ["..."],
  "samples": {"head": [], "middle": [], "tail": []}
}
  • duration_covered: 전체 영상 길이 대비 자막 커버리지. 인트로/엔딩 광고가 제거되면 낮아질 수 있음.
  • coverage_span: 첫 자막과 마지막 자막 사이의 구간 대비 커버리지. "말하는 부분이 덮였는지"를 더 잘 반영합니다.
  • samples: 앞/중간/뒤 각각 최대 5개 구간 샘플. 수동 확인에 유용합니다.
  • status=fail의 일반적인 원인: 세그먼트 없음, 커버리지 30% 미만, 모든 분할 영상 실패.

실패 및 폴백

상황동작
외장 자막 파싱 실패실패 기록 후 플랫폼/내장 자막 계속 시도
플랫폼 자막 LOGIN_REQUIREDSESSDATA 설정 방법 안내; faster-whisper가 설치되고 ASR이 허용되면 자동 음성 인식
플랫폼에 자막 트랙 없음NO_SUBTITLE 안내; --asr 또는 --subtitle 사용 가능
내장 자막이 PGS/VobSub 비트맵SRT로 직접 변환 불가; OCR 또는 외장 자막 사용 권장
ASR 미설치건너뛰고 pip install faster-whisper 메시지 출력; 조용히 실패하지 않음
특정 출력 형식 실패다른 형식은 계속 생성; quality.warnings에 기록; 모두 실패해야 RENDER_FAILED 보고
일괄 처리 중 일부 실패성공한 항목은 계속 출력; _manifest.json 및 *.error.json에 실패 기록

종료 코드:

  • 0 성공 (일괄 처리 시 하나 이상 성공)
  • 2 입력/링크/API/파싱 오류
  • 3 자막 없음, 로그인 필요, 품질 실패
  • 4 종속성 누락 (ffmpeg/Whisper/docx 등)
  • 5 문서 렌더링 실패
  • 1 예상치 못한 오류

예시

# 기본: 플랫폼 자막 → Markdown + Word
python main.py "https://www.bilibili.com/video/BV1xx411c7mD" --format md,docx

# Word만, 파일 이름 지정
python main.py "BV1xx411c7mD" --format docx -o "논문_노트.docx"

# 다중 분할 영상 + 타임스탬프 + 품질 보고서
python main.py "https://www.bilibili.com/video/BV1xx411c7mD?p=1" --pages all --format md

# 외장 자막 우선
python main.py "input.mp4" --subtitle "input.srt" --format md,docx

# 이중 언어 (플랫폼에 두 개의 자막 트랙이 있을 때 자동 정렬)
python main.py "BV1xx411c7mD" --bilingual --language zh --format md,docx

# 로그인 없이, ASR 폴백 사용 (처음 모델 다운로드)
python main.py "BV1xx411c7mD" --asr --asr-model small --format md,docx

# 디렉터리 일괄 처리
python main.py "./videos" --format md,docx --out-dir output/batch

# 로컬 하드코딩 자막 OCR (실험적)
python main.py "input.mp4" --ocr --ocr-fps 2 --format md

한계

  • 플랫폼 자막의 가용성은 영상, 계정, 지역 및 업로더 설정에 따라 달라집니다. 이 스킬은 권한을 우회할 수 없습니다.
  • AI 자막 자체에 오타, 누락된 문장, 시간 축 오류가 있을 수 있습니다. 품질 보고서는 이를提示할 수 있지만, 수동 교정을 대체할 수는 없습니다.
  • 이중 언어는 "시간 정렬"이지 "번역"이 아닙니다. 두 자막 트랙의 언어가 다를 때만 대조를 표시합니다.
  • 자동 화자 분리는 구현되지 않았습니다. 자막에 있는 [홍길동], 【홍길동】, 홍길동: 등의 표시만 파싱합니다.
  • OCR은 로컬 동영상만 지원하며, 기본적으로 하단 30% 영역을 스캔합니다. 애니메이션/세로 화면/자막 위치 변동 시 --ocr-crop 또는 --ocr-full-frame 조정이 필요할 수 있습니다.
  • PDF는 LibreOffice 또는 reportlab이 필요합니다. 그렇지 않으면 명확한 오류 메시지가 표시되며, md/docx 출력에는 영향이 없습니다.
  • 긴 영상의 ASR은 매우 느릴 수 있습니다. small 모델의 첫 다운로드 크기는 약 460MB입니다.

저작권 및 개인정보 보호

  • 사용자가 사용할 권리가 있는 영상/자막만 처리하십시오. 저작권으로 보호된 콘텐츠를 대량으로 수집하는 데 이 스킬을 사용하지 마십시오.
  • 자막 문서에는 원본 영상 제목, 업로더, 링크가 포함되어 출처를 추적할 수 있습니다.
  • Cookie, 서명된 CDN URL은 로그/품질 보고서에 기록되지 않습니다. 그럼에도 불구하고 사용자가 공개된 장소에 Cookie를 붙여넣지 않도록 권장합니다.
  • 임시 오디오/프레임 추출 파일은 기본적으로 출력 디렉터리의 .vsub-tmp에 저장되며, 실행 종료 시 자동으로 정리됩니다. --keep-temp를 사용하면 문제 해결을 위해 보관할 수 있습니다.

파일 구조

dsh-bilibili-subtitles/
├── SKILL.md
├── README.md
├── main.py                  # CLI 진입점
├── vsub/
│   ├── bilibili.py          # URL/API/자막/오디오
│   ├── input_adapter.py     # 입력 어댑터
│   ├── pipeline.py          # 5단계 파이프라인 오케스트레이션
│   ├── providers/           # external/bilibili/embedded/ocr/asr
│   ├── parsers/             # srt/vtt/ass/bilibili-json/plain
│   ├── cleaners/            # 정제, 병합, 이중 언어, 용어
│   ├── renderers/           # md/docx/pdf/txt/srt/json
│   └── quality.py           # 품질 검증
├── templates/
├── tests/
└── requirements.txt

관련 스킬