Bharti Subtitles
Subtitles for your Media Library videos, generated inside your own browser. No API key, no per-minute cost, and the video is never uploaded anywhere.
1. What Bharti Subtitles does
You pick a video that is already in your WordPress Media Library, pick the language that is spoken in it, and press one button. The speech is turned into subtitles, you get a chance to correct anything the model misheard, and then the subtitles are saved and attached to the video. Visitors get a CC button on the player.
The part that makes this different from every other subtitle plugin is where the work happens. There is no transcription service behind Bharti Subtitles. The speech model is downloaded into the browser of whoever pressed the button, and it runs there.
| Consequence | What it means for you |
|---|---|
| No API key | You never sign up for anything, anywhere. Nothing to configure before the first run. |
| No per-minute cost | Plugins built on the OpenAI Whisper API bill for every minute of every video, every time you run it. A hundred hours of course videos is a real invoice. Here it is free however much you caption. |
| Nothing is uploaded | The browser reads the video file and works on it locally. It is not sent to us, and not to anyone else. For medical, legal, internal-training or members-only content that is often the difference between "allowed" and "not allowed". |
| No server load | Your host never transcodes or transcribes anything, so this runs happily on the cheapest shared hosting. |
Accessibility
Captions for prerecorded video are a WCAG 2.1 requirement (Success Criterion 1.2.2). If your site has an accessibility obligation, this is one of the items on that list.
2. Requirements
| WordPress | 6.2 or newer |
|---|---|
| PHP | 7.4 or newer |
| Browser | A current version of Chrome, Edge, Firefox or Safari, on the machine of the person generating subtitles. Visitors need nothing special — they just see a normal subtitle track. |
| Internet | Needed the first time only, to download the speech model. The browser keeps it afterwards. |
| Video formats | Anything the browser itself can play. MP4 (H.264 + AAC) and WebM are the safe choices. |
| Uploads folder | Must be writable — the .vtt file is saved
beside the video. |
Only the person generating subtitles needs the modern browser. Once the subtitles are saved they are an ordinary WebVTT file served by your site, and every browser and player understands those.
3. Installation
- In WordPress, go to Plugins → Add New → Upload Plugin and choose
bharti-subtitles.zip. If you prefer, unzip it and upload thebharti-subtitlesfolder to/wp-content/plugins/over FTP. - Press Install Now, then Activate.
- You will find the plugin in two places: Media → Bharti Subtitles for generating, and Settings → Bharti Subtitles for defaults.
Uploading the wrong ZIP is the most common install problem. The file
you downloaded from CodeCanyon may be the full package, which contains the documentation
and licence files as well. The plugin itself is the bharti-subtitles.zip
inside it. If WordPress says "the package could not be installed — no valid
plugins were found", that is what happened.
4. Quick start
- Go to Media → Bharti Subtitles.
- Choose your video from the Video list. Videos that already have subtitles are marked — has subtitles.
- Choose the Spoken language. This is the language spoken in the video, not the language of your site.
- Press Generate subtitles. The first run downloads the speech model, so it takes longer than the ones after it. Lines appear as they are recognised.
- Read the lines. Click any line to correct it — names, brands and technical words are what the model gets wrong most often.
- Press Save to this video. The subtitles are now attached, and the CC button appears wherever that video is embedded.
There is also a shortcut from the Media Library itself: open any video's details and you will see a Generate subtitles button that brings you straight here with that video already selected.
5. The panel
While it is working
Two different waits are shown, and it is worth knowing which is which:
- "Setting up on this device — one time only" is the model download. It reports megabytes so you can see it moving. It happens once per browser.
- "Writing the subtitles…" is the actual transcription. Lines appear underneath as they are decoded.
Cancel stops it cleanly at any point. Nothing is saved until you press Save.
Editing before you save
Every line is editable in place. Fix a word and the timings around it are kept, so you can correct spelling without pushing the subtitles out of sync. This step matters more than it looks: a two-minute pass over the lines is the difference between subtitles that read as professional and subtitles that read as machine output.
Generating again
Pressing Generate again discards what is on screen and starts over. It does not touch subtitles you have already saved — those are only replaced when you press Save again.
Removing subtitles
Remove saved subtitles deletes the .vtt file and the
video's link to it. The video itself is never touched.
6. Settings
Under Settings → Bharti Subtitles. These are defaults and site-wide behaviour; nothing here changes subtitles you have already saved.
| Setting | Default | What it does |
|---|---|---|
| Default language | English | Which language is pre-selected on the panel. Saves you a click if you always caption the same language. |
| Words per line | 9 | How many words each subtitle holds, between 3 and 14. Lower means subtitles change faster; higher means longer lines that may not fit on a phone. A subtitle also never stays on screen longer than about four seconds, whatever this is set to. |
| Remove filler words | Off | Strips "um", "uh" and their equivalents. Useful for interviews and lectures. Leave it off for scripted narration, where there is nothing to strip. |
| Automatically show subtitles | On | Adds the subtitle track to videos on the front end. Turn it off if your theme builds its own player and you want to add the track yourself. |
7. Subtitle appearance
The same settings page has a live preview showing exactly how subtitles will look. What you can change:
| Control | Options |
|---|---|
| Font | A short list of families every device has |
| Size | A percentage of the player's own subtitle size |
| Bold | On by default — it survives busy footage better |
| Capitals | Off by default |
| Text colour | Any colour |
| Background and opacity | Any colour, any opacity down to fully transparent |
| Outline | A thin dark edge, so text stays readable with the background off |
| Position | Bottom or top |
| Alignment | Left, centre or right |
Position is the one setting written into the file itself. Everything
else is applied by your site's stylesheet, so changing it updates every video at once.
Position has to be written into each .vtt as it is saved — which means
changing it only affects subtitles you save afterwards. Re-save a video's
subtitles if you want the new position applied to it.
What is deliberately not here
No karaoke highlighting, no word-by-word animation, no glow. Those effects need the captions drawn onto the video frames and the video re-encoded — that is a server-side video editor, not a subtitle track. Everything Bharti Subtitles offers is what a real subtitle file can carry, which is also why the files work in VLC, on YouTube and in any editor.
8. How subtitles appear on your site
With Automatically show subtitles on, Bharti Subtitles adds a subtitle track to videos rendered by either of the two ways WordPress shows video:
- the classic
[video]shortcode - the Gutenberg Video block
The track is added with default set, so subtitles are switched on when the
video starts. Viewers can turn them off from the player's own CC control.
The Video block needs its playback controls switched on. Bharti Subtitles adds the subtitle track, but the CC control belongs to the player itself. In the editor, select the video, and in the block settings turn on Playback controls. With it off the player has no controls at all — so no CC button either, even though the subtitles are attached and will still be drawn on screen.
An existing track is never disturbed. If the video already has a
<track> — added by hand, or by another plugin — Bharti Subtitles leaves the
markup alone. Two identical CC entries in the player is worse than none.
Adding the track yourself
If your theme or page builder replaces the WordPress player, turn Automatically show subtitles off and add the track in your own template. The subtitle URL is available from PHP:
<?php
$vtt = BSUB_REST::subtitle_url( $attachment_id );
if ( $vtt ) {
printf(
'<track kind="subtitles" src="%s" srclang="en" label="English" default />',
esc_url( $vtt )
);
}
9. Languages
Seventeen languages are offered. Only languages the on-device model actually handles are listed — offering more would simply produce bad subtitles.
| Group | Languages |
|---|---|
| Strongest | English, Spanish, French, German, Italian, Portuguese, Dutch, Russian, Polish, Japanese, Korean, Chinese, Turkish, Indonesian |
| Usable, expect to edit | Hindi, Marathi, and Hinglish (Hindi written in Roman letters) |
About Hindi, Marathi and Hinglish
These three are worth being straight about, because they behave differently from the rest.
- They need a larger speech model — about 250 MB on the first run against 50 MB for the other languages, and two to three times slower. The smaller model does not write these languages down at all: it turns Hindi into English and Marathi into Roman letters. The size buys the script itself, so it is not optional. The panel tells you this before you press the button.
- They are transcribed in shorter passes, which is slower again but considerably more accurate for these scripts.
- Expect to correct more lines than you would in English. The model has seen far less Hindi and Marathi than it has English. What you get is a usable draft to fix, and that is genuinely faster than typing subtitles from nothing — but it is a draft, not a finished transcript.
Hinglish is transcribed as Hindi and then converted to Roman letters on your own device, so it is exactly as accurate as Hindi is.
10. .srt and .vtt files
Besides saving to the video, you can download the subtitles in either format.
| Format | Use it for |
|---|---|
.srt | YouTube, Vimeo, Premiere, DaVinci Resolve, most video editors |
.vtt | The web standard — what your site itself uses |
The downloaded file is named after the video, not after the plugin. A video called
launch-talk.mp4 gives you launch-talk.srt. That is deliberate:
players such as VLC pick subtitles up automatically when the two files sit in the same
folder with the same name. It also stops your Downloads folder filling with
subtitles (1), subtitles (2), and so on.
Subtitles are never written inside the video file. The video is left exactly as you uploaded it, and the subtitles travel beside it.
11. Speed and the model
The first run on any given browser downloads the speech model. After that the browser keeps it and every later run starts immediately.
| Model download, once | Then | |
|---|---|---|
| English | about 50 MB | roughly real time on a modern laptop |
| Other European and Asian languages | about 50 MB | roughly real time |
| Hindi, Marathi, Hinglish | about 250 MB | several times slower — see above |
Speed after the download depends entirely on the machine doing the work, not on your hosting. A current laptop is comfortable. A ten-year-old office desktop will be slow but will finish.
Why there is no bulk mode
Everything happens in the browser of the person who pressed the button. Captioning two hundred videos overnight would mean a server doing the work — and that would bring back the per-minute bill, the upload, and the server load that this plugin exists to avoid. It is a deliberate trade, not an oversight.
12. Troubleshooting
The subtitles do not appear on the front end
Check three things, in this order:
- The video actually has subtitles saved — Media → Bharti Subtitles marks those videos — has subtitles.
- Settings → Bharti Subtitles → Automatically show subtitles is on.
- Your theme is not replacing the WordPress player with its own. If it is, see Adding the track yourself.
The subtitles show, but there is no CC button
The Video block has Playback controls switched off, so the player draws no controls at all. Select the video in the editor and turn that setting on. Nothing is wrong with the subtitles — they are attached, which is why they appear on screen.
"The browser could not read the audio"
The video uses a codec your browser will not decode — nearly always HEVC inside a
.mov. Convert it to MP4 (H.264 + AAC), re-upload, and it will work.
The button does nothing
If you arrived from an old link, the video it pointed at may have been deleted from the Media Library since. Bharti Subtitles falls back to the first video and tells you the link is stale — pick a video from the list.
"Could not write the subtitle file"
The uploads folder is not writable. This is a hosting permissions matter; your host can fix it in a minute.
The first line or two is missing
Press Generate again. The speech model is not perfectly deterministic at the very start of a file, and a second pass usually catches it. If it keeps happening on the same video, check whether that video begins with music or noise over the speech.
The whole transcript is wrong or in the wrong alphabet
The Spoken language setting does not match what is actually spoken. This is the single most common cause. Set it correctly and generate again.
The progress bar seems stuck
During the model download the byte counter underneath keeps moving even when the percentage does not — watch that instead. A 250 MB download on a slow connection takes a while, and it only ever happens once.
13. For developers
Where things are stored
| What | Where |
|---|---|
| The subtitle file | Your uploads folder, beside the video, e.g.
/wp-content/uploads/2026/08/launch-talk.vtt |
| Link to it | Post meta _bharti_subtitles_vtt on the attachment —
a path relative to the uploads folder |
| Language used | Post meta _bharti_subtitles_language |
| When it was made | Post meta _bharti_subtitles_generated |
| All settings | A single option, bharti_subtitles_settings |
Filter: where the runtime files come from
The speech engine's WebAssembly runtime is fetched from a public CDN, because those files are about 32 MB in total and shipping them inside the plugin is not reasonable. Organisations that cannot allow outbound requests can host the files themselves and point the plugin at their own copy:
add_filter( 'bharti_subtitles_wasm_paths', function () {
return 'https://example.com/assets/transformers/';
} );
The version is pinned deliberately. Following the library's latest release would mean untested runtime files arriving on every site at once, on a day nobody changed anything.
REST endpoints
Namespace bharti-subtitles/v1, used by the panel itself. Both require the
upload_files capability and a valid nonce.
Getting the subtitle URL in PHP
$url = BSUB_REST::subtitle_url( $attachment_id ); // '' if there are none
14. Uninstalling
Deactivating the plugin leaves everything in place — settings, subtitle files and the links to them. Nothing is lost and nothing changes except that the CC track stops being added.
Deleting the plugin from the Plugins screen removes its settings, its
post meta, and the .vtt files it created. Your videos are never touched.
If you want to keep the subtitle files, download the .srt or
.vtt for the videos you care about before deleting the plugin.
15. Changelog
1.0.0
- First release.
16. Support
Support is available through the item's comments section on CodeCanyon.
When reporting a problem, these four things will get you an answer in one reply instead of four:
- WordPress version and PHP version
- Browser and version, on the machine where you pressed the button
- The spoken language you chose
- Anything shown in the browser console (press F12, open the Console tab)