Bilibili (哔哩哔哩) Video Transcript & Subtitle Extractor
Pricing
from $1.99 / 1,000 transcripts
Bilibili (哔哩哔哩) Video Transcript & Subtitle Extractor
Turn any Bilibili (哔哩哔哩) video link or BV number into clean, LLM-ready text with timestamps.
Pricing
from $1.99 / 1,000 transcripts
Rating
0.0
(0)
Developer
Lantern Lab
Maintained by CommunityActor stats
0
Bookmarked
4
Total users
3
Monthly active users
3 days ago
Last modified
Categories
Share
Bilibili Video Transcript & Subtitle Extractor
Hand it a Bilibili (哔哩哔哩) video link, BV number or b23.tv share link and get the spoken words back as clean text you can paste straight into a model, with a timestamp on every line. When Bilibili publishes a caption track for the video, that track is used. When it does not — which, signed out, is nearly always — the Actor downloads the public audio and transcribes it with open-source SenseVoice-Small running inside the Actor itself. No Bilibili login, no cookies, no account of your own, and nothing sent to a transcription service. $1.99 per 1,000 transcripts, plus $0.001 for each 10 seconds of speech transcribed, plus $0.005 per run — a ten-minute talk costs about $0.067. See Pricing.
Input:
{"videoUrls": ["https://www.bilibili.com/video/BV1z9nt6aE5H/"],"allowAsr": true,"maxDurationSec": 600}
Output — one row per video part. text is the whole transcript; segments carries the
same words with timings. Sample from a real run, transcript trimmed:
{"recordType": "transcript","platform": "bilibili","videoId": "BV1DSnK6REdy","bvid": "BV1DSnK6REdy","aid": 117475559611144,"cid": 42910354047,"part": 1,"partCount": 1,"url": "https://www.bilibili.com/video/BV1DSnK6REdy/","title": "电脑总是卡顿掉帧?原来是ACE 根本没有彻底卸载干净!","authorName": "宇浩玩数码","publishedAt": "2026-10-20T22:20:03.000Z","durationSec": 52,"viewCount": 2191286,"language": "zh","transcriptSource": "asr","asrModel": "sensevoice-small","text": "只要你电脑上玩过藤子杰的任何一款游戏,那么你以后在玩别的游戏的时候,都会卡到怀疑人生。我也是今天才发现的…","wordCount": 299,"segments": [{ "start": 0.2, "end": 12.44, "text": "只要你电脑上玩过藤子杰的任何一款游戏,那么你以后在玩别的游戏的时候,都会卡到怀疑人生。" },{ "start": 12.74, "end": 17.01, "text": "我不能忍受的是给你看一下,他居然把自节的反作弊捆绑到steam上了。" }],"segmentCount": 5,"availableCaptionLanguages": [],"audioSec": 51.04,"speechSec": 49.49,"asrBlocksCharged": 5,"partial": false,"partialReason": null,"collectedAt": "2026-10-24T10:50:00.882Z"}
What you get
- The transcript, twice over.
textis one block of plain text, ready for a prompt.segmentsis the same content as{ start, end, text }, so you can link to a moment. - Where the words came from.
transcriptSourceisplatform_captionorasr, andasrModelnames the model when it was recognised. You always know what you are reading. - What you are paying for, on the row.
speechSecis the talking the model found andasrBlocksChargedis what that was billed as, so any invoice can be checked against the rows that produced it. - The video around it.
title,authorName(the uploader's public display name),publishedAt,durationSec,viewCount,bvid,cidandpart, so a transcript can be traced back to the exact part it came from. - Multi-part (分P) videos. Add
?p=3to a link for one part, or turn onincludeAllPartsto get every part as its own row. - Honest gaps. A video with no transcript is still a row, with
partial: true, apartialReasonand a sentence instatusTextsaying what happened. A blocked request, a deleted video and a video with no speech are three different reasons and never look the same. The run never reports "nothing found" for collection it did not finish. - A run summary. The last dataset row, and the
RUN_SUMMARYkey, hold the totals: transcripts by source, every partial reason, audio recognised, requests sent to Bilibili and why the run stopped.
Input
| Field | Default | What it does |
|---|---|---|
videoUrls | — | One video per line: full link, BV…, av… or a b23.tv link. ?p=3 picks a part. |
preferPlatformCaptions | true | Read Bilibili's own caption track first when there is one. |
allowAsr | true | Transcribe the audio when there is no caption track. |
includeSegments | true | Include the time-coded segments array. |
includeAllParts | false | Write a row for every part of a multi-part video. |
maxDurationSec | 600 | Skip (and mark) a part longer than this instead of transcribing it. |
maxItems | 50 | Upper bound on transcripts written and charged. |
asrModel | sensevoice-small | The only model carried, running inside the Actor. |
asrLanguage | auto | Force the spoken language, for example zh or en. |
maxUpstreamRequests | derived | Hard ceiling on requests to Bilibili. Left empty, it is worked out from your input. |
proxyConfiguration | Apify Proxy | Bilibili refuses some datacenter addresses; the Actor retries once through a Chinese residential address by itself. |
Limits worth knowing before you run it
- Bilibili serves its caption list to signed-in callers only. This Actor signs in to
nothing, so
preferPlatformCaptionsfinds a track only on the rare video that exposes one. On a sample of 40 popular videos taken on 2026-10-24, none did. Plan on speech recognition, and on its price. - Speech recognition is not free and not instant. It costs CPU in proportion to how
much talking there is, which is also how it is priced.
maxDurationSecis there so a long video cannot surprise you; raise it deliberately. - Recognition makes mistakes, more of them on music, dialect, overlapping speakers and
technical names.
segmentskeeps the timeline, so any line can be checked against the video. - A video with no speech — a music video, a clip that is all sound effects — comes
back with
partialReason: "no_speech_detected", no text, and no charge. That includes the case where the model only looped one short syllable over the music. It is an answer about the video, not a failure of the run. - One awkward video cannot hold up your list. Recognition is stopped if it passes
twice the length of the audio; that video is returned with
asr_failedand is not charged, and the rest of the list carries on. - Public videos only. Nothing behind a login, a paywall or an age gate is collected.
Pricing
Pay per event: $1.99 per 1,000 transcripts, plus $0.001 for each 10 seconds of speech the model transcribes, plus $0.005 for each run. A video Bilibili already captioned costs no audio events at all.
| Event | Price | Charged for |
|---|---|---|
result | $0.00199 ($1.99 per 1,000) | Each row that carries words. |
asr-10s | $0.001 per started 10 seconds of speech | The stretches of a video the model actually found a voice in, added up and rounded up per video — silence, intro music and music-only passages are not charged. Not charged for a platform caption, and not charged when the model found no words. |
run-start | $0.005, once per run | The signing keys and signed-out session every run sets up before it reads a video. |
What that works out to, per video of someone talking from start to finish (a video that is half music costs about half the audio part):
| Typical video | Price |
|---|---|
| 1 min | $0.008 |
| 3 min | $0.025 |
| 10 min | $0.067 |
| any length, Bilibili captioned it | $0.002 |
Rows with no transcript — blocked, deleted, too long, no speech, a duplicate, over a limit — are written free. A run that collects nothing still pays the $0.005 session.
To cap a run, set Maximum cost per run in the run options. At the cap the Actor stops
before the next video, marks what it did not reach partial with charge_limit_reached,
and says so in RUN_SUMMARY.
Notes on how it works
Requests go to Bilibili's public web API, signed with the same WBI signature the website
uses, with no cookie jar at all. A refused request is retried once with fresh signing
keys and then once through a Chinese residential address; if it is still refused, the row
says blocked rather than pretending the video has no transcript. The audio itself comes
off Bilibili's CDN, which refuses nobody, so it is fetched straight off the Actor and only
retried through your proxy if the CDN turns that down - downloadSec and asrSec on each
row say where a slow video spent its time. Bilibili lists several mirrors per stream and
some of them only answer viewers inside China, so the global ones are always tried first.
The next video is fetched while the current one is being transcribed, so you are not
charged for a machine waiting on a CDN. If Apify moves a run to another machine
mid-collection, it carries on from the videos it had already written instead of collecting
and charging for them twice. Speech recognition is
SenseVoice-Small through
sherpa-onnx on the CPU, with
Silero VAD cutting the audio into utterances so
every line keeps a real start and end — and so the quiet stretches are never transcribed
or billed. The weights are baked into the Actor's image, so a run downloads no model and
calls no third-party service.