-
-
Save jabis/f5e98571abe2aed3c43d to your computer and use it in GitHub Desktop.
A fast port of MooPlay, by challet, from MooTools 1.2.4 to 1.4.*
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function() { | |
/* | |
--- | |
description: Base MooPlay object, useful but not really interesting | |
license: GNU GPL | |
authors: | |
- Clément Hallet | |
requires: | |
- core/1.2.4: [Core, Element, Element.Event, Element.Style, Class, Class.Extra.Events, Class.Extra.Options] | |
provides: | |
- MooPlay | |
- MooPlay.Subtitle | |
- MooPlay.Subtitle.Parser | |
- MooPlay.Control | |
- MooPlay.Display | |
... | |
*/ | |
this.Element.NativeEvents = Object.extend(Element.NativeEvents, { | |
loadstart: 2, | |
progress: 2, | |
suspend: 2, | |
abort: 2, | |
error: 2, | |
emptied: 2, | |
stalled: 2, | |
play: 2, | |
pause: 2, | |
loadedmetadata: 2, | |
loadeddata: 2, | |
waiting: 2, | |
playing: 2, | |
canplay: 2, | |
canplaythrough: 2, | |
seeking: 2, | |
seeked: 2, | |
timeupdate: 2, | |
ended: 2, | |
ratechange: 2, | |
durationchange: 2, | |
volumechange: 2 | |
}); | |
var MooPlay = this.MooPlay = { | |
Subtitle: { | |
Parser: {} | |
}, | |
Control: {}, | |
Display: {} | |
}; | |
/* | |
--- | |
description: some utility functions | |
license: GNU GPL | |
authors: | |
- Clément Hallet | |
requires: | |
- MooPlay | |
provides: | |
- MooPlay.Utils | |
... | |
*/ | |
MooPlay.Utils = { | |
/** | |
* @param srt_time : format is '00:02:52,406' | |
*/ | |
sexagesimalToTimestamp: function(srt_time) { | |
return ((srt_time.h * 60 + srt_time.m) * 60 + srt_time.s) * 1000 + srt_time.ms; | |
}, | |
/** | |
* @return format is '00:02:52,406' | |
*/ | |
timestampToSexagesimal: function(timestamp) { | |
var ms = timestamp.floor(); | |
var s = (ms / 1000).floor() ; | |
var m = (s / 60).floor(); | |
var h = (m / 60).floor(); | |
return { | |
h: h, | |
m: m % 60, | |
s: s % 60, | |
ms: ms % 1000 | |
}; | |
}, | |
readable: function(srt_time) { | |
srt_time.m = String(srt_time.m).pad(2,'0'); | |
srt_time.s = String(srt_time.s).pad(2,'0'); | |
srt_time.ms = String(srt_time.ms).pad(3,'0'); | |
return srt_time; | |
} | |
} | |
//+ Jonas Raoni Soares Silva | |
//@ http://jsfromhell.com/string/pad [rev. #1] | |
String.prototype.pad = function(l, s, t){ | |
return s || (s = " "), (l -= this.length) > 0 ? (s = new Array(Math.ceil(l / s.length) | |
+ 1).join(s)).substr(0, t = !t ? l : t == 1 ? 0 : Math.ceil(l / 2)) | |
+ this + s.substr(0, l - t) : this; | |
};/* | |
--- | |
description: proxy between any DOM element and a video element, controls and displays the current position inside the video | |
license: GNU GPL | |
authors: | |
- Clément Hallet | |
requires: | |
- MooPlay | |
- more/1.2.4: [Slider] | |
provides: | |
- MooPlay.Control.PlayProgress | |
... | |
*/ | |
MooPlay.Control.PlayProgress = new Class({ | |
Implements: [Options], | |
initialize: function(video, slider, options) { | |
this.setOptions(options); | |
this.slider = slider; | |
this.video = $(video); | |
this.suspended = false; | |
this.video.addEvents({ | |
'timeupdate': this.tick.bind(this), | |
'seeked': this.resume.bind(this) | |
}); | |
this.slider.knob.addEvents({ | |
'mousedown': this.suspend.bind(this), | |
'mouseup': this.resume.bind(this), | |
'click': function(event) { event.stop(); } | |
}); | |
this.slider.addEvent('change', this.change.bind(this)); | |
}, | |
suspend: function(event) { | |
event.preventDefault(); | |
this.suspended = true; | |
}, | |
resume: function(event) { | |
event.preventDefault(); | |
this.suspended = false; | |
}, | |
tick: function(event) { | |
if(!this.suspended) { | |
position = this.slider.toPosition( event.target.currentTime / event.target.duration * this.slider.range ); | |
this.slider.knob.setStyle(this.slider.property, position); | |
} | |
}, | |
change: function(step) { | |
this.suspended = true; | |
this.video.currentTime = this.video.duration * step / this.slider.steps; | |
} | |
}); | |
/* | |
--- | |
description: proxy between any DOM element and a video element, displays the loading progress of the video | |
license: GNU GPL | |
authors: | |
- Clément Hallet | |
requires: | |
- MooPlay | |
- progressbar: * | |
- more/1.2.4: [Slider] | |
provides: | |
- MooPlay.Control.LoadProgress | |
... | |
*/ | |
MooPlay.Control.LoadProgress = new Class({ | |
options: { | |
preload_class: 'preloading' | |
}, | |
Implements: [Options], | |
initialize: function(video, progressbar, options) { | |
this.setOptions(options); | |
this.progressbar = progressbar; | |
this.video = $(video); | |
this.video.addEvents({ | |
'progress': function(e, video, data) { | |
if(e.event.lengthComputable) { | |
this.tick(e.event.loaded, e.event.total); | |
} else { | |
this.preload(true); | |
} | |
}.bind(this), | |
'loadstart': this.preload.pass(true, this), | |
'seeking': this.preload.pass(true, this), | |
'loadedmetadata': this.preload.pass(false, this), | |
'seeked': this.preload.pass(false, this) | |
}); | |
}, | |
preload: function(state) { | |
if(state) { | |
this.progressbar.options.container.addClass(this.options.preload_class); | |
} else { | |
this.progressbar.options.container.removeClass(this.options.preload_class); | |
} | |
}, | |
tick: function(loaded, total) { | |
this.progressbar.set(loaded / total * 100); | |
}, | |
}); | |
/* | |
--- | |
description: make an element to act as a button. | |
license: GNU GPL | |
authors: | |
- Clément Hallet | |
requires: | |
- MooPlay | |
provides: | |
- MooPlay.Control.BaseButton | |
... | |
*/ | |
MooPlay.Control.BaseButton = new Class({ | |
Implements: [Options], | |
options: { | |
over_state_class: 'over', | |
click_state_class: 'clicked' | |
}, | |
initialize: function(video, element, options) { | |
this.setOptions(options); | |
this.element = $(element); | |
this.video = $(video); | |
//console.log(video,element,options,this.element,this.video); | |
this.element.addEvents({ | |
'mouseenter': function(event) { | |
event.preventDefault(); | |
this.element.addClass(this.options.over_state_class); | |
}.bind(this), | |
'mouseleave': function(event) { | |
event.preventDefault(); | |
this.element.removeClass(this.options.over_state_class); | |
}.bind(this), | |
'mousedown': function(event) { | |
event.preventDefault(); | |
this.element.addClass(this.options.click_state_class); | |
}.bind(this), | |
'mouseup': function(event) { | |
event.preventDefault(); | |
this.element.removeClass(this.options.click_state_class); | |
}.bind(this) | |
}); | |
this.specificInitialize(); | |
} | |
}); | |
/* | |
--- | |
description: proxy between any DOM element and a video element, controls and displays the play and pause video states | |
license: GNU GPL | |
authors: | |
- Clément Hallet | |
requires: | |
- MooPlay.Control.BaseButton | |
provides: | |
- MooPlay.Control.PlayPause | |
... | |
*/ | |
MooPlay.Control.PlayPause = new Class({ | |
Extends: MooPlay.Control.BaseButton, | |
options: { | |
paused_state_class: 'paused' | |
}, | |
initialize:function(video,element,options){ | |
this.parent(video,element,options); | |
}, | |
specificInitialize: function() { | |
if(this.video.paused) { | |
this.element.addClass(this.options.paused_state_class); | |
} | |
this.video.addEvents({ | |
'play': function() { | |
this.element.removeClass(this.options.paused_state_class); | |
}.bind(this), | |
'pause': function() { | |
this.element.addClass(this.options.paused_state_class); | |
}.bind(this) | |
}); | |
this.element.addEvents({ | |
'click': function(event) { | |
event.preventDefault(); | |
this.toggleState(); | |
}.bind(this) | |
}); | |
}, | |
toggleState: function() { | |
if(this.video.paused) { | |
this.video.play(); | |
} else { | |
this.video.pause(); | |
} | |
} | |
}); | |
/* | |
--- | |
description: Allows to move inside the video, with a pscific speed factor | |
license: GNU GPL | |
authors: | |
- Clément Hallet | |
requires: | |
- MooPlay.Control.BaseButton | |
provides: | |
- MooPlay.Control.FastMove | |
... | |
*/ | |
MooPlay.Control.FastMove = new Class({ | |
Extends: MooPlay.Control.BaseButton, | |
options: { | |
speed_factor: 1 | |
}, | |
initialize:function(video,element,options){ | |
this.parent(video,element,options) | |
}, | |
specificInitialize: function() { | |
this.element.addEvents({ | |
'mousedown': this.beginMove.bind(this), | |
'mouseup': this.stopMove.bind(this), | |
'mouseleave': this.stopMove.bind(this) | |
}); | |
this.start_time = null; | |
this.timer = null; | |
this.start_pos = null; | |
}, | |
beginMove: function() { | |
if(this.timer == null) { | |
this.start_time = Date.now(); | |
this.start_pos = this.video.currentTime; | |
this.timer = this.tick.bind(this).periodical(50); | |
} | |
}, | |
stopMove: function() { | |
if(this.timer != null) { | |
this.start_time = null; | |
this.start_pos = null; | |
clearTimeout(this.timer); | |
this.timer = null; | |
} | |
}, | |
tick: function() { | |
if(this.timer == null) { | |
return; | |
} | |
var time_to_move = (Date.now() - this.start_time) * this.options.speed_factor; | |
this.video.currentTime = this.start_pos + (time_to_move / 1000); | |
} | |
}); | |
/* | |
--- | |
description: display the player with the dimension of the page | |
license: GNU GPL | |
authors: | |
- Clément Hallet | |
requires: | |
- MooPlay | |
provides: | |
- MooPlay.Control.FullScreen | |
... | |
*/ | |
MooPlay.Control.FullScreen = new Class({ | |
Extends: MooPlay.Control.BaseButton, | |
Implements: [Events,Options], | |
options: { | |
active_state_class: 'active' | |
}, | |
full_screened: false, | |
initialize:function(video,element,options){ | |
this.parent(video,element,options); | |
}, | |
specificInitialize: function() { | |
this.initialStyle = this.video.getStyles('position', 'top', 'left'); | |
this.element.addEvents({ | |
'click': function(event) { | |
event.preventDefault(); | |
this.fireEvent(this.full_screened ? 'foldStart' : 'expandStart'); | |
}.bind(this) | |
}); | |
this.fx = new Fx.Morph(this.video, { | |
link: 'cancel', | |
onComplete: function() { | |
this.fireEvent(this.full_screened ? 'foldComplete' : 'expandComplete'); | |
this.full_screened = !this.full_screened; | |
}.bind(this) | |
}); | |
this.addEvents({ | |
'expandStart': this.onExpandStart.bind(this), | |
'expandComplete': this.onExpandComplete.bind(this), | |
'foldStart': this.onFoldStart.bind(this), | |
'foldComplete': this.onFoldComplete.bind(this) | |
}); | |
}, | |
onExpandStart: function() { | |
document.body.setStyle('overflow', 'hidden'); | |
var abs_coordinates = this.video.getCoordinates(document.body); | |
var body_scroll = document.body.getScroll(); | |
this.initialCoordinates = { | |
top: abs_coordinates.top - body_scroll.y, | |
left: abs_coordinates.left - body_scroll.x, | |
height: abs_coordinates.height, | |
width: abs_coordinates.width, | |
}; | |
this.video.setStyles({ | |
position: 'fixed', | |
top: String(this.initialCoordinates.top) + 'px', | |
left: String(this.initialCoordinates.left) + 'px' | |
}); | |
var body_dimension = document.body.getCoordinates(); | |
this.fx.start({ | |
height: body_dimension.height, | |
width: body_dimension.width, | |
top: 0, | |
left: 0 | |
}); | |
}, | |
onExpandComplete: function() { | |
this.video.setStyles({ | |
width: '100%', | |
height: '100%' | |
}); | |
this.element.addClass(this.options.active_state_class); | |
}, | |
onFoldStart: function() { | |
var video_dimension = this.video.getCoordinates(); | |
this.video.setStyles({ | |
width: String(video_dimension.width) + 'px', | |
height: String(video_dimension.height) + 'px' | |
}); | |
this.fx.start({ | |
height: this.initialCoordinates.height, | |
width: this.initialCoordinates.width, | |
top: this.initialCoordinates.top, | |
left: this.initialCoordinates.left | |
}); | |
}, | |
onFoldComplete: function() { | |
document.body.setStyle('overflow', 'visible'); | |
this.video.setStyles(this.initialStyle); | |
this.element.removeClass(this.options.active_state_class); | |
document.body.setStyle('overflow', 'visible'); | |
} | |
}); | |
/* | |
--- | |
description: control volume through a slider | |
license: GNU GPL | |
authors: | |
- Clément Hallet | |
requires: | |
- MooPlay | |
- MooPlay.Utils | |
provides: | |
- MooPlay.Control.Volume | |
... | |
*/ | |
MooPlay.Control.Volume = new Class({ | |
options: { | |
auto_unmute: true | |
}, | |
Implements: [Options], | |
initialize: function(video, slider, options) { | |
this.setOptions(options); | |
this.slider = slider; | |
this.video = $(video); | |
this.video.addEvent('volumechange', this.update.bind(this)); | |
this.slider.addEvent('change', this.change.bind(this)); | |
}, | |
update: function(event) { | |
var volume = event.target.muted ? 0 : event.target.volume; | |
position = this.slider.toPosition( volume * this.slider.range ); | |
this.slider.knob.setStyle(this.slider.property, position); | |
}, | |
change: function(pos) { | |
this.video.volume = pos / this.slider.steps; | |
if(this.options.auto_unmute && this.video.muted) { | |
this.video.muted = false; | |
} | |
} | |
}); | |
/* | |
--- | |
description: control mute with a button | |
license: GNU GPL | |
authors: | |
- Clément Hallet | |
requires: | |
- MooPlay | |
- MooPlay.Utils | |
provides: | |
- MooPlay.Control.Mute | |
... | |
*/ | |
MooPlay.Control.Mute = new Class({ | |
Extends: MooPlay.Control.BaseButton, | |
options: { | |
muted_state_class: 'muted' | |
}, | |
initialize:function(video,element,options){ | |
this.parent(video,element,options); | |
}, | |
specificInitialize: function() { | |
this.video.addEvents({ | |
'volumechange': this.update.bind(this) | |
}); | |
this.element.addEvents({ | |
'click': function(event) { | |
event.preventDefault(); | |
this.toggleState(); | |
}.bind(this) | |
}); | |
}, | |
update: function(event) { | |
if(event.target.muted) { | |
this.element.addClass(this.options.muted_state_class); | |
} else { | |
this.element.removeClass(this.options.muted_state_class); | |
} | |
}, | |
toggleState: function() { | |
this.video.muted = !this.video.muted; | |
} | |
}); | |
/* | |
--- | |
description: display position in the video, in human readable time | |
license: GNU GPL | |
authors: | |
- Clément Hallet | |
requires: | |
- MooPlay | |
- MooPlay.Utils | |
provides: | |
- MooPlay.Control.TimeDisplay | |
... | |
*/ | |
MooPlay.Control.TimeDisplay = new Class({ | |
Implements: [Options], | |
options: { | |
pattern: '{h}:{m}:{s},{ms}', | |
current: true, // vs 'remaining' | |
auto_update: true | |
}, | |
initialize: function(video, container, options) { | |
this.setOptions(options); | |
this.container = $(container); | |
this.video = $(video); | |
if(this.options.auto_update) { | |
this.video.addEvent('timeupdate', function(event) { | |
if(this.options.current) { | |
this.update(event.target.currentTime * 1000); | |
} else { | |
this.update(Math.max(0, event.target.duration - event.target.currentTime) * 1000); | |
} | |
}.bind(this)); | |
} | |
}, | |
update: function(abs_movie_time) { | |
var new_text = this.options.pattern.substitute( | |
MooPlay.Utils.readable(MooPlay.Utils.timestampToSexagesimal(abs_movie_time)) | |
); | |
if(new_text != this.container.get('text')) { | |
this.container.empty().appendText(new_text); | |
} | |
} | |
}); | |
/* | |
--- | |
description: object representation of a subtitle line | |
license: GNU GPL | |
authors: | |
- Clément Hallet | |
requires: | |
- MooPlay | |
provides: | |
- MooPlay.Subtitle.Item | |
... | |
*/ | |
MooPlay.Subtitle.Item = new Class({ | |
initialize: function(start, end, texts) { | |
this.start = start; | |
this.end = end; | |
this.element = new Element('div'); | |
texts.each(function(text) { | |
this.element.grab( | |
new Element('p').appendText(text) | |
); | |
}.bind(this)); | |
}, | |
}); | |
/* | |
--- | |
description: hash tree store for subtitles | |
license: GNU GPL | |
authors: | |
- Clément Hallet | |
requires: | |
- MooPlay | |
- MooPlay.Subtitle.Item | |
provides: | |
- MooPlay.Subtitle.Tree | |
... | |
*/ | |
MooPlay.Subtitle.Tree = new Class({ | |
nb_childs: 2, | |
children: [], | |
subs: [], | |
initialize : function(start, end) { | |
this.start = start; | |
this.end = end; | |
}, | |
buildChildren: function() { | |
var child_period = Math.ceil((this.end - this.start) / this.nb_childs); | |
for (var i = 0; i < this.nb_childs; i++) { | |
this.children.push(new MooPlay.Subtitle.Tree( | |
this.start + i * child_period, // start | |
this.start + (i + 1) * child_period // end | |
)); | |
} | |
}, | |
getChildren: function(even_empty) { | |
if(this.children.length == 0 && even_empty) { | |
this.buildChildren(); | |
} | |
return this.children; | |
}, | |
doesSubtitleFit: function(sub) { | |
return sub.start >= this.start && sub.end <= this.end; | |
}, | |
addSub: function(sub) { | |
var fit_in_one_child = false; | |
this.getChildren(true).each(function(child) { | |
if(child.doesSubtitleFit(sub)) { | |
fit_in_one_child = true; | |
child.addSub(sub); | |
} | |
}.bind(this)); | |
if(this.doesSubtitleFit(sub) && !fit_in_one_child) { | |
this.subs.push(sub); | |
} | |
}, | |
getSubs: function(timestamp) { | |
if(timestamp < this.start && timestamp >= this.end) { | |
return []; | |
} | |
var subs = []; | |
this.subs.each(function(sub) { | |
if(timestamp >= sub.start && timestamp < sub.end) { | |
subs.push(sub); | |
} | |
}); | |
this.getChildren(false).each(function(child) { | |
if(timestamp >= child.start && timestamp <= child.end) { | |
subs.extend(child.getSubs(timestamp)); | |
} | |
}); | |
return subs; | |
} | |
}); | |
/* | |
--- | |
description: ajax-loading subtitles and routing to the right parser | |
license: GNU GPL | |
authors: | |
- Clément Hallet | |
requires: | |
- MooPlay | |
- MooPlay.Subtitle.Item | |
- MooPlay.Subtitle.Tree | |
provides: | |
- MooPlay.Subtitle.Loader | |
... | |
*/ | |
MooPlay.Subtitle.Loader = new Class({ | |
Implements: [Options], | |
initialize: function(url, options) { | |
this.url = url; | |
this.setOptions(options); | |
this.load(); | |
}, | |
load: function() { | |
var request = new Request({ | |
url: this.url, | |
method: 'get', | |
onSuccess: this.run.bind(this) | |
}); | |
request.send({}); | |
}, | |
run: function (data) { | |
var parser = this.selectParser(); | |
return new parser(data, {onComplete: this.options.onComplete}); | |
}, | |
selectParser: function() { | |
var ext = this.url.split('.').pop(); | |
switch(ext) { | |
case 'srt': | |
return MooPlay.Subtitle.Parser.SubRip; | |
break; | |
case 'sub': | |
return MooPlay.Subtitle.Parser.SubViewer; | |
break; | |
default: | |
throw 'the ' + ext + ' format is not known or supported as a subtitle file'; | |
break; | |
} | |
} | |
}); | |
/* | |
--- | |
description: diplay subtitles synchronised with a video element | |
license: GNU GPL | |
authors: | |
- Clément Hallet | |
requires: | |
- MooPlay | |
- MooPlay.Subtitle.Item | |
- MooPlay.Subtitle.Tree | |
provides: | |
- MooPlay.Subtitle.Player | |
... | |
*/ | |
MooPlay.Subtitle.Player = new Class({ | |
Implements: [Options], | |
options: { | |
subs_hash: null, | |
tick_delay: 100, // not in use for now | |
time_shift: 0, | |
onDispose: function(element, container, overlapping) { | |
element.dispose(); | |
sub.element.removeClass('overlapping' + String(overlapping)); | |
}, | |
onDisplay: function(element, container, overlapping) { | |
element.addClass('overlapping' + String(overlapping)); | |
element.inject(container, 'bottom'); | |
} | |
}, | |
initialize: function( video, container, options) { | |
this.setOptions(options); | |
this.video = $(video); | |
this.container = $(container); | |
if(this.options.subs_hash != null) { | |
this.loadSubtitles(this.options.subs_hash); | |
} | |
this.overlapping_level = 0; | |
this.displayed = []; | |
this.video.addEvent('timeupdate', function(event) { | |
if(this.subs_hash != null || this.displayed.length != 0) { | |
this.tick(event.target.currentTime * 1000); | |
} | |
}.bind(this)); | |
}, | |
loadSubtitles: function(subs_hash) { | |
this.unLoad(); | |
this.subs_hash = subs_hash; | |
}, | |
unLoad: function() { | |
this.subs_hash = null; | |
}, | |
tick: function(abs_movie_time) { | |
var next_displayed = this.subs_hash != null ? this.subs_hash.getSubs(abs_movie_time - this.options.time_shift) : []; | |
// remove subs which are not here anymore | |
this.displayed.each(function(sub) { | |
var displayed = []; | |
if(!next_displayed.contains(sub) || this.subs_hash == null) { | |
this.options.onDispose(sub.element, this.container, --this.overlapping_level); | |
} else { | |
displayed.push(sub); | |
} | |
this.displayed = displayed; | |
}.bind(this)); | |
// display subs which should to | |
next_displayed.each(function(sub) { | |
if(!this.displayed.contains(sub)) { | |
this.displayed.push(sub); | |
this.options.onDisplay(sub.element, this.container, this.overlapping_level++); | |
} | |
}.bind(this)); | |
}, | |
setTimeShift: function(shift) { | |
this.options.time_shift = parseInt(shift); | |
} | |
}); | |
/* | |
--- | |
description: base class for ajax-loading and parsing subtitles file | |
license: GNU GPL | |
authors: | |
- Clément Hallet | |
requires: | |
- MooPlay | |
- MooPlay.Subtitle.Item | |
- MooPlay.Subtitle.Tree | |
provides: | |
- MooPlay.Subtitle.Parser.Base | |
... | |
*/ | |
MooPlay.Subtitle.Parser.Base = new Class({ | |
Implements: [Options], | |
options: { | |
onComplete: Function.from() | |
}, | |
initialize: function(data, options) { | |
this.setOptions(options); | |
this.hash( | |
this.parse(data) | |
); | |
this.options.onComplete(this.hash_root); | |
}, | |
parse:function(data){ | |
return this; | |
}, | |
hash: function(subs) { | |
var abs_start = Infinity; | |
var abs_end = 0; | |
Object.each(subs,function(sub) { | |
abs_start = Math.min(abs_start, sub.start); | |
abs_end = Math.max(abs_end, sub.end); | |
}); | |
this.hash_root = new MooPlay.Subtitle.Tree(abs_start, abs_end); | |
Object.each(subs,function(sub) { | |
this.hash_root.addSub(sub); | |
}.bind(this)); | |
} | |
}); | |
/* | |
--- | |
description: specific class for parsing subtitles file in SubRip format (.srt) | |
license: GNU GPL | |
authors: | |
- Clément Hallet | |
requires: | |
- MooPlay | |
- MooPlay.Utils | |
- MooPlay.Subtitle.Parser.Base | |
- MooPlay.Subtitle.Item | |
provides: | |
- MooPlay.Subtitle.Parser.SubRip | |
... | |
*/ | |
MooPlay.Subtitle.Parser.SubRip = new Class({ | |
Extends: MooPlay.Subtitle.Parser.Base, | |
regexps: { | |
new_sub: /^(\d+)$/, | |
time: /^(\d{2}):(\d{2}):(\d{2}),(\d{3}) --> (\d{2}):(\d{2}):(\d{2}),(\d{3})$/, | |
text: /^(.+)$/ | |
}, | |
options: { | |
srt_end_of_line: '\n', | |
onComplete: Function.from() | |
}, | |
initialize:function(){ | |
}, | |
parse: function(data) { | |
var subs = []; | |
var current_sub = null; | |
var current_text = null; | |
var index = null | |
var lines = data.split(this.options.srt_end_of_line); | |
// in case file doesn't end with an empty line | |
lines.push(''); | |
do { | |
var line = lines.shift(); | |
if(this.regexps.new_sub.test(line)) { | |
current_text = []; | |
current_sub = {}; | |
} else if(line != null && this.regexps.time.test(line)) { | |
var times = this.regexps.time.exec(line); | |
current_sub.start = MooPlay.Utils.sexagesimalToTimestamp({ h: times[1].toInt(), m: times[2].toInt(), s: times[3].toInt(), ms: times[4].toInt() }); | |
current_sub.end = MooPlay.Utils.sexagesimalToTimestamp({ h: times[5].toInt(), m: times[6].toInt(), s: times[7].toInt(), ms: times[8].toInt() }); | |
var times = null; | |
} else if(line != null && this.regexps.text.test(line)) { | |
current_text.push(this.regexps.text.exec(line)[0]); | |
} else if(current_sub != null) { | |
subs.push(new MooPlay.Subtitle.Item(current_sub.start, current_sub.end, current_text)); | |
current_sub = null; | |
current_text = null; | |
} | |
} while(line != null); | |
return subs; | |
}, | |
}); | |
/* | |
--- | |
description: specific class for parsing subtitles file in SubViewer format (.sub) | |
license: GNU GPL | |
authors: | |
- Clément Hallet | |
requires: | |
- MooPlay | |
- MooPlay.Utils | |
- MooPlay.Subtitle.Parser.Base | |
- MooPlay.Subtitle.Item | |
provides: | |
- MooPlay.Subtitle.Parser.SubViewer | |
... | |
*/ | |
MooPlay.Subtitle.Parser.SubViewer = new Class({ | |
Implements: MooPlay.Subtitle.Parser.Base, | |
regexps: { | |
time: /^(\d{2}):(\d{2}):(\d{2}).(\d{3}),(\d{2}):(\d{2}):(\d{2}).(\d{3})$/, | |
text: /^(.+)$/ | |
}, | |
options: { | |
srt_end_of_line: '\n', | |
onComplete: Function.from() | |
}, | |
parse: function(data) { | |
var subs = []; | |
var current_sub = null; | |
var current_text = null; | |
var index = null | |
var lines = data.split(this.options.srt_end_of_line); | |
// in case file doesn't end with an empty line | |
lines.push(''); | |
do { | |
var line = lines.shift(); | |
if(line != null && this.regexps.time.test(line)) { | |
current_text = []; | |
current_sub = {}; | |
var times = this.regexps.time.exec(line); | |
current_sub.start = MooPlay.Utils.sexagesimalToTimestamp({ h: times[1].toInt(), m: times[2].toInt(), s: times[3].toInt(), ms: times[4].toInt() }); | |
current_sub.end = MooPlay.Utils.sexagesimalToTimestamp({ h: times[5].toInt(), m: times[6].toInt(), s: times[7].toInt(), ms: times[8].toInt() }); | |
var times = null; | |
} else if(line != null && this.regexps.text.test(line)) { | |
current_text = this.regexps.text.exec(line)[0].split('[BR]'); | |
} else if(current_sub != null) { | |
subs.push(new MooPlay.Subtitle.Item(current_sub.start, current_sub.end, current_text)); | |
current_sub = null; | |
current_text = null; | |
} | |
} while(line != null); | |
return subs; | |
}, | |
}); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment