CommunityCoding & Developmentgithub.com

dsh-bilibili-subtitles

Extract subtitles from Bilibili video links (BV/av/ep/ss, b23.tv short links) or local videos and organize them into Markdown/Word/PDF/TXT/SRT documents. Prioritizes platform/external subtitles, with ASR/OCR only as a fallback.

What is dsh-bilibili-subtitles?

This skill provides a complete pipeline for extracting and structuring subtitles from Bilibili videos and local media files. It intelligently prioritizes high-quality platform subtitles, external subtitle files, and embedded tracks over slower ASR or OCR methods, ensuring fast and accurate results. Input can be a standard Bilibili link, BV/av/ep/ss number, b23.tv short link, a local video file, or even a batch directory. Output is generated in multiple formats including Markdown, Word, PDF, TXT, and SRT, accompanied by a structured JSON segments file and a quality report that tracks coverage, confidence, and potential issues. The skill supports bilingual alignment when two subtitle tracks are available, multi-part videos, session-based Bilibili authentication (via SESSDATA cookie), and numerous options for templates, timestamps, punctuation, and glossary replacement. It is designed to be used both as an independent CLI tool (via python main.py) and as a DSH plugin/skill integrated into the DSH desktop or web agent environment.

Works with✓Claude Code~Codex CLI~Cursor
npx skills add Chenfan2/dsh-bilibili-subtitles

Installed? Explore more Coding & Development skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Ask in your favorite AI

Open a new chat with this agent skill pre-loaded.

Documentation

What does dsh-bilibili-subtitles do?

Turn a Bilibili video link into a readable, searchable, and deliverable subtitle document.

Core principle: Prefer existing subtitles first, only fall back to ASR or OCR. Do not immediately download video/audio for Whisper; Bilibili platform subtitles (including AI subtitles) are typically higher quality and faster.

When to Use

Use this skill when:

  • The user provides a Bilibili video link, BV/av number, episode/ep/ss link for anime, or b23.tv short link and asks to "extract subtitles" / "create a document" / "export to Word/Markdown".
  • The user has a local video file with external subtitles that need batch conversion to documents.
  • The user needs timestamped, bilingual aligned, or multi-P merged subtitle transcripts.
  • The user requires a subtitle quality report to assess if manual proofreading is worthwhile.

Do not use for:

  • Translating subtitles: this skill only performs bilingual alignment, not machine translation.
  • Precise speaker diarization: automatic diarization is not enabled; only existing [speaker] markers in subtitles are preserved.
  • Bypassing Bilibili login/pay/region restrictions: ask the user to provide cookies they are authorized to use, or switch to local files.

Installation & Invocation

  • Plugin: https://github.com/Chenfan2/dsh-bilibili-subtitles (In DSH desktop, go to "Plugins → Add Plugin" and paste the URL, or run dsh plugin --profile web add github:Chenfan2/dsh-bilibili-subtitles).
  • Plain skill: Copy the entire directory into DSH's skills directory (or run install.ps1).

After installation, execute from within the directory:

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

If you only need it temporarily, you can run main.py directly from the skill directory without full installation.

One-Command Example

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

Outputs in output/:

  • Title_BVnumber.md
  • Title_BVnumber.docx
  • Title_BVnumber.quality.json (quality report)
  • Title_BVnumber.segments.json (cleaned, structured subtitles)
  • _manifest.json (summary of the run)

Input / Output Contract

Inputs

TypeExample
Bilibili videohttps://www.bilibili.com/video/BV1xx411c7mD?p=2
BV / av numberBV1xx411c7mD, av80433022
Anime episodehttps://www.bilibili.com/bangumi/play/ep123456, .../ss28747
Short linkhttps://b23.tv/xxxxxx
Local videoinput.mp4, input.mkv
External subtitles--subtitle input.srt (also supports .ass / .vtt / .json / .txt)
Directory/batchpython main.py ./videos --format md,docx

Outputs

  • Document file paths (Markdown/Word/PDF/TXT/SRT).
  • Structured subtitles: [{start, end, text, speaker?, lang?, confidence?, translation?}].
  • Quality report: subtitle source, language, coverage, low-confidence segments, warnings, head/middle/tail samples.
  • Processing attempt log: per-provider success/failure/skip with reasons.

Subtitle Source Priority

