diff --git a/demos/videoeditor/js/videoeditor.js b/demos/videoeditor/js/videoeditor.js
index 1ba72fb5..e2520906 100644
--- a/demos/videoeditor/js/videoeditor.js
+++ b/demos/videoeditor/js/videoeditor.js
@@ -11,15 +11,15 @@ Ox.load('UI', {
annotationsSize: 256,
duration: 6336.08,
find: 'dode',
+ getFrameURL: function(position, width) {
+ return 'http://next.0xdb.org/0393109/frame/' + width + '/' + position + '.jpg'
+ },
getLargeTimelineImageURL: function(i) {
return 'http://next.0xdb.org/0393109/timelines/timeline.64.' + i + '.png';
},
getSmallTimelineImageURL: function(i) {
return 'http://next.0xdb.org/0393109/timelines/timeline.16.' + i + '.png';
},
- getVideoImageURL: function(i) {
- return 'png/0393109.png';
- },
height: window.innerHeight - 129,
'in': 3128.76,
out: 3130.72,
diff --git a/source/Ox.UI/js/Video/Ox.BlockVideoTimeline.js b/source/Ox.UI/js/Video/Ox.BlockVideoTimeline.js
index 7ceb91a8..a1e6a90c 100644
--- a/source/Ox.UI/js/Video/Ox.BlockVideoTimeline.js
+++ b/source/Ox.UI/js/Video/Ox.BlockVideoTimeline.js
@@ -51,7 +51,7 @@ Ox.BlockVideoTimeline = function(options, self) {
results: self.options.results,
subtitles: self.options.subtitles,
timeline: self.options.getImageURL,
- width: Math.ceil(self.options.duration),
+ width: Math.round(self.options.duration),
type: self.options.type
});
@@ -113,7 +113,7 @@ Ox.BlockVideoTimeline = function(options, self) {
.css({
position: 'absolute',
top: '2px',
- width: Math.ceil(self.options.duration) + 'px',
+ width: Math.round(self.options.duration) + 'px',
height: '20px',
marginLeft: (-i * self.options.width) + 'px',
//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) {
var position = Math.round(self.options[point]);
self.$pointMarker[point].css({
@@ -241,7 +255,9 @@ Ox.BlockVideoTimeline = function(options, self) {
}
self.setOption = function(key, value) {
- if (key == 'position') {
+ if (key == 'in' || key == 'out') {
+ setPoint(key)
+ } else if (key == 'position') {
setPositionMarker();
} else if (key == 'width') {
setWidth();
diff --git a/source/Ox.UI/js/Video/Ox.LargeVideoTimeline.js b/source/Ox.UI/js/Video/Ox.LargeVideoTimeline.js
index 51e39676..e8384320 100644
--- a/source/Ox.UI/js/Video/Ox.LargeVideoTimeline.js
+++ b/source/Ox.UI/js/Video/Ox.LargeVideoTimeline.js
@@ -39,7 +39,7 @@ Ox.LargeVideoTimeline = function(options, self) {
$.extend(self, {
$cuts: [],
- $markerPoint: {},
+ $pointMarker: {},
$tiles: {},
$tooltip: new Ox.Tooltip({
animate: false
@@ -82,13 +82,13 @@ Ox.LargeVideoTimeline = function(options, self) {
['in', 'out'].forEach(function(point) {
var titlecase = Ox.toTitleCase(point);
- self.$markerPoint[point] = $('')
+ self.$pointMarker[point] = $('
')
.addClass('OxMarkerPoint' + titlecase)
.attr({
src: Ox.UI.PATH + 'png/videoMarker' + titlecase + '.png'
})
.appendTo(self.$timeline);
- setMarkerPoint(point);
+ setPointMarker(point);
});
setWidth();
@@ -132,18 +132,18 @@ Ox.LargeVideoTimeline = function(options, self) {
updateTooltip();
}
- function setMarkerPoint(point) {
- self.$markerPoint[point].css({
- left: (self.options[point] * self.fps) + 'px'
- });
- }
-
function setMarker() {
self.$markerPosition.css({
left: (self.center - 4) + 'px',
});
}
+ function setPointMarker(point) {
+ self.$pointMarker[point].css({
+ left: (self.options[point] * self.fps) + 'px'
+ });
+ }
+
function setPosition() {
self.tile = parseInt(self.options.position * self.fps / self.tileWidth);
self.$timeline.css({
@@ -215,9 +215,10 @@ Ox.LargeVideoTimeline = function(options, self) {
}
self.setOption = function(key, value) {
- if (key == 'points') {
- setMarkerPoint('in');
- setMarkerPoint('out');
+ if (key == 'in') {
+ setPointMarker('in');
+ } else if (key == 'out') {
+ setPointMarker('out');
} else if (key == 'position') {
setPosition();
} else if (key == 'subtitles') {
diff --git a/source/Ox.UI/js/Video/Ox.SmallVideoTimeline.js b/source/Ox.UI/js/Video/Ox.SmallVideoTimeline.js
index 689828e1..5a0aa762 100644
--- a/source/Ox.UI/js/Video/Ox.SmallVideoTimeline.js
+++ b/source/Ox.UI/js/Video/Ox.SmallVideoTimeline.js
@@ -245,6 +245,16 @@ Ox.SmallVideoTimeline = function(options, self) {
self.$image.options({
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') {
self.$positionMarkerRing.css({
borderColor: 'rgba(255, 255, 255, ' + (self.options.paused ? 0.5 : 1) + ')'
diff --git a/source/Ox.UI/js/Video/Ox.SmallVideoTimelineImage.js b/source/Ox.UI/js/Video/Ox.SmallVideoTimelineImage.js
index 157b1972..627df94b 100644
--- a/source/Ox.UI/js/Video/Ox.SmallVideoTimelineImage.js
+++ b/source/Ox.UI/js/Video/Ox.SmallVideoTimelineImage.js
@@ -19,11 +19,6 @@ Ox.SmallVideoTimelineImage = function(options, self) {
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) ?
1 : Math.ceil(self.options.duration / 3600);
self.imageWidth = Ox.isString(self.options.timeline) ?
@@ -169,16 +164,17 @@ Ox.SmallVideoTimelineImage = function(options, self) {
right = Math.round(
subtitle.out / self.options.duration * self.imageWidth
) + 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(top, bottom, function(y) {
- var color = (y == top || y == bottom - 1) ?
- [0, 0, 0] : [255, 255, 255],
+ var color = y == top ? [0, 0, 0, 0] :
+ (y == top + 1 || y == bottom - 1) ?
+ [0, 0, 0, 128] : [255, 255, 255, 128],
index = x * 4 + y * 4 * width;
data[index] = color[0];
data[index + 1] = color[1];
data[index + 2] = color[2];
- data[index + 3] = 128;
+ data[index + 3] = color[3];
});
});
});
diff --git a/source/Ox.UI/js/Video/Ox.VideoEditor.js b/source/Ox.UI/js/Video/Ox.VideoEditor.js
index ef062cfa..c6d11d4e 100644
--- a/source/Ox.UI/js/Video/Ox.VideoEditor.js
+++ b/source/Ox.UI/js/Video/Ox.VideoEditor.js
@@ -20,9 +20,9 @@ Ox.VideoEditor = function(options, self) {
find: '',
frameURL: function() {},
fps: 25,
+ getFrameURL: null,
getLargeTimelineImageURL: null,
getSmallTimelineImageURL: null,
- getVideoImageURL: null,
'in': 0,
height: 0,
largeTimeline: true,
@@ -75,7 +75,7 @@ Ox.VideoEditor = function(options, self) {
setPoint('in');
},
key_left: function() {
- movePositionBy(-1);
+ movePositionBy(-0.04);
},
key_o: function() {
setPoint('out');
@@ -85,7 +85,7 @@ Ox.VideoEditor = function(options, self) {
},
key_p: playInToOut,
key_right: function() {
- movePositionBy(1);
+ movePositionBy(0.04);
},
key_s: function() {
// toggleSize
@@ -100,7 +100,7 @@ Ox.VideoEditor = function(options, self) {
movePositionBy(self.options.duration);
},
key_shift_left: function() {
- movePositionBy(-0.04);
+ movePositionBy(1);
//movePositionBy(-60);
},
key_shift_i: function() {
@@ -110,11 +110,11 @@ Ox.VideoEditor = function(options, self) {
goToPoint('out');
},
key_shift_right: function() {
- movePositionBy(0.04);
+ movePositionBy(1);
//movePositionBy(60);
},
key_shift_up: function() {
- movePositionBy(-self.options.duration);
+ movePositionBy(-self.options.position);
},
key_slash: function() {
select('cut');
@@ -144,7 +144,7 @@ Ox.VideoEditor = function(options, self) {
['play', 'in', 'out'].forEach(function(type, i) {
self.$player[i] = new Ox.VideoPlayer({
controlsBottom: type == 'play' ?
- ['play', 'playInToOut', 'mute', 'size', 'space', 'position'] :
+ ['play', 'playInToOut', 'volume', 'size', 'space', 'position'] :
['goto', 'set', 'space', 'position'],
duration: self.options.duration,
externalControls: true,
@@ -160,7 +160,7 @@ Ox.VideoEditor = function(options, self) {
showMilliseconds: 2,
subtitles: self.options.subtitles,
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
})
.css({
@@ -512,8 +512,11 @@ Ox.VideoEditor = function(options, self) {
}
function setPoint(point) {
+ var otherPoint = point == 'in' ? 'out' : 'in';
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({
position: self.options[point]
});
diff --git a/source/Ox.UI/js/Video/Ox.VideoPlayer.js b/source/Ox.UI/js/Video/Ox.VideoPlayer.js
index 17c84972..c986d5f6 100644
--- a/source/Ox.UI/js/Video/Ox.VideoPlayer.js
+++ b/source/Ox.UI/js/Video/Ox.VideoPlayer.js
@@ -306,8 +306,6 @@ Ox.VideoPlayer = function(options, self) {
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'
})
.appendTo(self.$videoContainer);
- /*
- if (self.options.points[i] == self.options.position) {
- self.$pointMarker[point][edge].show();
+ // fixme: there's a bug in jquery and/or webkit
+ // normally, setMarker() should properly .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 = $('