video editor improvements

This commit is contained in:
rolux 2011-05-18 20:30:58 +02:00
parent f8ec3fccf4
commit a1deb20f97
8 changed files with 89 additions and 50 deletions

View file

@ -11,15 +11,15 @@ Ox.load('UI', {
annotationsSize: 256, annotationsSize: 256,
duration: 6336.08, duration: 6336.08,
find: 'dode', find: 'dode',
getFrameURL: function(position, width) {
return 'http://next.0xdb.org/0393109/frame/' + width + '/' + position + '.jpg'
},
getLargeTimelineImageURL: function(i) { getLargeTimelineImageURL: function(i) {
return 'http://next.0xdb.org/0393109/timelines/timeline.64.' + i + '.png'; return 'http://next.0xdb.org/0393109/timelines/timeline.64.' + i + '.png';
}, },
getSmallTimelineImageURL: function(i) { getSmallTimelineImageURL: function(i) {
return 'http://next.0xdb.org/0393109/timelines/timeline.16.' + i + '.png'; return 'http://next.0xdb.org/0393109/timelines/timeline.16.' + i + '.png';
}, },
getVideoImageURL: function(i) {
return 'png/0393109.png';
},
height: window.innerHeight - 129, height: window.innerHeight - 129,
'in': 3128.76, 'in': 3128.76,
out: 3130.72, out: 3130.72,

View file

@ -51,7 +51,7 @@ Ox.BlockVideoTimeline = function(options, self) {
results: self.options.results, results: self.options.results,
subtitles: self.options.subtitles, subtitles: self.options.subtitles,
timeline: self.options.getImageURL, timeline: self.options.getImageURL,
width: Math.ceil(self.options.duration), width: Math.round(self.options.duration),
type: self.options.type type: self.options.type
}); });
@ -113,7 +113,7 @@ Ox.BlockVideoTimeline = function(options, self) {
.css({ .css({
position: 'absolute', position: 'absolute',
top: '2px', top: '2px',
width: Math.ceil(self.options.duration) + 'px', width: Math.round(self.options.duration) + 'px',
height: '20px', height: '20px',
marginLeft: (-i * self.options.width) + 'px', marginLeft: (-i * self.options.width) + 'px',
//background: 'rgba(255, 0, 0, 0.1)', //background: 'rgba(255, 0, 0, 0.1)',
@ -195,6 +195,20 @@ Ox.BlockVideoTimeline = function(options, self) {
}); });
} }
function setPoint(point) {
setPointMarker(point);
self.$image.options(point, self.options[point]);
self.$lines.forEach(function($line, i) {
$($line.children()[0]).replaceWith(
self.$images[i] = self.$image.clone()
.css({
position: 'absolute',
marginLeft: (-i * self.options.width) + 'px'
})
);
});
}
function setPointMarker(point) { function setPointMarker(point) {
var position = Math.round(self.options[point]); var position = Math.round(self.options[point]);
self.$pointMarker[point].css({ self.$pointMarker[point].css({
@ -241,7 +255,9 @@ Ox.BlockVideoTimeline = function(options, self) {
} }
self.setOption = function(key, value) { self.setOption = function(key, value) {
if (key == 'position') { if (key == 'in' || key == 'out') {
setPoint(key)
} else if (key == 'position') {
setPositionMarker(); setPositionMarker();
} else if (key == 'width') { } else if (key == 'width') {
setWidth(); setWidth();

View file

@ -39,7 +39,7 @@ Ox.LargeVideoTimeline = function(options, self) {
$.extend(self, { $.extend(self, {
$cuts: [], $cuts: [],
$markerPoint: {}, $pointMarker: {},
$tiles: {}, $tiles: {},
$tooltip: new Ox.Tooltip({ $tooltip: new Ox.Tooltip({
animate: false animate: false
@ -82,13 +82,13 @@ Ox.LargeVideoTimeline = function(options, self) {
['in', 'out'].forEach(function(point) { ['in', 'out'].forEach(function(point) {
var titlecase = Ox.toTitleCase(point); var titlecase = Ox.toTitleCase(point);
self.$markerPoint[point] = $('<img>') self.$pointMarker[point] = $('<img>')
.addClass('OxMarkerPoint' + titlecase) .addClass('OxMarkerPoint' + titlecase)
.attr({ .attr({
src: Ox.UI.PATH + 'png/videoMarker' + titlecase + '.png' src: Ox.UI.PATH + 'png/videoMarker' + titlecase + '.png'
}) })
.appendTo(self.$timeline); .appendTo(self.$timeline);
setMarkerPoint(point); setPointMarker(point);
}); });
setWidth(); setWidth();
@ -132,18 +132,18 @@ Ox.LargeVideoTimeline = function(options, self) {
updateTooltip(); updateTooltip();
} }
function setMarkerPoint(point) {
self.$markerPoint[point].css({
left: (self.options[point] * self.fps) + 'px'
});
}
function setMarker() { function setMarker() {
self.$markerPosition.css({ self.$markerPosition.css({
left: (self.center - 4) + 'px', left: (self.center - 4) + 'px',
}); });
} }
function setPointMarker(point) {
self.$pointMarker[point].css({
left: (self.options[point] * self.fps) + 'px'
});
}
function setPosition() { function setPosition() {
self.tile = parseInt(self.options.position * self.fps / self.tileWidth); self.tile = parseInt(self.options.position * self.fps / self.tileWidth);
self.$timeline.css({ self.$timeline.css({
@ -215,9 +215,10 @@ Ox.LargeVideoTimeline = function(options, self) {
} }
self.setOption = function(key, value) { self.setOption = function(key, value) {
if (key == 'points') { if (key == 'in') {
setMarkerPoint('in'); setPointMarker('in');
setMarkerPoint('out'); } else if (key == 'out') {
setPointMarker('out');
} else if (key == 'position') { } else if (key == 'position') {
setPosition(); setPosition();
} else if (key == 'subtitles') { } else if (key == 'subtitles') {

View file

@ -245,6 +245,16 @@ Ox.SmallVideoTimeline = function(options, self) {
self.$image.options({ self.$image.options({
duration: value duration: value
}); });
} else if (key == 'in') {
self.$image.options({
'in': value
});
setPointMarker('in');
} else if (key == 'out') {
self.$image.options({
out: value
});
setPointMarker('out');
} else if (key == 'paused') { } else if (key == 'paused') {
self.$positionMarkerRing.css({ self.$positionMarkerRing.css({
borderColor: 'rgba(255, 255, 255, ' + (self.options.paused ? 0.5 : 1) + ')' borderColor: 'rgba(255, 255, 255, ' + (self.options.paused ? 0.5 : 1) + ')'

View file

@ -19,11 +19,6 @@ Ox.SmallVideoTimelineImage = function(options, self) {
width: self.options.width + 'px' width: self.options.width + 'px'
}); });
// fixme: unless we do a block timeline,
// we can always use a single 1920 png
// fixme: timeline doesn't have to go through canvas at all,
// just use one or more images
self.images = Ox.isString(self.options.timeline) ? self.images = Ox.isString(self.options.timeline) ?
1 : Math.ceil(self.options.duration / 3600); 1 : Math.ceil(self.options.duration / 3600);
self.imageWidth = Ox.isString(self.options.timeline) ? self.imageWidth = Ox.isString(self.options.timeline) ?
@ -169,16 +164,17 @@ Ox.SmallVideoTimelineImage = function(options, self) {
right = Math.round( right = Math.round(
subtitle.out / self.options.duration * self.imageWidth subtitle.out / self.options.duration * self.imageWidth
) + 1, ) + 1,
top = bottom - subtitle.text.split('\n').length - 2; top = bottom - subtitle.text.split('\n').length - 3;
Ox.loop(left, right, function(x) { Ox.loop(left, right, function(x) {
Ox.loop(top, bottom, function(y) { Ox.loop(top, bottom, function(y) {
var color = (y == top || y == bottom - 1) ? var color = y == top ? [0, 0, 0, 0] :
[0, 0, 0] : [255, 255, 255], (y == top + 1 || y == bottom - 1) ?
[0, 0, 0, 128] : [255, 255, 255, 128],
index = x * 4 + y * 4 * width; index = x * 4 + y * 4 * width;
data[index] = color[0]; data[index] = color[0];
data[index + 1] = color[1]; data[index + 1] = color[1];
data[index + 2] = color[2]; data[index + 2] = color[2];
data[index + 3] = 128; data[index + 3] = color[3];
}); });
}); });
}); });

View file

@ -20,9 +20,9 @@ Ox.VideoEditor = function(options, self) {
find: '', find: '',
frameURL: function() {}, frameURL: function() {},
fps: 25, fps: 25,
getFrameURL: null,
getLargeTimelineImageURL: null, getLargeTimelineImageURL: null,
getSmallTimelineImageURL: null, getSmallTimelineImageURL: null,
getVideoImageURL: null,
'in': 0, 'in': 0,
height: 0, height: 0,
largeTimeline: true, largeTimeline: true,
@ -75,7 +75,7 @@ Ox.VideoEditor = function(options, self) {
setPoint('in'); setPoint('in');
}, },
key_left: function() { key_left: function() {
movePositionBy(-1); movePositionBy(-0.04);
}, },
key_o: function() { key_o: function() {
setPoint('out'); setPoint('out');
@ -85,7 +85,7 @@ Ox.VideoEditor = function(options, self) {
}, },
key_p: playInToOut, key_p: playInToOut,
key_right: function() { key_right: function() {
movePositionBy(1); movePositionBy(0.04);
}, },
key_s: function() { key_s: function() {
// toggleSize // toggleSize
@ -100,7 +100,7 @@ Ox.VideoEditor = function(options, self) {
movePositionBy(self.options.duration); movePositionBy(self.options.duration);
}, },
key_shift_left: function() { key_shift_left: function() {
movePositionBy(-0.04); movePositionBy(1);
//movePositionBy(-60); //movePositionBy(-60);
}, },
key_shift_i: function() { key_shift_i: function() {
@ -110,11 +110,11 @@ Ox.VideoEditor = function(options, self) {
goToPoint('out'); goToPoint('out');
}, },
key_shift_right: function() { key_shift_right: function() {
movePositionBy(0.04); movePositionBy(1);
//movePositionBy(60); //movePositionBy(60);
}, },
key_shift_up: function() { key_shift_up: function() {
movePositionBy(-self.options.duration); movePositionBy(-self.options.position);
}, },
key_slash: function() { key_slash: function() {
select('cut'); select('cut');
@ -144,7 +144,7 @@ Ox.VideoEditor = function(options, self) {
['play', 'in', 'out'].forEach(function(type, i) { ['play', 'in', 'out'].forEach(function(type, i) {
self.$player[i] = new Ox.VideoPlayer({ self.$player[i] = new Ox.VideoPlayer({
controlsBottom: type == 'play' ? controlsBottom: type == 'play' ?
['play', 'playInToOut', 'mute', 'size', 'space', 'position'] : ['play', 'playInToOut', 'volume', 'size', 'space', 'position'] :
['goto', 'set', 'space', 'position'], ['goto', 'set', 'space', 'position'],
duration: self.options.duration, duration: self.options.duration,
externalControls: true, externalControls: true,
@ -160,7 +160,7 @@ Ox.VideoEditor = function(options, self) {
showMilliseconds: 2, showMilliseconds: 2,
subtitles: self.options.subtitles, subtitles: self.options.subtitles,
type: type, type: type,
video: type == 'play' ? self.options.video : self.options.getVideoImageURL, video: type == 'play' ? self.options.video : self.options.getFrameURL,
width: self.sizes.player[i].width width: self.sizes.player[i].width
}) })
.css({ .css({
@ -512,8 +512,11 @@ Ox.VideoEditor = function(options, self) {
} }
function setPoint(point) { function setPoint(point) {
var otherPoint = point == 'in' ? 'out' : 'in';
self.options[point] = self.options.position; self.options[point] = self.options.position;
self.$player[0].options(point, self.options[point]); self.$player.forEach(function($player) {
$player.options(point, self.options[point]);
});
self.$player[point == 'in' ? 1 : 2].options({ self.$player[point == 'in' ? 1 : 2].options({
position: self.options[point] position: self.options[point]
}); });

View file

@ -306,8 +306,6 @@ Ox.VideoPlayer = function(options, self) {
loadImage(); loadImage();
self.options[self.options.type] = self.options.position;
} }
/* /*
@ -407,11 +405,14 @@ Ox.VideoPlayer = function(options, self) {
src: Ox.UI.PATH + 'png/videoMarker' + titleCase + '.png' src: Ox.UI.PATH + 'png/videoMarker' + titleCase + '.png'
}) })
.appendTo(self.$videoContainer); .appendTo(self.$videoContainer);
/* // fixme: there's a bug in jquery and/or webkit
if (self.options.points[i] == self.options.position) { // normally, setMarker() should properly .show()
self.$pointMarker[point][edge].show(); // the in markers of the in player
// or the out markers of the out player,
// but only setting css display seems to work
if (self.options.type == point) {
self.$pointMarker[point][edge].css({display: 'block'});
} }
*/
}); });
}); });
@ -903,7 +904,7 @@ Ox.VideoPlayer = function(options, self) {
---------------------------------------------------------------------------- ----------------------------------------------------------------------------
*/ */
if (self.options.enableVolume) { if (self.options.enableVolume || true) { // fixme
self.$volume = $('<div>') self.$volume = $('<div>')
.addClass('OxControls OxVolume') .addClass('OxControls OxVolume')
@ -961,6 +962,8 @@ Ox.VideoPlayer = function(options, self) {
} }
self.options.type != 'play' && self.options.showMarkers && setMarkers();
self.results = []; self.results = [];
if (self.options.subtitles) { if (self.options.subtitles) {
if (Ox.isArray(self.options.subtitles)) { if (Ox.isArray(self.options.subtitles)) {
@ -1386,6 +1389,10 @@ Ox.VideoPlayer = function(options, self) {
}); });
} }
function isEqual(a, b) {
return Math.abs(a - b) < 0.001;
}
function loadImage() { function loadImage() {
self.$video self.$video
.one({ .one({
@ -1395,7 +1402,7 @@ Ox.VideoPlayer = function(options, self) {
} }
}) })
.attr({ .attr({
src: self.options.video(self.options.position) src: self.options.video(self.options.position, self.options.width)
}); });
} }
@ -1535,13 +1542,15 @@ Ox.VideoPlayer = function(options, self) {
} }
function setMarkers() { function setMarkers() {
//Ox.print('SET MARKERS', self.options.position, self.options['in'], self.options.out, self.$pointMarker);
Ox.forEach(self.$posterMarker, function(marker) { Ox.forEach(self.$posterMarker, function(marker) {
self.options.position == self.options.posterFrame ? isEqual(self.options.position, self.options.posterFrame) ?
marker.show() : marker.hide(); marker.show() : marker.hide();
}); });
Ox.forEach(self.$pointMarker, function(markers, point) { Ox.forEach(self.$pointMarker, function(markers, point) {
Ox.forEach(markers, function(marker) { Ox.forEach(markers, function(marker) {
self.options.position == self.options[point] ? //Ox.print(self.options.position, self.options[point], isEqual(self.options.position, self.options[point]))
isEqual(self.options.position, self.options[point]) ?
marker.show() : marker.hide(); marker.show() : marker.hide();
}); });
}); });
@ -1994,12 +2003,16 @@ Ox.VideoPlayer = function(options, self) {
toggleFullscreen(); toggleFullscreen();
} else if (key == 'height' || key == 'width') { } else if (key == 'height' || key == 'width') {
setSizes(); setSizes();
} else if (key == 'in' || key == 'out') {
self.options.paused && setMarkers();
} else if (key == 'muted') { } else if (key == 'muted') {
toggleMuted(); toggleMuted();
} else if (key == 'paused') { } else if (key == 'paused') {
togglePaused(); togglePaused();
} else if (key == 'position') { } else if (key == 'position') {
setPosition(value); setPosition(value);
} else if (key == 'posterFrame') {
self.options.paused && setMarkers();
} else if (key == 'scaleToFill') { } else if (key == 'scaleToFill') {
toggleScale(); toggleScale();
} }

View file

@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="256"> <svg xmlns="http://www.w3.org/2000/svg" width="256" height="256">
<line x1="88" y1="40" x2="40" y2="128" stroke="#404040" stroke-linecap="round" stroke-width="48"/> <line x1="88" y1="56" x2="24" y2="128" stroke="#404040" stroke-linecap="round" stroke-width="48"/>
<line x1="40" y1="128" x2="88" y2="216" stroke="#404040" stroke-linecap="round" stroke-width="48"/> <line x1="24" y1="128" x2="88" y2="200" stroke="#404040" stroke-linecap="round" stroke-width="48"/>
<line x1="168" y1="40" x2="216" y2="128" stroke="#404040" stroke-linecap="round" stroke-width="48"/> <line x1="168" y1="56" x2="232" y2="128" stroke="#404040" stroke-linecap="round" stroke-width="48"/>
<line x1="216" y1="128" x2="168" y2="216" stroke="#404040" stroke-linecap="round" stroke-width="48"/> <line x1="232" y1="128" x2="168" y2="200" stroke="#404040" stroke-linecap="round" stroke-width="48"/>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 490 B

After

Width:  |  Height:  |  Size: 490 B