Skip to content

Instantly share code, notes, and snippets.

@defeo
Created August 3, 2016 00:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save defeo/641fd2d9edc6b4ecf8185a9a9331030b to your computer and use it in GitHub Desktop.
Save defeo/641fd2d9edc6b4ecf8185a9a9331030b to your computer and use it in GitHub Desktop.
A pure ES6 example using the VTTCue API to add subtitles to a video track + speech synthesis for fun
fetch('oneview.md')
.then((res) => res.text())
.then((subtitles) => {
// Je parse votre fichier de sous-titres
const lines = subtitles.split("\n")[Symbol.iterator]();
const track = {
label: lines.next().value,
cues: []
};
lines.next();
const cue_regex = /^(.*) \(([0-9]):([0-9]{2})\)$/;
let cue_end = true;
let cue_payload = null;
for (let l of lines) {
if (l === '' && cue_end) {
const [, comment, cue_min, cue_sec ] = cue_regex.exec(lines.next().value);
lines.next();
const start = (60*parseInt(cue_min) + parseInt(cue_sec))*1000 + 1;
if (track.cues.length > 0)
track.cues[track.cues.length-1].end = start - 1;
cue_payload = [];
track.cues.push({
start: start,
comment: comment,
payload: cue_payload,
})
cue_end = false;
} else if (l === '' && !cue_end) {
cue_end = true;
} else {
cue_payload.push(l);
cue_end = false;
}
}
track.cues[track.cues.length-1].end = 60*60*1000;
// Je le convertis en VTT, je ne m'en sers pas, mais ça peut être utile
// pour écrire un convertisseur
const escape = (string) => string
.replace('&', '&')
.replace('<', '&lt;')
.replace('>', '&gt;');
const time = (ms) => (new Date(ms)).toISOString().match(/.*T(.*)Z/)[1]
const vtt = [
`WEBVTT - ${escape(track.label)}\n`,
'\n'
];
for (let [i, cue] of track.cues.entries()) {
vtt.push(
`${i+1} - ${escape(cue.comment)}\n`,
`${time(cue.start)} --> ${time(cue.end)}\n`,
cue.payload.map(escape).join('\n'),
'\n',
'\n'
);
}
console.log(vtt.join(""));
// J'ajoute les sous-titres à la vidéo
// ça ne pourrait pas être plus expérimental: https://w3c.github.io/webvtt/
// ...utiliser un navigateur récent !
const v = document.querySelector('video');
const subs = document.querySelector('#subs');
v.addEventListener('mouseover', (e) => v.controls = true);
v.addEventListener('mouseout', (e) => v.controls = false);
const t = v.addTextTrack('captions', track.label);
for (let cue of track.cues) {
const c = new VTTCue(cue.start/1000, cue.end/1000, cue.payload.join('\n'))
t.addCue(c);
c.onenter = (e) => {
subs.textContent = c.text;
if (window.speechSynthesis)
window.speechSynthesis.speak(new SpeechSynthesisUtterance(c.text));
}
}
t.mode = 'showing';
})
.catch((err) => console.log(err));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment