From 3b2c8a40b1f7c6462657f2793419250146875b6c Mon Sep 17 00:00:00 2001 From: rlx <0x0073@0x2620.org> Date: Thu, 1 Aug 2013 08:41:43 +0000 Subject: [PATCH] video player panel: handle cuts and loop, add play-in-to-out, add missing keyboard shortcuts --- source/Ox.UI/js/Video/VideoPanel.js | 89 ++++++++++++++++++++++++++++- 1 file changed, 88 insertions(+), 1 deletion(-) diff --git a/source/Ox.UI/js/Video/VideoPanel.js b/source/Ox.UI/js/Video/VideoPanel.js index a17a7017..adafe461 100644 --- a/source/Ox.UI/js/Video/VideoPanel.js +++ b/source/Ox.UI/js/Video/VideoPanel.js @@ -51,6 +51,7 @@ Ox.VideoPanel = function(options, self) { enableDownload: false, enableSubtitles: false, find: '', + fps: 25, fullscreen: false, getLargeTimelineURL: null, height: 0, @@ -126,6 +127,9 @@ Ox.VideoPanel = function(options, self) { .bindEvent({ resize: resizeElement, key_0: toggleMuted, + key_comma: function() { + movePositionTo('cut', -1); + }, key_control_c: function() { that.triggerEvent('copy', [{ annotation: self.options.selected, @@ -140,6 +144,9 @@ Ox.VideoPanel = function(options, self) { out: self.options.out }]); }, + key_dot: function() { + movePositionTo('cut', 1); + }, key_equal: function() { self.$video.changeVolume(0.1); }, @@ -147,6 +154,10 @@ Ox.VideoPanel = function(options, self) { self.$annotationPanel.options({selected: ''}); setPoint('in', self.options.position, true); }, + key_l: toggleLoop, + key_left: function() { + movePositionBy(-1 / self.options.fps); + }, key_minus: function() { self.$video.changeVolume(-0.1); }, @@ -154,10 +165,34 @@ Ox.VideoPanel = function(options, self) { self.$annotationPanel.options({selected: ''}); setPoint('out', self.options.position, true); }, + key_p: playInToOut, + key_right: function() { + movePositionBy(self.options.fps); + }, + key_shift_down: function() { + movePositionBy(self.options.duration); + }, + key_shift_i: function() { + goToPoint('in'); + }, + key_shift_left: function() { + movePositionBy(-1); + }, + key_shift_o: function() { + goToPoint('out'); + }, + key_shift_right: function() { + movePositionBy(1); + }, + key_shift_up: function() { + movePositionBy(-self.options.position); + }, + key_slash: selectCut, key_space: togglePaused }); self.fullscreen = false; + self.results = []; self.$player = Ox.Element().css({overflow: 'hidden'}); @@ -167,7 +202,10 @@ Ox.VideoPanel = function(options, self) { censoredIcon: self.options.censoredIcon, censoredTooltip: self.options.censoredTooltip, controlsTop: ['fullscreen', 'title', 'find'], - controlsBottom: ['play', 'volume', 'scale', 'timeline', 'position', 'settings'], + controlsBottom: [ + 'play', 'playInToOut', 'volume', 'scale', + 'timeline', 'loop', 'position', 'settings' + ], enableDownload: self.options.enableDownload, enableFind: true, enableKeyboard: true, @@ -179,6 +217,7 @@ Ox.VideoPanel = function(options, self) { fullscreen: self.options.fullscreen, height: getPlayerHeight(), 'in': self.options['in'], + loop: self.options.loop, muted: self.options.muted, out: self.options.out, paused: self.options.paused, @@ -206,6 +245,9 @@ Ox.VideoPanel = function(options, self) { fullscreen: function(data) { self.options.fullscreen = data.fullscreen; }, + loop: function(data) { + that.triggerEvent('loop', data); + }, muted: function(data) { that.triggerEvent('muted', data); }, @@ -245,6 +287,7 @@ Ox.VideoPanel = function(options, self) { }); self.$timeline = Ox.LargeVideoTimeline({ + cuts: self.options.cuts, duration: self.options.duration, find: self.options.find, getImageURL: self.options.getLargeTimelineURL, @@ -391,6 +434,16 @@ Ox.VideoPanel = function(options, self) { })).sort(sortAnnotations); } + // fixme: why not goToNextPosition()? + function getNextPosition(type, direction) { + // type can only be 'cut' + var positions; + if (type == 'cut') { + positions = [0].concat(self.options.cuts, self.options.duration); + } + return Ox.nextValue(positions, self.options.position, direction); + } + function getPlayerHeight() { return self.options.height - self.options.showTimeline * 80 - 1; @@ -408,6 +461,18 @@ Ox.VideoPanel = function(options, self) { * self.options.annotationsSize - 16 - 1; } + function playInToOut() { + self.$video.playInToOut(); + } + + function movePositionBy(sec) { + setPosition(Ox.limit(self.options.position + sec, 0, self.options.duration)); + } + + function movePositionTo(type, direction) { + setPosition(getNextPosition(type, direction)); + } + function resizeAnnotations(data) { // called on annotations resize self.options.annotationsSize = data.size; @@ -455,6 +520,24 @@ Ox.VideoPanel = function(options, self) { that.triggerEvent('select', {id: self.options.selected}); } + function selectCut() { + var points = { + 'in': Ox.last(self.options.cuts), + out: self.options.duration + }; + Ox.forEach(self.options.cuts, function(cut, i) { + if (cut > self.options.position) { + points = { + 'in': i == 0 ? 0 : self.options.cuts[i - 1], + out: cut - 1 / self.options.fps + }; + return false; // break + } + }); + setPoint('in', points['in']); + setPoint('out', points.out); + } + function setPoint(point, position, triggerEvent) { self.options[point] = position; self.$video.options(point, position); @@ -527,6 +610,10 @@ Ox.VideoPanel = function(options, self) { }); } + function toggleLoop() { + self.$video.toggleLoop(); + } + function toggleMuted() { self.$video.toggleMuted(); }