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의 성공/실패/건너뜀 및 사유.
자막 출처 우선순위
다음 순서로 시도하며, 실패 시 명시적으로 비활성화하지 않는 한 자동으로 다음 단계로 넘어갑니다:
- 사용자 외장 자막 (
--subtitle): 품질이 가장 높고 완전히 제어 가능합니다. - Bilibili 플랫폼 자막 / AI 자막:
x/player/v2API를 통해 읽으며,SESSDATA가 필요합니다. - 로컬 동영상 내장 자막:
ffprobe로 감지하고ffmpeg로 SRT 형식으로 추출합니다. - 하드코딩 자막 OCR: 로컬 동영상만 해당되며,
--ocr옵션을 켜야 합니다. 실험적 기능입니다. - 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-punctuation | ASR/OCR의 자동 구두점 추가 비활성화 (기본값 활성화) |
--pages auto/all/1,3-5 | 분할 영상(P) 선택; 기본값은 링크에 지정된 P만 처리, 지정되지 않으면 P1 |
--template default/minimal/파일.md | Markdown 템플릿 |
--quality-report PATH | 품질 보고서 JSON 경로 |
--no-quality | 품질 보고서를 생성하지 않으며, 문서에 처리 정보도 첨부하지 않음 |
--glossary terms.json | 용어 치환, 예: {"DeepSeek":"심층구"} |
--json-summary | stdout에 기계가 읽을 수 있는 요약 출력 (agent가 읽기에 적합) |
--asr / --no-asr | Whisper 폴백 허용/금지; 기본값 자동 (설치된 경우에만 시도) |
--asr-model small | tiny/base/small/medium; 기본값 small |
--model-dir DIR | Whisper 모델 캐시 디렉터리 (기본값 ./.vsub-models-cache) |
--ocr | 로컬 동영상의 하드코딩 자막 OCR (실험적) |
--ffmpeg PATH | ffmpeg/ffprobe 경로 지정 |
--strict | 입력 중 하나라도 실패하거나 품질이 fail이면 0이 아닌 종료 코드 반환 |
전체 매개변수: python main.py --help.
권장 워크플로우 (agent)
-
입력 판단:
- Bilibili 링크/BV/av → 바로 실행.
- 로컬 동영상 → 동일한 이름의
.srt/.vtt/.ass파일이 있는지 확인, 있으면--subtitle우선; 없으면 내장 자막 시도. - 자막 파일만 있는 경우 → 직접 입력으로 사용 가능.
-
품질 보고서를 확인하지 않고 ASR을 실행하지 말고, 먼저 기본 출력으로 실행합니다:
python main.py "<링크>" --format md,docx --out-dir output -
LOGIN_REQUIRED오류 발생 시:- 사용자에게 플랫폼 자막을 이용하려면
SESSDATA가 필요하다고 알리고 설정 방법을 안내합니다. 반복해서 재시도하지 마십시오. - 사용자에게 Cookie가 없는 경우, 그때
--asr을 제안합니다 (처음 모델 다운로드, 시간 소요, 인식 오류 가능성 설명).
- 사용자에게 플랫폼 자막을 이용하려면
-
<stem>.quality.json파일 확인:status=ok: 바로 전달.status=warn:warnings를 확인하고, 특히 커버리지, 중복, 낮은 신뢰도에 주의하며 전달 시 참고 사항을 알립니다.status=fail: 성공인 척하지 마십시오. 실패 원인을 보고하고 외장 자막/ASR/OCR을 제안합니다.
-
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_REQUIRED | SESSDATA 설정 방법 안내; 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