The following sources are tried in order; failures cause automatic fallback unless explicitly disabled:

  1. User external subtitles (--subtitle): Highest quality, fully controllable.
  2. Bilibili platform subtitles / AI subtitles: Retrieved via x/player/v2; requires SESSDATA.
  3. Local video embedded subtitles: Detected with ffprobe, extracted with ffmpeg to SRT.
  4. Hardcoded subtitle OCR: Local video only, enabled via --ocr; experimental.
  5. Whisper ASR: Enabled with --asr or as automatic fallback; downloads model on first use.

Without login, Bilibili typically does not return subtitle lists. In this case, you will get LOGIN_REQUIRED along with a prompt to provide a Cookie or enable ASR. This is a platform restriction, not a link error.

Bilibili Login (Required for Platform Subtitles)

The platform subtitle API only returns subtitle_url for logged-in sessions. Environment variables are recommended to avoid exposing credentials in command history:

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

How to obtain: Log in to bilibili.com in your browser → Developer Tools → Application → Cookies → bilibili.com → Copy the value of SESSDATA.

Alternative methods:

python main.py URL --sessdata "SESSDATA value"
python main.py URL --cookie "SESSDATA=...; bili_jct=..."
python main.py URL --cookies cookies.txt
  • Cookies are equivalent to account credentials: do not commit them to repositories, documents, or public channels.
  • This skill uses cookies in memory only; logs and reports are sanitized.
  • When cookies expire, re-copy them from the browser.

Common Parameters

ParameterDescription
--format md,docx,pdf,txt,srt,jsonOutput formats, comma separated; default md
-o, --output PATHSpecify output file when single input + single format
--out-dir DIROutput directory, default output
--title TEXTOverride document title (default is video title / filename)
--subtitle PATHExternal subtitle file or directory (highest priority)
--language zhPreferred subtitle/transcription language; platform subtitles matched by language
--bilingualBilingual alignment: if two tracks exist, align by time; with single track, try line-based splitting
--timestamps / --no-timestampsShow [00:12] timestamps in body; default on
--merge-sentences / --no-merge-sentencesMerge hard-cut short sentences; default on
--no-auto-punctuationDisable automatic punctuation for ASR/OCR (default on)
--pages auto/all/1,3-5Select multiple parts; default processes only the part specified in URL, otherwise P1
--template default/minimal/file.mdMarkdown template
--quality-report PATHPath for quality report JSON
--no-qualitySkip generating quality report; also omit processing metadata from documents
--glossary terms.jsonTerm replacement, e.g., {"DeepSeek":"深度求索"}
--json-summaryOutput machine-readable summary to stdout (for agent consumption)
--asr / --no-asrEnable / disable Whisper fallback; default auto (only if already installed)
--asr-model smalltiny / base / small / medium; default small
--model-dir DIRWhisper model cache directory (default ./.vsub-models-cache)
--ocrPerform OCR on hardcoded subtitles in local video (experimental)
--ffmpeg PATHSpecify ffmpeg / ffprobe path
--strictReturn non-zero exit code if any input fails or quality is fail

Full parameter list: python main.py --help.

Recommended Workflow (for Agents)

  1. Determine input type:

    • Bilibili link / BV / av → run directly.
    • Local video → check for a matching .srt / .vtt / .ass file; if found, use --subtitle; otherwise try embedded subtitles.
    • Subtitle file only → can be used directly as input.
  2. Run default output first; do not enable ASR before examining the quality report:

    python main.py "<link>" --format md,docx --out-dir output
    
  3. If LOGIN_REQUIRED is returned:

    • Inform the user that platform subtitles require SESSDATA, and provide setup instructions; do not retry repeatedly.
    • If the user does not have a cookie, suggest --asr (explaining the model download, time cost, and potential recognition errors).
  4. Inspect <stem>.quality.json:

    • status=ok: deliver directly.
    • status=warn: check warnings (especially coverage, overlaps, low confidence); include a note in the delivery summary.
    • status=fail: do not pretend success; report the failure reason and suggest external subtitles / ASR / OCR.
  5. Use present to deliver the .md / .docx file as the final artifact; attach the quality report only if the user requests it.

Execution environment:

  • Prefer using the Python returned by load_workspace_dependencies (it includes python-docx).

  • Windows PowerShell invocation:

    & "C:\...\python.exe" main.py "<link>" --format md,docx --out-dir output
    
  • All outputs and temp files must be placed inside the session workspace; do not use system temp directories (may be blocked by sandbox).

Quality Report Fields

{
  "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: Relative to full video duration; may be lower if intro/outro ads were removed.
  • coverage_span: Relative to content interval between first and last subtitle; better reflects whether speech portions are covered.
  • samples: Up to 5 segments each from head, middle, and tail for manual spot-checking.
  • Common status=fail reasons: no segments, coverage below 30%, all parts failed.

Failures & Fallback

SituationBehavior
External subtitle parse failureLog failure, continue to platform/embedded subtitles
Platform subtitle LOGIN_REQUIREDPrompt to set SESSDATA; if faster-whisper is installed and ASR allowed, automatically transcribe
No platform subtitle trackPrompt NO_SUBTITLE; can try --asr or --subtitle
Embedded subtitle is PGS/VobSub bitmapCannot convert directly to SRT; suggest OCR or external subtitles
ASR not installedSkip and give pip install faster-whisper; does not silently fail
One output format failsOther formats continue; recorded in quality.warnings; only report RENDER_FAILED if all fail
Batch partial failuresSuccessful items still output; failures recorded in _manifest.json and *.error.json

Exit codes:

  • 0 Success (batch: at least one succeeded)
  • 2 Input/link/API/parse error
  • 3 No subtitles, login required, quality failure
  • 4 Missing dependency (ffmpeg/Whisper/docx, etc.)
  • 5 Document rendering failure
  • 1 Unexpected error

Examples

# Basic: platform subtitles → Markdown + Word
python main.py "https://www.bilibili.com/video/BV1xx411c7mD" --format md,docx

# Just Word, with custom filename
python main.py "BV1xx411c7mD" --format docx -o "PaperNotes.docx"

# Multi-part + timestamps + quality report
python main.py "https://www.bilibili.com/video/BV1xx411c7mD?p=1" --pages all --format md

# External subtitles priority
python main.py "input.mp4" --subtitle "input.srt" --format md,docx

# Bilingual (auto-align when platform has two tracks)
python main.py "BV1xx411c7mD" --bilingual --language zh --format md,docx

# No login, fallback to ASR (downloads model first time)
python main.py "BV1xx411c7mD" --asr --asr-model small --format md,docx

# Batch directory
python main.py "./videos" --format md,docx --out-dir output/batch

# Local hardcoded subtitle OCR (experimental)
python main.py "input.mp4" --ocr --ocr-fps 2 --format md

Limitations

  • Platform subtitle availability depends on the video, account, region, and uploader settings; this skill cannot bypass permissions.
  • AI subtitles may contain errors, missing sentences, or timeline drift; the quality report can only flag issues, not replace manual proofreading.
  • Bilingual mode uses "time alignment", not translation; it only aligns tracks in different languages.
  • Automatic speaker diarization is not implemented; only existing markers like [Zhang San], 【Zhang San】, Zhang San: are parsed.
  • OCR applies only to local videos, by default the bottom 30% of the frame; for animations, vertical videos, or drifting subtitle position, adjust with --ocr-crop or --ocr-full-frame.
  • PDF output requires LibreOffice or reportlab; otherwise, a clear error is thrown without affecting md/docx.
  • ASR for long videos may be slow; the small model first download is about 460MB.

Copyright & Privacy

  • Only process videos/subtitles the user has rights to; do not use this skill to bulk scrape copyrighted content.
  • Subtitle documents retain the original video title, uploader, and link for traceability.
  • Cookies and signed CDN URLs are not written to logs/quality reports; it is still recommended that users not paste cookies in public.
  • Temporary audio/frame files are stored by default under .vsub-tmp in the output directory and are automatically cleaned after execution; use --keep-temp to retain for debugging.

File Structure

dsh-bilibili-subtitles/
├── SKILL.md
├── README.md
├── main.py                  # CLI entry point
├── vsub/
│   ├── bilibili.py          # URL/API/subtitles/audio
│   ├── input_adapter.py     # Input adaptation
│   ├── pipeline.py          # Five-layer pipeline orchestration
│   ├── providers/           # external/bilibili/embedded/ocr/asr
│   ├── parsers/             # srt/vtt/ass/bilibili-json/plain
│   ├── cleaners/            # cleaning, merging, bilingual, glossary
│   ├── renderers/           # md/docx/pdf/txt/srt/json
│   └── quality.py           # Quality validation
├── templates/
├── tests/
└── requirements.txt

Related Skills