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.

ConsequenceWhat 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

WordPress6.2 or newer
PHP7.4 or newer
BrowserA 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.
InternetNeeded the first time only, to download the speech model. The browser keeps it afterwards.
Video formatsAnything the browser itself can play. MP4 (H.264 + AAC) and WebM are the safe choices.
Uploads folderMust 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

  1. In WordPress, go to Plugins → Add New → Upload Plugin and choose bharti-subtitles.zip. If you prefer, unzip it and upload the bharti-subtitles folder to /wp-content/plugins/ over FTP.
  2. Press Install Now, then Activate.
  3. 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

  1. Go to Media → Bharti Subtitles.
  2. Choose your video from the Video list. Videos that already have subtitles are marked — has subtitles.
  3. Choose the Spoken language. This is the language spoken in the video, not the language of your site.
  4. 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.
  5. Read the lines. Click any line to correct it — names, brands and technical words are what the model gets wrong most often.
  6. 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.

SettingDefaultWhat it does
Default languageEnglish Which language is pre-selected on the panel. Saves you a click if you always caption the same language.
Words per line9 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 wordsOff 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 subtitlesOn 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:

ControlOptions
FontA short list of families every device has
SizeA percentage of the player's own subtitle size
BoldOn by default — it survives busy footage better
CapitalsOff by default
Text colourAny colour
Background and opacityAny colour, any opacity down to fully transparent
OutlineA thin dark edge, so text stays readable with the background off
PositionBottom or top
AlignmentLeft, 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.

GroupLanguages
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.

FormatUse it for
.srtYouTube, Vimeo, Premiere, DaVinci Resolve, most video editors
.vttThe 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, onceThen
Englishabout 50 MBroughly real time on a modern laptop
Other European and Asian languagesabout 50 MBroughly real time
Hindi, Marathi, Hinglishabout 250 MBseveral 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:

  1. The video actually has subtitles saved — Media → Bharti Subtitles marks those videos — has subtitles.
  2. Settings → Bharti Subtitles → Automatically show subtitles is on.
  3. 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

WhatWhere
The subtitle fileYour uploads folder, beside the video, e.g. /wp-content/uploads/2026/08/launch-talk.vtt
Link to itPost meta _bharti_subtitles_vtt on the attachment — a path relative to the uploads folder
Language usedPost meta _bharti_subtitles_language
When it was madePost meta _bharti_subtitles_generated
All settingsA 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:

  1. WordPress version and PHP version
  2. Browser and version, on the machine where you pressed the button
  3. The spoken language you chose
  4. Anything shown in the browser console (press F12, open the Console tab)