diff --git a/demos/video/js/video.js b/demos/video/js/video.js
index 62e0b560..825dc31d 100644
--- a/demos/video/js/video.js
+++ b/demos/video/js/video.js
@@ -34,6 +34,7 @@ Ox.load('UI', {
Ox.VideoPlayer({
controls: ['play', 'mute', 'fullscreen', 'scale', 'timeline', 'position'],
enableKeyboard: true,
+ find: 'brick',
focus: 'mouseenter',
height: 192,
'in': 3128.725,
@@ -126,6 +127,7 @@ Ox.load('UI', {
.bindEvent({
resize: function(foo, size) {
$videos[0].options({width: size - 32});
+ $smallTimeline.options({width: size - 16});
}
}),
size: 392,
@@ -163,7 +165,7 @@ Ox.load('UI', {
.bindEvent({
resize: function(foo, size) {
$videos[2].options({width: size - 32});
- $blockTimeline.options({width: size - 40});
+ $blockTimeline.options({width: size - 16});
}
}),
size: 392,
@@ -192,19 +194,43 @@ Ox.load('UI', {
Ox.get('srt/0393109.srt', function(srt) {
var subtitles = Ox.parseSRT(srt);
$foo.append(
- Ox.SmallVideoTimelineImages({
+ $smallTimeline = Ox.SmallVideoTimeline({
duration: 6336.08,
+ find: 'brick',
getTimelineURL: function(i) {
return 'png/timeline.16.' + i + '.png';
},
- 'in': 1800,
- out: 1900,
- results: [
- {'in': 3600, out: 3700}
- ],
+ 'in': 3128.725,
+ out: 3130.725,
+ results: results,
subtitles: subtitles,
type: 'editor',
- width: 392
+ width: 376
+ })
+ .css({
+ position: 'absolute',
+ left: '4px',
+ top: '4px'
+ })
+ );
+ $foo.append(
+ $playerTimeline = Ox.SmallVideoTimeline({
+ duration: 6336.08,
+ find: 'brick',
+ getTimelineURL: function(i) {
+ return 'png/timeline.16.' + i + '.png';
+ },
+ 'in': 3128.725,
+ out: 3130.725,
+ results: results,
+ subtitles: subtitles,
+ type: 'player',
+ width: 376
+ })
+ .css({
+ position: 'absolute',
+ left: '4px',
+ top: '32px'
})
);
$bar.append(
@@ -217,13 +243,14 @@ Ox.load('UI', {
'in': 3128.725,
out: 3130.725,
results: results,
+ showMilliseconds: 2,
subtitles: subtitles,
- width: 353
+ width: 376
})
.css({
position: 'absolute',
- left: '16px',
- top: '16px'
+ left: '4px',
+ top: '4px'
})
.bindEvent('position', function(data) {
$videos[2].options({
diff --git a/source/Ox.UI/js/Video/Ox.BlockVideoTimeline.js b/source/Ox.UI/js/Video/Ox.BlockVideoTimeline.js
index b02ca61a..4f204ef5 100644
--- a/source/Ox.UI/js/Video/Ox.BlockVideoTimeline.js
+++ b/source/Ox.UI/js/Video/Ox.BlockVideoTimeline.js
@@ -16,6 +16,7 @@ Ox.BlockVideoTimeline = function(options, self) {
.options(options || {})
.css({
position: 'absolute',
+ //background: 'rgba(192, 192, 192, 0.1)'
})
.bind({
mousedown: mousedown,
@@ -89,7 +90,7 @@ Ox.BlockVideoTimeline = function(options, self) {
overflow: 'hidden'
})
.appendTo(that.$element);
- self.$images[i] = Ox.SmallVideoTimelineImages({
+ self.$images[i] = Ox.SmallVideoTimelineImage({
duration: self.options.duration,
editing: self.options.editing,
getTimelineURL: self.options.getTimelineURL,
@@ -105,13 +106,15 @@ Ox.BlockVideoTimeline = function(options, self) {
marginLeft: (-i * self.options.width) + 'px'
})
.appendTo(self.$lines[i]);
- self.$interfaces[i] = $('
').addClass('OxInterface')
+ self.$interfaces[i] = $('
')
+ .addClass('OxInterface')
.css({
position: 'absolute',
top: '2px',
width: Math.ceil(self.options.duration) + 'px',
height: '20px',
marginLeft: (-i * self.options.width) + 'px',
+ //background: 'rgba(255, 0, 0, 0.1)',
zIndex: 11
})
.appendTo(self.$lines[i]);
@@ -123,6 +126,7 @@ Ox.BlockVideoTimeline = function(options, self) {
function getPosition(e) {
//FIXME: this might still be broken in opera according to http://acko.net/blog/mouse-handling-and-absolute-positions-in-javascript
+ Ox.print('offsetX', e.offsetX)
return (e.offsetX ? e.offsetX : e.clientX - $(e.target).offset().left);
}
@@ -171,7 +175,7 @@ Ox.BlockVideoTimeline = function(options, self) {
Ox.highlight(subtitle.text, self.options.find, 'OxHighlight').replace(/\n/g, '
') +
'
' +
Ox.formatDuration(subtitle['in'], 3) + ' - ' + Ox.formatDuration(subtitle['out'], 3) :
- Ox.formatDuration(position, 3)
+ Ox.formatDuration(position)
})
.show(e.clientX, e.clientY);
@@ -189,7 +193,6 @@ Ox.BlockVideoTimeline = function(options, self) {
function setPointMarker(point) {
var position = Math.round(self.options[point]);
- Ox.print('$$ position', position)
self.$pointMarker[point].css({
left: (position % self.options.width) + 'px',
top: (parseInt(position / self.options.width) *
diff --git a/source/Ox.UI/js/Video/Ox.SmallVideoTimeline.js b/source/Ox.UI/js/Video/Ox.SmallVideoTimeline.js
index 93e734c4..d3d77630 100644
--- a/source/Ox.UI/js/Video/Ox.SmallVideoTimeline.js
+++ b/source/Ox.UI/js/Video/Ox.SmallVideoTimeline.js
@@ -8,46 +8,254 @@ Ox.SmallVideoTimeline = function(options, self) {
getTimelineURL: null,
'in': 0,
out: 0,
- width: 256,
- type: 'player'
+ paused: false,
+ showMilliseconds: 0,
+ type: 'player',
+ width: 256
})
.options(options || {})
.addClass('OxSmallVideoTimeline')
- .css({
+ .css(Ox.extend({
width: self.options.width + 'px'
- });
+ }, self.options.type == 'player' ? {
+ background: 'rgb(0, 0, 0)',
+ borderRadius: '8px'
+ } : {}));
self.height = self.options.type == 'player' ? 16 : 24;
+ self.imageLeft = self.options.type == 'player' ? 8 : 4;
+ self.imageWidth = self.options.width -
+ (self.options.type == 'player' ? 16 : 8)
self.imageHeight = self.options.type == 'player' ? 16 : 18;
- self.imageTop = self.options.type == 'player' ? 0 : 3;
+ self.interfaceLeft = self.options.type == 'player' ? 0 : 4;
+ self.interfaceTop = self.options.type == 'player' ? 0 : 2;
+ self.interfaceWidth = self.options.type == 'player' ? self.options.width : self.imageWidth;
that.css({
height: self.height + 'px'
});
- self.tooltip = Ox.Tooltip({
+ self.$image = Ox.SmallVideoTimelineImage({
+ duration: self.options.duration,
+ editing: self.options.editing,
+ getTimelineURL: self.options.getTimelineURL,
+ 'in': self.options['in'],
+ out: self.options.out,
+ results: self.options.results,
+ subtitles: self.options.subtitles,
+ width: self.imageWidth,
+ type: self.options.type
+ })
+ .css({
+ position: 'absolute',
+ left: self.imageLeft + 'px',
+ width: self.options.width + 'px'
+ })
+ .appendTo(that);
+
+ self.$interface = Ox.Element()
+ .addClass('OxInterface')
+ .css({
+ position: 'absolute',
+ left: self.interfaceLeft + 'px',
+ top: self.interfaceTop + 'px',
+ width: self.interfaceWidth + 'px',
+ height: '20px',
+ zIndex: 11
+ })
+ .bind({
+ mousedown: mousedown,
+ mouseleave: mouseleave,
+ mousemove: mousemove
+ })
+ .bindEvent({
+ drag: function(event, e) {
+ mousedown(e);
+ }
+ })
+ .appendTo(that);
+
+ if (self.options.type == 'player') {
+ self.$positionMarker = $('
')
+ .css({
+ position: 'absolute',
+ width: '14px',
+ height: '14px',
+ border: '1px solid rgba(0, 0, 0, 0.5)',
+ borderRadius: '8px'
+ })
+ .append(
+ self.$positionMarkerRing = $('
')
+ .css({
+ width: '10px',
+ height: '10px',
+ border: '2px solid rgba(255, 255, 255, ' + (self.options.paused ? 0.5 : 1) + ')',
+ borderRadius: '7px',
+ })
+ .append(
+ $('
')
+ .css({
+ width: '8px',
+ height: '8px',
+ border: '1px solid rgba(0, 0, 0, 0.5)',
+ borderRadius: '5px',
+ })
+ )
+ )
+ .appendTo(that.$element);
+ } else {
+ self.$positionMarker = $('
')
+ .attr({
+ src: Ox.UI.PATH + 'png/videoMarkerPlay.png'
+ })
+ .css({
+ position: 'absolute',
+ top: '2px',
+ width: '9px',
+ height: '5px',
+ zIndex: 10
+ })
+ .appendTo(that.$element);
+ }
+ setPositionMarker();
+
+ if (self.options.type == 'editor') {
+ self.$pointMarker = {};
+ ['in', 'out'].forEach(function(point) {
+ var titleCase = Ox.toTitleCase(point);
+ self.$pointMarker[point] = $('
')
+ .addClass('OxPointMarker' + titleCase)
+ .attr({
+ src: Ox.UI.PATH + 'png/videoMarker' + titleCase + '.png'
+ })
+ .css({
+ position: 'absolute',
+ top: '16px',
+ width: '6px',
+ height: '6px',
+ marginLeft: (point == 'in' ? -1 : 4) + 'px',
+ zIndex: 10
+ })
+ .appendTo(that.$element);
+ setPointMarker(point);
+ });
+ }
+
+ self.$tooltip = Ox.Tooltip({
animate: false
}).css({
textAlign: 'center'
});
- getImageURL('timeline', function(timelineURL) {
+ function getPosition(e) {
+ var position =
+ (
+ (e.offsetX ? e.offsetX : e.clientX - $(e.target).offset().left) -
+ (self.options.type == 'player' ? 8 : 0)
+ ) * self.options.duration / self.imageWidth;
+ return Ox.limit(position, 0, self.options.duration);
+ }
- $('
')
- .attr({
- src: timelineURL
+ function getSubtitle(position) {
+ var subtitle = '';
+ Ox.forEach(self.options.subtitles, function(v) {
+ if (v['in'] <= position && v.out > position) {
+ subtitle = v;
+ return false;
+ }
+ });
+ return subtitle;
+ }
+
+ function mousedown(e) {
+ if ($(e.target).is('.OxInterface')) {
+ self.options.position = getPosition(e);
+ setPositionMarker();
+ if (!self.triggered) {
+ that.triggerEvent('position', {
+ position: self.options.position
+ });
+ self.triggered = true;
+ setTimeout(function() {
+ self.triggered = false;
+ }, 250);
+ }
+ }
+ }
+
+ function mouseleave() {
+ self.$tooltip.hide();
+ }
+
+ function mousemove(e) {
+ var position, subtitle;
+ if ($(e.target).is('.OxInterface')) {
+ position = getPosition(e);
+ subtitle = getSubtitle(position);
+ self.$tooltip.options({
+ title: subtitle ?
+ '
' +
+ Ox.highlight(subtitle.text, self.options.find, 'OxHighlight').replace(/\n/g, '
') +
+ '' +
+ Ox.formatDuration(subtitle['in'], self.options.showMilliseconds) + ' - ' +
+ Ox.formatDuration(subtitle['out'], self.options.showMilliseconds) :
+ Ox.formatDuration(position, self.options.showMilliseconds)
+ })
+ .show(e.clientX, e.clientY);
+
+ } else {
+ self.$tooltip.hide();
+ }
+ }
+
+ function setPointMarker(point) {
+ self.$pointMarker[point].css({
+ left: self.imageLeft + Math.round(
+ self.options[point] * self.imageWidth / self.options.duration
+ ) + 'px'
+ });
+ }
+
+ function setPositionMarker() {
+ Ox.print(self.interfaceLeft + Math.round(
+ self.options.position * self.imageWidth / self.options.duration
+ ));
+ self.$positionMarker.css({
+ left: self.interfaceLeft + Math.round(
+ self.options.position * self.imageWidth / self.options.duration
+ ) - (self.options.type == 'editor' ? 4 : 0) + 'px',
+ });
+ }
+
+ function setWidth() {
+ that.css({
+ width: self.options.width + 'px'
+ });
+ self.$image.css({
+ width: self.imageWidth + 'px'
+ });
+ self.$image.children().css({
+ width: self.imageWidth + 'px'
+ });
+ self.$interface.css({
+ width: self.interfaceWidth + 'px'
+ });
+ setPositionMarker();
+ if (self.options.type == 'editor') {
+ setPointMarker('in');
+ setPointMarker('out');
+ }
+ }
+
+ self.setOption = function(key, value) {
+ if (key == 'paused') {
+ self.$positionMarkerRing.css({
+ borderColor: 'rgba(255, 255, 255, ' + (self.options.paused ? 0.5 : 1) + ')'
})
- .css({
- width: self.options.width + 'px',
- height: self.imageHeight + 'px',
- top: self.imageTop + 'px'
- })
- .appendTo(that.$element);
-
-
-
- });
-
+ } else if (key == 'width') {
+ setWidth();
+ }
+ };
return that;
diff --git a/source/Ox.UI/js/Video/Ox.SmallVideoTimelineImages.js b/source/Ox.UI/js/Video/Ox.SmallVideoTimelineImage.js
similarity index 99%
rename from source/Ox.UI/js/Video/Ox.SmallVideoTimelineImages.js
rename to source/Ox.UI/js/Video/Ox.SmallVideoTimelineImage.js
index 5e0df72c..f6b3bf07 100644
--- a/source/Ox.UI/js/Video/Ox.SmallVideoTimelineImages.js
+++ b/source/Ox.UI/js/Video/Ox.SmallVideoTimelineImage.js
@@ -1,4 +1,4 @@
-Ox.SmallVideoTimelineImages = function(options, self) {
+Ox.SmallVideoTimelineImage = function(options, self) {
self = self || {};
var that = Ox.Element({}, self)
diff --git a/source/Ox.UI/js/Video/Ox.VideoPlayer.js b/source/Ox.UI/js/Video/Ox.VideoPlayer.js
index a465e6e8..7e02e999 100644
--- a/source/Ox.UI/js/Video/Ox.VideoPlayer.js
+++ b/source/Ox.UI/js/Video/Ox.VideoPlayer.js
@@ -508,7 +508,6 @@ Ox.VideoPlayer = function(options, self) {
//*/
self.$positionMarker = $('
')
- .addClass('positionmarker')
.css({
float: 'left',
width: '14px',