With HTML5 you can add captions to your video using the <track />
element. However, only vtt files are officialy supported, while the current most populair subtitle format is the well known srt format.
So instead of converting all the srt files to vtt files, I had the idea of writing a script which will do all of this on the fly. Without any manual converting.
Using the script you can add srt files to the <track />
element like so:
<track label="English" kind="subtitles" srclang="en" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/1178475/Fantastic.Beasts.The.Crimes.of.Grindelwald.2018.1080p.WEB-DL.H264.AC3-EVO.srt" default>
What the script basically does is following
- Gets the content from the file using a XMLHttpRequest
- Converts the srt format to a vtt format
- Creates a blob from the vtt string
- Creates a file from the blob
- Replaces the original
src
with the generated vtt file
The script itself is very simple and small, only 4kb in size. I wonder if I can make the script even smaller and if I wrote the code well.
document.addEventListener("DOMContentLoaded", function () {
/**
* Get all videos
*/
var videoElements = document.getElementsByTagName('video');
/**
* This function converts all srt's to vtt files
*/
function convertSrtToVtt()
{
/**
* Generate an unique identifier
*/
this.id = '_' + Math.random().toString(36).substr(2, 9);
/**
* All tracks assigned to current video element
*/
var tracks = document.querySelectorAll("#" + this.id + " track");
var subtitle = {
data:
{
track: {}
},
/**
* Load the file from url
*
* @param {object} track - DOM <track /> object
*/
load: function(track)
{
subtitle.track = track;
if(subtitle.isSrt(subtitle.track.src))
{
var client = new XMLHttpRequest();
client.open('GET', subtitle.track.src);
client.onreadystatechange = function()
{
subtitle.convert(client.responseText).then(
function (file)
{
/**
* Replace the srt file with the generated vtt file
*/
subtitle.track.src = file
}
);
}
client.send();
}
},
/**
* Converts the SRT string to a VTT formatted string
*
* @param {string} content - SRT string
* @return {object} promise - Returns a promise with the generated file as the return value
*/
convert: function(content)
{
var promise = new Promise(
function (resolve, reject)
{
/**
* Replace all (,) commas with (.) dots. Eg: 00:00:01,144 -> 00:00:01.144
*/
content = content.replace(/(\d+:\d+:\d+)+,(\d+)/g, '$1.$2');
content = "WEBVTT - Generated using SRT2VTT\r\n\r\n" + content;
/**
* Convert content to a file
*/
var blob = new Blob([content], {type: 'text/vtt'});
var file = window.URL.createObjectURL(blob);
resolve(file);
}
);
return promise;
},
isSrt: function(filename)
{
return filename.split('.').pop().toLowerCase() === 'srt' ? true : false;
},
isVTT: function(filename)
{
return filename.split('.').pop().toLowerCase() === 'vtt' ? true : false;
}
}
for(var i = 0;i < tracks.length;i++)
{
subtitle.load(tracks[i]);
}
}
for(var i = 0;i < videoElements.length;i++)
{
videoElements[i].addEventListener('loadstart', convertSrtToVtt);
}
});