// vim: et:ts=4:sw=4:sts=4:ft=js /*@ Ox.VideoPlayer Generic Video Player (options, self) -> Video Player options Options annotation <[o]> Array of annotation tracks name Name of the annotation track data <[o]> Annotation data in In point (sec) out Out point (sec) text Text controls <[[s]]|[[][]]> Controls, first top, then bottom, from left to right Can be 'fullscreen', 'scale', 'title', 'find', 'menu', 'play', 'playInToOut', 'mute', 'volume', 'size', 'timeline', 'space', 'position', 'settings'. The 'space' control is just empty space that separates left-aligned from right-aligned controls. duration Duration (sec) enableFind If true, enable find enableFullscreen If true, enable fullscreen enableKeyboard If true, enable keyboard controls externalControls If true, controls are outside the video find Query string focus focus on 'click', 'load' or 'mouseover' fps Frames per second fullscreen If true, video is in fullscreen height Height in px (excluding external controls) in In point (sec) keepIconVisible If true, play icon stays visible after mouseleave keepLargeTimelineVisible If true, large timeline stays visible after mouseleave keepLogoVisible If true, logo stays visible after mouseleave logo Logo image URL logoLink Logo link URL logoTitle Text for tooltip muted If true, video is muted paused If true, video is paused playInToOut If true, video plays only from in to out position Initial position (sec) poster Poster URL posterFrame Position of poster frame (sec) preload 'auto', 'metadata' or 'none' out Out point (sec) scaleToFill If true, scale to fill (otherwise, scale to fit) showFind If true, show find input showHours If true, don't show hours for videos shorter than one hour showIcon If true, show play icon showIconOnLoad If true, show icon on load showInterfaceOnLoad If true, show controls and title on load showLargeTimeline If true, show large timeline showMilliseconds Number of decimals to show showPointMarkers If true, show in/out markers showProgress <|false> If true, show buffering progress sizeIsLarge If true, initial state of the size control is large subtitles URL or SRT or array of subtitles in In point (sec) out Out point (sec) text Text timeline Timeline image URL title Video title type 'play', 'in' or 'out' video Video URL volume Volume (0-1) width Width in px @*/ Ox.VideoPlayer = function(options, self) { self = self || {}; var that = Ox.Element({}, self) .defaults({ annotations: [], controlsBottom: [], controlsTop: [], duration: 0, enableFind: false, enableFullscreen: false, enableKeyboard: false, externalControls: false, find: '', focus: 'click', fps: 25, fullscreen: false, height: 144, 'in': 0, keepIconVisible: false, keepLargeTimelineVisible: false, keepLogoVisible: false, largeTimeline: false, logo: '', logoLink: '', logoTitle: '', muted: false, paused: false, playInToOut: false, position: 0, poster: '', preload: 'auto', out: 0, scaleToFill: false, showFind: false, showHours: false, showIcon: false, showIconOnLoad: false, showInterfaceOnLoad: false, showLargeTimeline: false, showMilliseconds: 0, showPointMarkers: false, showProgress: false, subtitles: [], timeline: '', title: '', type: 'play', video: '', volume: 1, width: 256 }) .options(options || {}) .addClass('OxVideo') .css({ position: 'absolute' }); Ox.UI.$window.bind({ resize: function() { self.options.fullscreen && setSizes(); } }); self['in'] = self.options.playInToOut ? self.options['in'] : 0, self.out = self.options.playInToOut ? self.options.out : self.options.duration; self.options.duration = self.out - self['in']; self.options.position = Ox.limit(self.options.position, self['in'], self.out); Ox.print('p/d', self.options.position, self.options.duration); // fixme: this is _relative_, resizing can happen self.millisecondsPerFrame = 1000 / self.options.fps; self.secondsPerFrame = 1 / self.options.fps; self.barHeight = 16; self.width = self.options.fullscreen ? window.innerWidth : self.options.width; self.height = self.options.fullscreen ? window.innerHeight : self.options.height; if (self.options.enableKeyboard) { that.bindEvent({ key_1: function() { toggleScale(true); }, key_f: function() { // need timeout so the "f" doesn't appear in the input field setTimeout(self.$findInput.focusInput, 0); }, key_g: function() { goToNextResult(1); }, key_left: function() { setPosition(self.options.position - self.secondsPerFrame, true); }, key_m: function() { toggleMuted(true); }, key_p: function() { playInToOut(); }, key_right: function() { setPosition(self.options.position + self.secondsPerFrame, true); }, key_shift_f: function() { self.options.enableFullscreen && toggleFullscreen(true); }, key_shift_g: function() { goToNextResult(-1); }, key_space: function() { togglePaused(true); } }) } if (self.options.enableKeyboard) { if (self.options.focus == 'mouseenter') { that.bind({ mouseenter: function() { if (!self.inputHasFocus) { that.gainFocus(); } }, mouseleave: function() { that.loseFocus(); } }); } else { that.bind({ click: that.gainFocus }); } } if ( (!self.options.externalControls && (self.options.controlsTop.length || self.options.controlsBottom.length)) || self.options.showIcon ) { that.bind({ mouseenter: function() { showInterface(); self.mouseHasLeft = false; Ox.print('MOUSE HAS ENTERED') }, mouseleave: function() { hideInterface(); self.mouseHasLeft = true; Ox.print('MOUSE HAS LEFT') } }); } if (Ox.isString(self.options.subtitles)) { if (self.options.subtitles.indexOf('\n') > -1) { self.options.subtitles = Ox.parseSRT(self.options.subtitles); } else { Ox.get(self.options.subtitles, function(data) { self.options.subtitles = Ox.parseSRT(data); self.results = find(self.options.find); Ox.print('--setting results--', self.$timeline) if (self.options.duration) { // video has loaded self.$timeline && self.$timeline.options({ results: self.results, subtitles: self.options.subtitles }); self.$largeTimeline && self.$largeTimeline.options({ subtitles: self.options.subtitles }); } }); self.options.subtitles = []; } } self.results = find(self.options.find); self.buffered = []; self.controlsTimeout; self.$videoContainer = $('
') .css({ position: 'absolute', top: self.options.externalControls && self.options.controlsTop ? '16px' : 0, background: 'rgb(0, 0, 0)', overflow: 'hidden' }) .bind({ click: function() { togglePaused(true); } }) .appendTo(that.$element) self.$video = $('