Last updated 22 April 2015. Created on 23 September 2013.
Edited by Rishi Kulshreshtha, hyside. Log in to edit this page.

I recently attempted to add multi-language subtitles to videos displayed directly on certain pages of a Drupal site. We were already using the video.js module to handle the viewing of these video files, and the module page noted that it now supported captions/subtitles tracks, but it wasn't immediately clear how to upload and associate multiple WEBVTT files (the standard supported for subtitles or captions). After a bit of reading and digging around through comments, I found that this is actually quite easy.

If you use the video.js module for your videos, you should have already created a content type and field of type "file" to allow for the upload of the video file you wish to display. You should have also changed the display format to use the video.js format if you want to display these videos inline on your site. Assuming these steps are already completed, and you are able to view uploaded videos on your site using this module, adding in captions or sub-titles is very easy:

Ensure the video file field is configured to allow unlimited (or at least more than one) values. This will allow you to upload more than one file to the same filed on a given form instance. While you are in there, ensure that the .vtt extension is an allowed file extension to upload in your form.

Create a valid WEBVTT formatted file either by hand, or by using a tool to assist you.

Once complete, it will look something like this (test.vtt):

00:00.300 --> 00:01.500
Hi, my name is Chris
00:01.500 --> 00:03.500
I am a project manager
00:03.500 --> 00:05.500
I am located in Chicago
00:05.500 --> 00:07.500
My extension is x7084
00:08.000 --> 00:10.000
[Off Camera] <i>Great, now just continue with the script...

There is a noted start/stop time for each caption entry. The first is the time (to the millisecond) that the caption entry will be displayed on the screen. The second is the time that caption value will disappear from the screen. The next line is the actual string/text value to display. This value will accept some simple HTML style markup, and you can make use of some of the other options supported by the WEBVTT standard. It can be a little tricky to get the timing just right when building the VTT files, but once you have something that works, you now have a ready to translate text file, that you can convert to other languages without having to change the timing values! Just replace the current language text, with that of another language, and you now have multilingual subtitles!

Edit your video content node and locate the video file field on the form. You should see an "Add a New File" upload field with an allowed file type list that includes "vtt" as a valid option. Upload your newly created .vtt file, and fill in the language code (EN, DE, ES, Etc.) or language name in the corresponding description field. Save your changes and view the video. If done correctly, there should now be a caption/subtitle control located on the bottom right, next to the volume control of the video player. Select your language of choice (maybe just the one), and you should start seeing your subtitles or captions appear over the bottom of the video, appearing and disappearing as you told them to in the VTT file. If you translate your VTT file for a given video, simply edit, add yet another file, upload your new VTT file (I named them video-name-en.vtt, video-name-de.vtt, etc.) and add the corresponding language code/name to the description field. Upon saving, and reloading, you will see that there are now two options in the closed-captions/sub-titles menu in the video player.

Looking for support? Visit the forums, or join #drupal-support in IRC.


mikemadison’s picture

Nice write up!

NandaKher’s picture

I have done every single step mentioned here, but can't get subtitles displayed.
Video and image are displayed properly, but subtitles never.
When I re-arrange subtitle weight to be smaller than video, then video never plays.
Is there something wrong?

Alpinist1974’s picture

It has worked well for me and works with the video module, it also allows you to dynamically create a vtt file.


fresc81’s picture

The support for subtitles was added in version 7.x-3.x. Use the dev version of the module and it will work as described.

oltean74’s picture

Hi everyone,
I just managed myself with this problem but, I solved in 'my way':
First of all I created a file field that I called 'subtitle'...became..'field_subtitle' then I just added in '' a line just after
function videojs_preprocess_videojs(&$vars)
line added :

 $path = isset($_GET['q']) ? $_GET['q'] : '<front>';
   $path = explode('/', $path); 
   if ($path[0] == 'node' && isset($path[1])) {
     // creating the node variable
     $vars['node'] = node_load($path[1], NULL, TRUE);
$node = menu_get_object();
$my_content_type = $node->type == 'my_content_type';
$vars['subtitle'] = $node->field_subtitle['und'][0]['uri'];

After that I added in 'videojs.tpl.php' just after

<?php foreach ($items as $item): ?>
  <source src....

this :
<track kind="subtitles" src="<?php print check_plain(file_create_url($item['subtitle'])) ?> srclang="ro" label="Romana"> />

ro is my language, you can change it with your's.
Now I can upload my 'subtitle.vtt' and the player
will see it with no problem.
I hope this help you !

oltean74’s picture

PS. I used link module because I just wanted to play videos(movies) from other sites

adrianorussao’s picture

Hi everyone,

I'm having problems with the url of a file_field.
I created in my content type a field of type file named field_track where do I upload the video track, but I can not get the url in template.php

<video id="<?php print $player_id; ?>-video" data-setup="{}" class="video-js vjs-default-skin vjs-big-play-centered" width="<?php print($width) ?>" height="<?php print($height) ?>" controls="controls" preload="auto"<?php echo $attrs; ?>>
<?php foreach ($items as $item): ?>
  <source src="<?php print check_plain(file_create_url($item['uri'])) ?>" type="<?php print check_plain($item['videotype']) ?>" />
  <track src="<?php print check_plain(file_create_url($item['field_track'])) ?>" kind="subtitles" srclang="pt" label="Portuguese" default>
<?php endforeach; ?>