'use strict'; /*@ Ox.VideoPanel VideoPanel Object () -> VideoPanel Object (options) -> VideoPanel Object (options, self) -> VideoPanel Object options Options object self shared private variable @*/ Ox.VideoPanel = function(options, self) { self = self || {}; var that = Ox.Element({}, self) .defaults({ annotationsCalendarSize: 256, annotationsFont: 'small', annotationsMapSize: 256, annotationsRange: 'all', annotationsSize: 256, annotationsSort: 'position', censored: [], censoredIcon: '', censoredTooltip: '', clickLink: null, cuts: [], duration: 0, enableDownload: false, enableSubtitles: false, find: '', fullscreen: false, getLargeTimelineURL: null, height: 0, 'in': 0, layers: [], loop: false, // fixme: used? muted: false, out: 0, paused: true, playInToOut: false, position: 0, poster: '', resolution: 0, scaleToFill: false, selected: '', showAnnotations: false, showAnnotationsCalendar: false, showAnnotationsMap: false, showLayers: {}, showTimeline: true, showUsers: false, smallTimelineURL: '', subtitles: [], timeline: '', tooltips: false, video: '', volume: 1, width: 0 }) .options(options || {}) .css({ height: self.options.height + 'px', width: self.options.width + 'px' }) .bindEvent({ resize: resizeElement, key_0: toggleMuted, key_equal: function() { self.$video.changeVolume(0.1); }, key_minus: function() { self.$video.changeVolume(-0.1); }, key_space: togglePaused }); self.fullscreen = false; self.$player = Ox.Element() .css({ overflowX: 'hidden', overflowY: 'hidden' }); self.$video = Ox.VideoPlayer({ annotations: getAnnotations(), censored: self.options.censored, censoredIcon: self.options.censoredIcon, censoredTooltip: self.options.censoredTooltip, controlsTop: ['fullscreen', 'title', 'find'], controlsBottom: ['play', 'volume', 'scale', 'timeline', 'position', 'settings'], enableDownload: self.options.enableDownload, enableFind: true, enableKeyboard: true, enableMouse: true, enablePosition: true, enableSubtitles: self.options.enableSubtitles, enableTimeline: true, find: self.options.find, fullscreen: self.options.fullscreen, height: getPlayerHeight(), 'in': self.options['in'], muted: self.options.muted, out: self.options.out, paused: self.options.paused, position: self.options.position, resolution: self.options.resolution, scaleToFill: self.options.scaleToFill, subtitles: self.options.subtitles, timeline: self.options.smallTimelineURL, video: self.options.video, volume: self.options.volume, width: getPlayerWidth() }) .bindEvent({ censored: function() { that.triggerEvent('censored'); }, download: function(data) { that.triggerEvent('downloadvideo', data); }, find: function(data) { self.$timeline.options({find: data.find}); self.$annotationPanel.options({highlight: data.find}); that.triggerEvent('find', data); }, fullscreen: function(data) { self.options.fullscreen = data.fullscreen; }, muted: function(data) { that.triggerEvent('muted', data); }, paused: function(data) { self.options.paused = data.paused; that.triggerEvent('paused', data); }, playing: function(data) { setPosition(data.position, true); }, position: function(data) { setPosition(data.position); }, resolution: function(data) { that.triggerEvent('resolution', data); }, scale: function(data) { that.triggerEvent('scale', data); }, select: selectAnnotation, subtitles: function(data) { self.$timeline.options({ subtitles: data.subtitles ? self.options.subtitles : [] }); that.triggerEvent('subtitles', data); }, volume: function(data) { that.triggerEvent('volume', data); } }) .appendTo(self.$player); self.$controls = Ox.Element() .bindEvent({ toggle: toggleControls }); self.$timeline = Ox.LargeVideoTimeline({ duration: self.options.duration, find: self.options.find, getImageURL: self.options.getLargeTimelineURL, position: self.options.position, subtitles: self.options.enableSubtitles ? self.options.subtitles : [], videoId: self.options.videoId, type: self.options.timeline, width: getTimelineWidth() }) .css({left: '4px', top: '4px'}) .bindEvent({ mousedown: that.gainFocus, position: changeTimeline }) .appendTo(self.$controls); self.$videoPanel = Ox.SplitPanel({ elements: [ { element: self.$player }, { collapsed: !self.options.showTimeline, collapsible: true, element: self.$controls, size: 80, tooltip: self.options.tooltips ? 'timeline' : false } ], orientation: 'vertical' }); self.$annotationPanel = Ox.AnnotationPanel({ calendarSize: self.options.annotationsCalendarSize, clickLink: self.options.clickLink, editable: false, font: self.options.annotationsFont, highlight: self.options.find, 'in': self.options['in'], layers: self.options.layers, mapSize: self.options.annotationsMapSize, out: self.options.out, position: self.options.position, range: self.options.annotationsRange, selected: self.options.selected, showCalendar: self.options.showAnnotationsCalendar, showFonts: true, showLayers: Ox.clone(self.options.showLayers), showMap: self.options.showAnnotationsMap, showUsers: self.options.showUsers, sort: self.options.annotationsSort, width: self.options.annotationsSize }) .bindEvent({ annotationsfont: function(data) { self.options.annotationsFont = data.font; that.triggerEvent('annotationsfont', data); }, annotationsrange: function(data) { self.options.annotationsRange = data.range; that.triggerEvent('annotationsrange', data); }, annotationssort: function(data) { self.options.annotationsSort = data.sort; that.triggerEvent('annotationssort', data); }, info: function(data) { that.triggerEvent('info', data); }, open: function() { setPosition(self.options['in']); }, resize: resizeAnnotations, resizeend: resizeendAnnotations, resizecalendar: function(data) { that.triggerEvent('resizecalendar', data); }, resizemap: function(data) { that.triggerEvent('resizemap', data); }, select: selectAnnotation, toggle: toggleAnnotations, togglecalendar: function(data) { self.options.showAnnotationsCalendar = !data.collapsed; that.triggerEvent('togglecalendar', data); }, togglelayer: function(data) { that.triggerEvent('togglelayer', { collapsed: data.collapsed, layer: data.layer }); }, togglemap: function(data) { self.options.showAnnotationsMap = !data.collapsed; that.triggerEvent('togglemap', data); } }); [ '0', 'b', 'backslash', 'closebracket', 'comma', 'dot', 'equal', 'f', 'g', 'i', 'minus', 'n', 'o', 'openbracket', 'p', 'shift_0', 'shift_g', 'shift_i', 'shift_o', 'slash', 'space' ].forEach(function(key) { key = 'key_' + key; self.$annotationPanel.bindEvent(key, function() { that.triggerEvent(key); }); }); that.setElement( Ox.SplitPanel({ elements: [ { element: self.$videoPanel }, { collapsed: !self.options.showAnnotations, collapsible: true, element: self.$annotationPanel, resizable: true, resize: [192, 256, 320, 384], size: self.options.annotationsSize, tooltip: self.options.tooltips ? 'annotations' : false } ], orientation: 'horizontal' }) ); function changeTimeline(data) { self.options.position = data.position; self.$video.options({position: self.options.position}); self.$annotationPanel.options({position: self.options.position}); that.triggerEvent('position', {position: self.options.position}); } function getAnnotations() { return Ox.flatten(self.options.layers.map(function(layer) { return layer.items.map(function(item) { return {id: item.id, 'in': item['in'], out: item.out, text: item.value}; }); })).sort(sortAnnotations); } function getPlayerHeight() { return self.options.height - self.options.showTimeline * 80 - 1; } function getPlayerWidth() { return self.options.width - (self.options.showAnnotations && !self.fullscreen) * self.options.annotationsSize - 1; } function getTimelineWidth() { return self.options.width - (self.options.showAnnotations && !self.fullscreen) * self.options.annotationsSize - 16 - 1; } function resizeAnnotations(data) { // called on annotations resize self.options.annotationsSize = data.size; self.$video.options({ width: getPlayerWidth() }); self.$timeline.options({ width: getTimelineWidth() }); self.$annotationPanel.options({width: data.size}); } function resizeendAnnotations(data) { that.triggerEvent('annotationssize', data.size); } function resizeElement(data) { // called on browser toggle self.options.height = data.size; self.$video.options({ height: getPlayerHeight() }); } /* function resizePanel(data) { // called on annotations toggle <-- FIXME: NOT TRUE Ox.print('RESIZEPANEL----------') self.$video.options({ width: getPlayerWidth() }); self.$timeline.options({ width: getTimelineWidth() }); } */ function selectAnnotation(data) { self.options.selected = data.id; if (self.options.selected) { setPosition(data['in']); setPoint('in', data['in']); setPoint('out', data.out); } self.$annotationPanel.options({selected: self.options.selected}); that.triggerEvent('select', {id: self.options.selected}); } function setPoint(point, position) { self.options[point] = position; self.$video.options(point, position); self.$timeline.options(point, position); self.$annotationPanel.options(point, position); } function setPosition(position, playing) { var minute = parseInt(position / 60), previousMinute = parseInt(self.options.position / 60); self.options.position = position; !playing && self.$video.options({position: self.options.position}); self.$timeline.options({position: self.options.position}); self.$annotationPanel.options({position: self.options.position}); if (!playing || minute != previousMinute) { that.triggerEvent('position', { position: !playing ? self.options.position : minute * 60 }); } } function sortAnnotations(a, b) { var ret = 0; if (a['in'] < b['in']) { ret = -1; } else if (a['in'] > b['in']) { ret = 1; } else if (a.out < b.out) { ret = -1; } else if (a.out > b.out) { ret = 1; } else if (a.value < b.value) { ret = -1; } else if (a.value > b.value) { ret = 1; } return ret; } function toggleAnnotations(data) { self.options.showAnnotations = !data.collapsed; self.$video.options({ width: getPlayerWidth() }); self.$timeline.options({ width: getTimelineWidth() }); that.triggerEvent('toggleannotations', { showAnnotations: self.options.showAnnotations }); } function toggleControls(data) { self.options.showTimeline = !data.collapsed; self.$video.options({ height: getPlayerHeight() }); that.triggerEvent('toggletimeline', { showTimeline: self.options.showTimeline }); } function toggleMuted() { self.$video.toggleMuted(); } function togglePaused() { self.$video.togglePaused(); self.$video.options('paused') && that.triggerEvent('position', { position: self.$video.options('position') }); } self.setOption = function(key, value) { if (key == 'fullscreen') { self.$video.options({fullscreen: value}); } else if (key == 'height') { self.$video.options({height: getPlayerHeight()}); } else if (key == 'in' || key == 'out') { setPoint(key, value); } else if (key == 'paused') { self.$video.options({paused: value}); } else if (key == 'position') { self.$video.options({position: value}); self.$timeline.options({position: value}); self.$annotationPanel.options({position: value}); } else if (key == 'selected') { self.$annotationPanel.options({selected: value}); } else if (key == 'showAnnotations') { that.$element.toggle(1); } else if (key == 'showTimeline') { self.$videoPanel.toggle(1); } else if (key == 'width') { self.$video.options({width: getPlayerWidth()}); self.$timeline.options({width: getTimelineWidth()}); } } // fixme: can these be removed? /*@ toggleAnnotations toggle annotations () -> toggle visibility of annotations @*/ that.toggleAnnotations = function() { that.$element.toggle(1); }; /*@ toggleTimeline toggle timeline () -> toggle visibility of timeline @*/ that.toggleTimeline = function() { self.$videoPanel.toggle(1); }; return that; }