video editor improvements
This commit is contained in:
parent
f8ec3fccf4
commit
a1deb20f97
8 changed files with 89 additions and 50 deletions
|
@ -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,
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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') {
|
||||||
|
|
|
@ -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) + ')'
|
||||||
|
|
|
@ -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];
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -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]
|
||||||
});
|
});
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 |
Loading…
Reference in a new issue