metanohi-misc-subsites/subsites/natur/subtitler.js

157 lines
4.2 KiB
JavaScript

/*
This program is free software. It comes without any warranty, to
the extent permitted by applicable law. You can redistribute it
and/or modify it under the terms of the Do What The Fuck You Want
To Public License, Version 2, as published by Sam Hocevar. See
http://sam.zoy.org/wtfpl/COPYING for more details.
*/
/* It's very simple and not perfect. I'm not going to develop more on this code.
*/
function subtitle(vid, subs_url, alt) {
this.videoElement = vid
this.subtitles = null
if (alt != undefined)
this.rootElement = alt
else
this.rootElement = document.body
this.fetchSubtitles(subs_url)
}
subtitle.prototype.fetchSubtitles = function(subs_url) {
var req = new XMLHttpRequest()
req.open('GET', subs_url, true)
req.onreadystatechange = function() {
if (req.readyState == 4) {
if (req.status == 200)
this.subtitleObject.extractSubtitles(req.responseText)
else
this.subtitleObject.err()
}
}
req.subtitleObject = this
req.send(null)
}
subtitle.prototype.extractSubtitles = function(subs) {
var subs = subs
while (subs.indexOf('\n') == 0)
subs = subs.substr(1)
while (subs.substr(subs.length-1) == '\n')
subs = subs.substr(0, subs.length-1)
subs = subs.split('\n\n')
var subs_arr = new Array()
var x, i, txt, times, start, end, msg
for (x in subs) {
txt = subs[x].split('\n')
times = txt[1].split(' --> ')
start = this.toSeconds(times[0])
end = this.toSeconds(times[1])
msg = ''
for (i = 2; i < txt.length; i++)
msg += '\n' + txt[i]
msg = msg.substr(1)
subs_arr.push([start, end, msg])
}
this.start(subs_arr)
}
subtitle.prototype.toSeconds = function(time_str) {
var t = 0
t += time_str.substr(0, 2) * 3600
t += time_str.substr(3, 2) * 60
t += time_str.substr(6, 2) * 1
t += time_str.substr(9, 3) * 0.001
return t
}
subtitle.prototype.err = function() {
this.start([[0, 4000, 'It wasn\t possible to load the subtitles.']])
}
/**********************/
subtitle.prototype.start = function(subs_arr) {
this.subtitles = subs_arr
this.textLength = this.subtitles.length
this.currentSubtitle = 0
this.currentSubtitleOn = false
var elem = document.createElement('div')
elem.style.position = 'absolute'
var subelem = document.createElement('div')
subelem.id = 'subtitle'
elem.appendChild(subelem)
this.rootElement.appendChild(elem)
this.subtitleElement = elem
this.subtitleTextElement = subelem
this.updateSubtitleElement()
this.videoElement.subtitlesObject = this
this.videoElement.onmouseover = function() {
this.subtitlesObject.subtitleElement.style.display = 'none'
}
this.videoElement.onmouseout = function() {
this.subtitlesObject.subtitleElement.style.display = ''
}
this.resume()
}
subtitle.prototype.resume = function() {
this.videoElement.addEventListener('timeupdate', this.check, true)
}
subtitle.prototype.stop = function() {
this.removeCurrentSubtitle()
this.videoElement.removeEventListener('timeupdate', this.check, true)
}
subtitle.prototype.updateSubtitleElement = function() {
var x = this.videoElement.offsetLeft
var y = this.videoElement.offsetTop
var w = this.videoElement.width
var h = this.videoElement.height
this.subtitleElement.style.left = x + 10 + 'px'
this.subtitleElement.style.width = w - 20 + 'px'
this.subtitleElement.style.top = y + h - 50 + 'px'
this.subtitleElement.style.height = '40px'
}
subtitle.prototype.check = function(event) {
var self = event.target.subtitlesObject
var time = event.target.currentTime
var csub = self.subtitles[self.currentSubtitle]
if (time >= csub[0] && time <= csub[1]) {
if (!self.currentSubtitleOn)
self.updateSubtitle()
}
else {
self.removeCurrentSubtitle()
if (time < csub[0] && self.currentSubtitle > 0)
self.currentSubtitle -= 1
else if (time > csub[1] && self.currentSubtitle < self.textLength)
self.currentSubtitle += 1
}
}
subtitle.prototype.updateSubtitle = function() {
this.subtitleTextElement.innerHTML = this.subtitles[this.currentSubtitle][2]
this.subtitleTextElement.style.display = ''
this.currentSubtitleOn = true
}
subtitle.prototype.removeCurrentSubtitle = function() {
this.subtitleTextElement.style.display = 'none'
this.subtitleTextElement.innerHTML = ''
this.currentSubtitleOn = false
}