Agent skill

Bilibili Page Reader

by Misaka-Mikoto-Tech in Misaka-Mikoto-Tech/agent-skills

Get content from Bilibili videos: official subtitles, danmaku (density/peaks/sample), comments.

MITAuto-check passedMedia & Creative

Install Bilibili Page Reader

skills CLI
$ npx skills add Misaka-Mikoto-Tech/agent-skills --skill bilibili-page-reader -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install Misaka-Mikoto-Tech/agent-skills bilibili-page-reader --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/Misaka-Mikoto-Tech/agent-skills.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/bilibili-page-reader .claude/skills/bilibili-page-reader && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
bilibili-page-reader
GitHub stars
278
Token cost
~3.6k tokens
SKILL.md length
680 words
Files
4
Skills in repo
3
Repo updated
First seen
Licence
MIT

At a glance

Get content from Bilibili videos: official subtitles, danmaku (density/peaks/sample), comments.

  • Works in 2 steps: Subtitles (preferred — via BE) → Audio Transcription Fallback (when no…
  • Tasks that involve Transcription
  • SKILL.md covers Core Rules, Workflow Overview, Phase 1: Subtitles (preferred… and Phase 2: Audio Transcription…, plus 4 more sections
  • Runs Python scripts from its folder; calls node, ffmpeg and python; reaches bilibili.com and api.bilibili.com

What it does

Bilibili Page Reader is an agent skill from Misaka-Mikoto-Tech/agent-skills. Get content from Bilibili videos: official subtitles, danmaku (density/peaks/sample), comments. When no subtitles exist (no 投稿字幕), fall back to downloading audio + ASR transcription via FunASR.

Its SKILL.md is about 3.6k tokens, which your agent loads only when the skill is triggered. The skill folder holds 4 other files (for example `agents/openai.yaml`, `audio2srt.py` and `clean_srt.py`).

It sits in Media & Creative, covering Transcription. It works with Bilibili, PowerShell, Node.js and Python. The repository describes itself as: Reusable AI agent skills for Codex, including a PowerShell skill for safe Windows command invocation and optional MCP utilities. The licence is MIT.

When your agent uses it

  • Tasks that involve Transcription

Example prompts

  • “/bilibili-page-reader”

Requirements

  • Python 3
  • Node.js

Workflow steps

2 steps, taken from the step headings in SKILL.md.

  1. Subtitles (preferred — via BE)
  2. Audio Transcription Fallback (when no subtitles exist)

What it can do on your machine

Read from SKILL.md and the folder at commit 711abaf. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Ships script files (Python), which the agent can run.

    Shell commands in SKILL.md call:

    • node
    • ffmpeg
    • python

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Hosts in commands or code, which the agent is likely to contact:

    • bilibili.com
    • api.bilibili.com

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Bilibili Page Reader loads about 3.6k tokens when it runs. Until then it costs about 54 tokens; SKILL.md has 680 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~54
When it runs · the whole SKILL.md, loaded when a task matches
~3.6k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from Misaka-Mikoto-Tech/agent-skills at commit 711abaf, republished under its MIT licence (© Misaka-Mikoto-Tech). 680 words, ~3,618 tokens.

Download SKILL.mdSave it as .claude/skills/bilibili-page-reader/SKILL.md (or your agent's skills folder). This skill also uses 3 other files; get the full folder from GitHub.
name
bilibili-page-reader
description
Get content from Bilibili videos: official subtitles, danmaku (density/peaks/sample), comments. When no subtitles exist (no 投稿字幕), fall back to downloading audio + ASR transcription via FunASR.

Bilibili Page Reader

Core Rules

  • Browser access via kimi-webbridge for page state, login-only data, Bilibili Evolved (BE) providers.
  • Do not click BE download buttons. Call providers directly via evaluate.
  • Always use a named session. A session-less evaluate may land on a different tab and silently return wrong data.
  • Network calls outside the browser (audio download, playurl API) use Node.js — PowerShell's curl.exe and Python's requests both get blocked by Bilibili CDN TLS fingerprinting on this platform.

Workflow Overview

                    ┌─ BE downloadSubtitles provider ──→ 投稿字幕 (timestamps)
                    │
BiliBili video ───┼─ BE downloadDanmaku provider ────→ danmaku density/peaks/sample
                    │
                    └─ No subtitles? ──→ Audio transcription fallback
                                         1. Get audio stream URL (Node.js → playurl API)
                                         2. Download .m4s audio
                                         3. ffmpeg → .m4a
                                         4. FunASR paraformer-zh → SRT with timestamps

Phase 1: Subtitles (preferred — via BE)

Use the one-shot evaluate below. It returns both subtitles and danmaku in a single call.

Setup
bash
~/.kimi-webbridge/bin/kimi-webbridge status
json
{"action":"navigate","args":{"url":"https://www.bilibili.com/video/BV.../","newTab":true},"session":"bilibili"}

Wait 2–3 seconds for BE to fully initialize.

One-shot evaluate
js
(async () => {
  const pa = window.bilibiliEvolved.pluginApis;

  // ── Identifiers ──
  const s = window.__INITIAL_STATE__ || {};
  const vd = s.videoData || {};
  const bvid = vd.bvid || s.bvid || location.pathname.match(/BV[\w]+/)?.[0];
  const aid = vd.aid || s.aid;
  const pages = vd.pages || [];
  const p = parseInt(new URLSearchParams(location.search).get('p') || '1') - 1;
  const cid = pages[p]?.cid || vd.cid || s.cid || pages[0]?.cid;
  const title = vd.title || document.title;

  // ── Register providers ──
  pa.registerData('downloadVideo.assets', []);

  // ── Poll for providers (downloadDanmaku loads async, ~1-2s) ──
  function getProviders() {
    const g = pa.getData('downloadVideo.assets');
    return Array.isArray(g[0]) ? g.flat() : g;
  }
  const deadline = Date.now() + 5000;
  let providers = getProviders();
  while (!providers.find(p => p.name === 'downloadDanmaku') && Date.now() < deadline) {
    await new Promise(r => setTimeout(r, 300));
    providers = getProviders();
  }

  // ── Subtitles: try 投稿字幕 first ──
  let subResult = { count: 0, text: '', source: 'none' };
  const subProvider = providers.find(p => p.name === 'downloadSubtitles');
  if (subProvider) {
    try {
      const subAssets = await subProvider.getAssets([{ input: {} }], { type: 'json', enabled: true });
      const subRaw = subAssets[0].data;
      let subText;
      if (subRaw instanceof Blob) {
        const buf = await subRaw.arrayBuffer();
        subText = new TextDecoder('utf-8').decode(buf);
      } else {
        subText = String(subRaw);
      }
      const subtitles = JSON.parse(subText);
      const subLines = subtitles.map(s => {
        const totalSec = Math.floor(s.from);
        const h = Math.floor(totalSec / 3600);
        const m = Math.floor((totalSec % 3600) / 60);
        const sec = String(totalSec % 60).padStart(2, '0');
        if (h > 0) {
          return '[' + h + ':' + String(m).padStart(2, '0') + ':' + sec + '] ' + s.content;
        }
        return '[' + m + ':' + sec + '] ' + s.content;
      });
      subResult = { count: subtitles.length, text: subLines.join('\n'), source: '投稿字幕' };
    } catch(e) {
      subResult = { count: 0, text: '', source: '投稿字幕_error' };
    }
  }

  // ── Danmaku: analyze in-page, summary only ──
  const dmk = providers.find(p => p.name === 'downloadDanmaku');
  const dmkAssets = await dmk.getAssets(
    [{ input: { aid: String(aid), cid: String(cid) } }],
    { type: 'json', enabled: true }
  );
  const dmkRaw = dmkAssets[0].data;
  let dmkText;
  if (dmkRaw instanceof Blob) {
    const buf = await dmkRaw.arrayBuffer();
    dmkText = new TextDecoder('utf-8').decode(buf);
  } else {
    dmkText = String(dmkRaw);
  }
  const danmaku = JSON.parse(dmkText);

  // Time density: 30s buckets
  const bucketSize = 30;
  const buckets = {};
  for (const d of danmaku) {
    const b = Math.floor(d.progress / 1000 / bucketSize) * bucketSize;
    buckets[b] = (buckets[b] || 0) + 1;
  }
  const density = Object.entries(buckets)
    .map(([t, c]) => [Number(t), c])
    .sort((a, b) => a[0] - b[0]);

  // Top 5 peak moments
  const peaks = density.slice().sort((a, b) => b[1] - a[1]).slice(0, 5);

  // Stratified sample: up to 40 entries across full timeline
  const sampleCount = Math.min(40, danmaku.length);
  const step = Math.max(1, Math.floor(danmaku.length / sampleCount));
  const danmakuSample = [];
  for (let i = 0; i < danmaku.length && danmakuSample.length < sampleCount; i += step) {
    danmakuSample.push({
      t: Math.floor(danmaku[i].progress / 1000),
      c: danmaku[i].content
    });
  }

  const totalDuration = danmaku.length > 0
    ? Math.max(...danmaku.map(d => d.progress)) : 0;

  // ── Return ──
  return JSON.stringify({
    ok: true, bvid, aid: Number(aid), cid: Number(cid), p: p + 1, title,
    sub: subResult,
    dmk: {
      count: danmaku.length,
      timeSpanSec: Math.floor(totalDuration / 1000),
      density,
      peakMoments: peaks.map(pk => ({ timeSec: pk[0], count: pk[1] })),
      sample: danmakuSample
    }
  });
})()
Response shape
json
{
  "sub": {
    "count": 243,
    "text": "[0:00] 大家好\n[0:01] 这个视频...",
    "source": "投稿字幕"
  },
  "dmk": {
    "count": 247,
    "density": [[0,11], [30,2], ...],
    "peakMoments": [{"timeSec": 1170, "count": 16}, ...],
    "sample": [{"t": 0, "c": "辛苦惹!"}, ...]
  }
}

If sub.count === 0, no 投稿字幕 was available. Proceed to Phase 2 below.


Phase 2: Audio Transcription Fallback (when no subtitles exist)

Use when Phase 1 returns sub.count === 0. This replaces the old "AI subtitle API" fallback which is unreliable — the /x/player/v2 API often returns stale/empty subtitle data.

Why this approach

The Bilibili CDN uses TLS fingerprinting that blocks curl and Python requests. Reliable paths:

MethodWorks?Notes
curl.exe with browser headers❌ Exit code 35SSL blocked
Python requests / urllib❌ BlockedSame reason
Node.js https.get()✅Use User-Agent + Referer headers
Browser fetch (in-page)✅ but evaluate timeout <1sOnly for fast API calls
Node.js to download audio✅Backup URL is most stable
Step 1: Get audio stream URL via Node.js
bash
node -e "
const https = require('https');
const url = 'https://api.bilibili.com/x/player/playurl' +
  '?bvid=BVxxxxxxxxx&cid=xxxxxxxxx&qn=0&fnval=4048&fourk=1&platform=web';
https.get(url, {
  headers: {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
    'Referer': 'https://www.bilibili.com/'
  }
}, (res) => {
  let data = '';
  res.on('data', (chunk) => { data += chunk; });
  res.on('end', () => {
    const d = JSON.parse(data);
    if (d.code === 0 && d.data && d.data.dash && d.data.dash.audio) {
      const audio = d.data.dash.audio;
      const best = audio.reduce((a,b) => a.bandwidth > b.bandwidth ? a : b);
      console.log(best.baseUrl + '|' + (best.backupUrl ? best.backupUrl[0] || '' : ''));
    } else {
      console.log('ERROR: no dash audio data');
    }
  });
}).on('error', (e) => { console.log('ERROR: ' + e.message); });
"

The fnval=4048 flag requests DASH format with separate audio/video streams.

Step 2: Download audio (use backup URL — most reliable)
bash
node -e "
const https = require('https');
const fs = require('fs');
const url = 'BACKUP_URL_FROM_STEP_1';
const file = fs.createWriteStream('output.m4s');
https.get(url, {
  headers: {
    'User-Agent': 'Mozilla/5.0 ...',
    'Referer': 'https://www.bilibili.com/'
  },
  timeout: 60000
}, (res) => {
  if (res.statusCode !== 200) { console.log('HTTP ' + res.statusCode); return; }
  res.pipe(file);
  res.on('end', () => { console.log('OK size=' + file.bytesWritten); });
}).on('error', (e) => { console.log('ERR: ' + e.message); });
"
Step 3: Convert to standard audio (stream copy, no re-encode)
bash
ffmpeg -i output.m4s -c copy output.m4a -y
Step 4: ASR transcription via FunASR
bash
set MODELSCOPE_CACHE=.\cache\modelscope
set MODELSCOPE_CREDENTIAL_PATH=.\cache\modelscope_cred
python audio2srt.py output.m4a --srt --model paraformer-zh --punc-model ct-punc --spk-model cam++
Step 5: Cleanup — remove intermediate audio files
bash
del output.m4s output.m4a

The only artifacts worth keeping are the .srt subtitle file. The raw .m4s, the converted .m4a, and any .json debug output are all intermediate and should be cleaned up after the SRT is confirmed valid.

What the script does:

  • Loads paraformer-zh (Chinese ASR, 220M params) + fsmn-vad + ct-punc + cam++
  • Outputs SRT with per-sentence timestamps via res[0]["sentence_info"]
  • CPU perf: ~15x realtime (21 min audio ≈ 90 sec)
  • Handles ModelScope cache/credential path setup automatically

If cam++ is too slow to download, omit --spk-model and group res[0]["timestamp"] (per-character ms array) by punctuation boundaries manually.

If no sentence_info in the output: the spk_model triggers sentence segmentation. Without it, you only get raw text + per-character timestamps.

Show full SKILL.md (301 more words)Show less
The audio2srt.py script

Located next to this SKILL.md file. Copy it into the current workspace or call it by its skill-directory path. It handles:

  • Model loading with ModelScope credential path override (sandbox-safe)
  • Multiple output formats: SRT, VTT, JSON
  • Parsing sentence_info, timestamp, and raw text fallback
  • Cleaning SenseVoice special tags (<|zh|>, <|HAPPY|>, etc.)
  • Segment deduplication and time-sorting

After transcription completes, delete *.m4s and *.m4a — only the .srt is the final output.


Danmaku Fallback: Protobuf API (when BE's downloadDanmaku is absent)

js
(async () => {
  const be = window.bilibiliEvolved;
  const proto = await be.runtimeLibrary.protobufLibrary;

  const schema = {
    nested: {
      DmSegMobileReply: {
        fields: { elems: { rule: 'repeated', type: 'DanmakuElem', id: 1 } },
      },
      DanmakuElem: {
        fields: {
          id: { type: 'int64', id: 1 },
          progress: { type: 'int32', id: 2 },
          mode: { type: 'int32', id: 3 },
          fontsize: { type: 'int32', id: 4 },
          color: { type: 'uint32', id: 5 },
          midHash: { type: 'string', id: 6 },
          content: { type: 'string', id: 7 },
          ctime: { type: 'int64', id: 8 },
          pool: { type: 'int32', id: 11 },
          idStr: { type: 'string', id: 12 },
          attr: { type: 'int32', id: 13 },
          animation: { type: 'string', id: 22 },
        },
      },
    },
  };
  const root = proto.Root.fromJSON(schema);
  const DmSegMobileReply = root.lookupType('DmSegMobileReply');

  const raw = await new Promise((resolve, reject) => {
    be.monkeyApis.GM_xmlhttpRequest({
      method: 'GET',
      url: `https://api.bilibili.com/x/v2/dm/web/seg.so?type=1&oid=${cid}&pid=${aid}&segment_index=1`,
      headers: { 'Referer': 'https://www.bilibili.com/' },
      responseType: 'arraybuffer',
      onload: r => resolve(r.response),
      onerror: r => reject(r.responseType)
    });
  });
  const decoded = DmSegMobileReply.decode(new Uint8Array(raw));
  return JSON.stringify(decoded.elems || []);
})()

If segment 1 has data and segment 2 is empty, treat segment 1 as complete. Apply the same density/peak/sample logic from Phase 1.


Comments

text
https://api.bilibili.com/x/v2/reply/main?jsonp=jsonp&type=1&oid={aid}&mode={mode}&ps=20&next=0

Modes: 2 = newest, 3 = popular, 0 = popular (server-dependent). Use DOM to confirm render order.


Data Structures

投稿字幕 (from BE downloadSubtitles)
js
[
  { "from": 0.3, "to": 5.3, "sid": 1, "location": 2, "content": "文字内容", "music": 0 },
  ...
]
Danmaku
js
{ "progress": 40000, "mode": 1, "fontsize": 25, "color": 16777215,
  "content": "弹幕内容", ... }

progress is in milliseconds.

DASH audio stream (from playurl API)
  • fnval=4048 → DASH response with dash.audio[]
  • Audio IDs: 30216 (~65kbps), 30232 (~74kbps), 30280 (~128kbps AAC)
  • Codec: mp4a.40.2 (AAC-LC, 48kHz, stereo)
  • Format: .m4s = fragmented MP4, valid for ffmpeg stream copy
ASR output (sentence_info)
js
[
  { "start": 110, "end": 2190, "text": "话说大家有没有见过那种反驳型人格", "spk": 0 },
  { "start": 2330, "end": 3750, "text": "就是不管听到你说什么,", "spk": 0 },
  ...
]

start/end in milliseconds. spk is the speaker ID (from cam++ diarization).


Gotchas

IssueWhat to do
downloadDanmaku not in providersPolling loop handles this. If absent after 5s, fall back to Protobuf API.
Session-less evaluateAlways use "session":"bilibili" or similar.
registerData() without []Always pass []. Provider callbacks crash without data.
Blob.text() hangsUse arrayBuffer() + TextDecoder('utf-8').decode() instead.
CDN blocks curl.exeUse Node.js https.get() with browser UA + Referer.
playurl API returns no dashDon't use platform=html5. Use fnval=4048&platform=web.
Audio URL returns 403URLs expire after ~5 min (deadline param). Fetch + download immediately in one pass.
ModelScope cache permission deniedSet MODELSCOPE_CACHE + MODELSCOPE_CREDENTIAL_PATH to writable workspace dirs. The audio2srt.py script handles this.
No sentence_info in outputAdd --spk-model cam++ to trigger sentence segmentation.
Nested array from getDataAlways flatten: Array.isArray(g[0]) ? g.flat() : g.
curl.exe downloadingUse node -e with https.get() instead.

© Misaka-Mikoto-Tech, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 3 other files in skills/bilibili-page-reader of Misaka-Mikoto-Tech/agent-skills.

  • SKILL.md
  • agents/openai.yaml
  • audio2srt.py
  • clean_srt.py

Open the folder on GitHubat commit 711abaf

Compare with similar skills

Bilibili Page Reader next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Bilibili Page Reader compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Bilibili Page Reader this skillMisaka-Mikoto-Tech/agent-skills278—~3.6kAutomated safety check: PassMIT
Video To Subtitle Summaryimlewc/video-to-subtitle-summary-skill218—~4.6kAutomated safety check: NotesMIT
Video To NotesKIRVO-REPORTING/video-to-notes105—~1.5kAutomated safety check: PassMIT
Bilibili HubOpenMinis/MinisSkills446—~2.2kAutomated safety check: PassMIT
Audio-Timed Subtitle GeneratorPluviobyte/rnskill1.6k—~1.1kAutomated safety check: NotesCustom licence
Srt Whiteboard Animationgeeklee/srt-whiteboard-animation4.2k—~1.8kAutomated safety check: PassMIT

Similar skills

  • Video To Subtitle Summary

    imlewc/video-to-subtitle-summary-skill

    A skill your agent uses when user provides a short video platform URL or local video/audio file and wants subtitles/AI summary, or when user asks to list their own AI Douyin historical tasks.

    218 GitHub stars~4.6k tokensUpdated 2 mo ago
    Media & CreativeAuto-check: notes
  • Video To Notes

    KIRVO-REPORTING/video-to-notes

    Use immediately for any bare YouTube or YouTube Shorts URL, youtu.be link, Bilibili or b23.tv link, or other video URL; do not ask what the user wants.

    105 GitHub stars~1.5k tokensUpdated 1 mo ago
    Media & CreativeAuto-check passed
  • Bilibili Hub

    OpenMinis/MinisSkills

    A skill for reading and writing Bilibili data with Python + UV, using bilibili-api-python + aiohttp.

    446 GitHub stars~2.2k tokensUpdated 3 days ago
    Media & CreativeAuto-check passed
  • Generates SRT, VTT and caption JSON for final narration audio or a merged video using Volcengine Doubao ASR word timestamps, with a quality gate before delivery.

    1.6k GitHub stars~1.1k tokensUpdated 20 days ago
    Media & CreativeAuto-check: notes
  • Srt Whiteboard Animation

    geeklee/srt-whiteboard-animation

    将 SRT 字幕做成暖米黄纸张底的白板手绘动画:读字幕→输出配图策略→确认后生成统一风格线稿→按叙事语义标注分区→预览台调整→渲染 MP4。编排沿用分区遮罩揭示(annotation.json / sequence / startMs / protectedRegions),但每个区域内的落墨换成 stream 的连续笔迹(骨架/网格 ink→color)。当用户提供 SRT…

    4.2k GitHub stars~1.8k tokensUpdated 2 mo ago
    Media & CreativeAuto-check passed
  • Video Transcribe

    wendy7756/AI-Video-Transcriber

    Transcribe and summarize a video or podcast from a URL (YouTube, TikTok, Bilibili, Apple Podcasts, SoundCloud, 30+ platforms) or from a local media/.txt file.

    3.3k GitHub stars~937 tokensUpdated 26 days ago
    Media & CreativeAuto-check: notes

More from Misaka-Mikoto-Tech/agent-skills

  • Locus Unity Bridge

    Misaka-Mikoto-Tech/agent-skills

    A skill your agent uses when an agent needs to inspect or control a real Unity Editor through Locus, especially when Unity MCP is unavailable, named-pipe discovery is needed, C must be executed, or…

    278 GitHub stars~4k tokensUpdated 19 days ago
    Auto-check passed
  • Powershell Safe Invocation

    Misaka-Mikoto-Tech/agent-skills

    A skill your agent uses when writing or running PowerShell on Windows, especially native programs, quoted paths, escaping, pwsh, Start-Process, file operations, or shell troubleshooting.

    278 GitHub stars~1.8k tokensUpdated 19 days ago
    Auto-check passed

Questions about Bilibili Page Reader

What does Bilibili Page Reader do?

Get content from Bilibili videos: official subtitles, danmaku (density/peaks/sample), comments. Bilibili Page Reader is an agent skill from Misaka-Mikoto-Tech/agent-skills. Get content from Bilibili videos: official subtitles, danmaku (density/peaks/sample), comments.

When should I use Bilibili Page Reader?

Bilibili Page Reader fits situations like: tasks that involve Transcription.

How do I install Bilibili Page Reader in Claude Code?

Run `npx skills add Misaka-Mikoto-Tech/agent-skills --skill bilibili-page-reader -a claude-code`. Or copy the skill folder (skills/bilibili-page-reader in Misaka-Mikoto-Tech/agent-skills) into .claude/skills/bilibili-page-reader in your project. Claude Code loads it when a task matches its description.

How do I install Bilibili Page Reader in Codex?

Run `npx skills add Misaka-Mikoto-Tech/agent-skills --skill bilibili-page-reader -a codex`. Or copy the skill folder (skills/bilibili-page-reader in Misaka-Mikoto-Tech/agent-skills) into .agents/skills/bilibili-page-reader in your project. Codex loads it when a task matches its description.

Can I use Bilibili Page Reader in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add Misaka-Mikoto-Tech/agent-skills --skill bilibili-page-reader -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/bilibili-page-reader, .gemini/skills/bilibili-page-reader, .github/skills/bilibili-page-reader and .opencode/skills/bilibili-page-reader in your project.

What does Bilibili Page Reader need to run?

Going by SKILL.md and its folder, Bilibili Page Reader needs Python for the scripts in its folder and the command-line tools its instructions call (node, ffmpeg and python). Our summary lists: Python 3; Node.js.

Does Bilibili Page Reader access the network?

SKILL.md names 2 domains. In commands or code: bilibili.com and api.bilibili.com; the agent is likely to contact these when it follows the instructions. This is read from the text; nothing was executed.

Is Bilibili Page Reader safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Bilibili Page Reader use?

Bilibili Page Reader is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Bilibili Page Reader use?

About 3.6k tokens (SKILL.md is roughly 14k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Bilibili Page Reader?

Skills that share tags, products or a category with Bilibili Page Reader: Video To Subtitle Summary (imlewc/video-to-subtitle-summary-skill, 218 stars), Video To Notes (KIRVO-REPORTING/video-to-notes, 105 stars), Bilibili Hub (OpenMinis/MinisSkills, 446 stars) and Audio-Timed Subtitle Generator (Pluviobyte/rnskill, 1.6k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Bilibili Page Reader?

Misaka-Mikoto-Tech (a GitHub user) maintains it in Misaka-Mikoto-Tech/agent-skills, which has 278 GitHub stars. The repository holds 3 skills in this directory. The repository was last updated on September 21, 2026.

Source: Misaka-Mikoto-Tech/agent-skills on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.