add new timeline and find input to video player
This commit is contained in:
parent
ac2ea5f53d
commit
ce33d3650a
6 changed files with 326 additions and 162 deletions
|
@ -27,14 +27,15 @@ Ox.load('UI', {
|
||||||
{'in': 5780.235, out: 5782.435},
|
{'in': 5780.235, out: 5782.435},
|
||||||
{'in': 5881.365, out: 5886.635}
|
{'in': 5881.365, out: 5886.635}
|
||||||
],
|
],
|
||||||
timeline = 'http://next.0xdb.org/' + id + '/timeline.16.png',
|
timeline = 'png/timeline.16.png',
|
||||||
url = 'http://next.0xdb.org/' + id + '/96p.webm',
|
url = 'http://next.0xdb.org/' + id + '/96p.webm',
|
||||||
videoSize = getVideoSize(),
|
videoSize = getVideoSize(),
|
||||||
$videos = [
|
$videos = [
|
||||||
Ox.VideoPlayer({
|
Ox.VideoPlayer({
|
||||||
controls: ['play', 'mute', 'fullscreen', 'scale', 'timeline', 'position'],
|
controls: ['play', 'mute', 'fullscreen', 'scale', 'timeline', 'position'],
|
||||||
|
enableFind: true,
|
||||||
|
enableFullscreen: true,
|
||||||
enableKeyboard: true,
|
enableKeyboard: true,
|
||||||
find: 'brick',
|
|
||||||
focus: 'mouseenter',
|
focus: 'mouseenter',
|
||||||
height: 192,
|
height: 192,
|
||||||
'in': 3128.725,
|
'in': 3128.725,
|
||||||
|
@ -47,7 +48,9 @@ Ox.load('UI', {
|
||||||
showIconOnLoad: true,
|
showIconOnLoad: true,
|
||||||
showProgress: false,
|
showProgress: false,
|
||||||
subtitles: 'srt/' + id + '.srt',
|
subtitles: 'srt/' + id + '.srt',
|
||||||
timeline: timeline,
|
timeline: function(i) {
|
||||||
|
return 'png/timeline.16.' + i + '.png';
|
||||||
|
},
|
||||||
title: '<b>Brick</b> - Rian Johnson - 2005',
|
title: '<b>Brick</b> - Rian Johnson - 2005',
|
||||||
video: url + '?' + + Ox.random(1000000),
|
video: url + '?' + + Ox.random(1000000),
|
||||||
width: 360
|
width: 360
|
||||||
|
|
BIN
demos/video/png/logo.png
Normal file
BIN
demos/video/png/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 32 KiB |
|
@ -3,6 +3,7 @@ Ox.SmallVideoTimeline = function(options, self) {
|
||||||
self = self || {};
|
self = self || {};
|
||||||
var that = Ox.Element({}, self)
|
var that = Ox.Element({}, self)
|
||||||
.defaults({
|
.defaults({
|
||||||
|
_offset: 0, // hack for cases where all these position: absolute elements have to go into a float: left
|
||||||
duration: 0,
|
duration: 0,
|
||||||
editing: false,
|
editing: false,
|
||||||
getTimelineURL: null,
|
getTimelineURL: null,
|
||||||
|
@ -226,13 +227,15 @@ Ox.SmallVideoTimeline = function(options, self) {
|
||||||
self.$positionMarker.css({
|
self.$positionMarker.css({
|
||||||
left: self.interfaceLeft + Math.round(
|
left: self.interfaceLeft + Math.round(
|
||||||
self.options.position * self.imageWidth / self.options.duration
|
self.options.position * self.imageWidth / self.options.duration
|
||||||
) - (self.options.type == 'editor' ? 4 : 0) + 'px',
|
) - (self.options.type == 'editor' ? 4 : 0) + self.options._offset + 'px',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function setWidth() {
|
function setWidth() {
|
||||||
self.imageWidth = self.options.width -
|
self.imageWidth = self.options.width -
|
||||||
(self.options.type == 'player' ? 16 : 8);
|
(self.options.type == 'player' ? 16 : 8);
|
||||||
|
self.interfaceWidth = self.options.type == 'player' ?
|
||||||
|
self.options.width : self.imageWidth;
|
||||||
that.css({
|
that.css({
|
||||||
width: self.options.width + 'px'
|
width: self.options.width + 'px'
|
||||||
});
|
});
|
||||||
|
@ -252,10 +255,24 @@ Ox.SmallVideoTimeline = function(options, self) {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.setOption = function(key, value) {
|
self.setOption = function(key, value) {
|
||||||
if (key == 'paused') {
|
if (key == 'duration') {
|
||||||
|
self.$image.options({
|
||||||
|
duration: value
|
||||||
|
});
|
||||||
|
} 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) + ')'
|
||||||
})
|
})
|
||||||
|
} else if (key == 'position') {
|
||||||
|
setPositionMarker();
|
||||||
|
} else if (key == 'results') {
|
||||||
|
self.$image.options({
|
||||||
|
results: value
|
||||||
|
});
|
||||||
|
} else if (key == 'subtitles') {
|
||||||
|
self.$image.options({
|
||||||
|
subtitles: value
|
||||||
|
});
|
||||||
} else if (key == 'width') {
|
} else if (key == 'width') {
|
||||||
setWidth();
|
setWidth();
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,6 @@ Ox.SmallVideoTimelineImage = function(options, self) {
|
||||||
type: 'player'
|
type: 'player'
|
||||||
})
|
})
|
||||||
.options(options || {})
|
.options(options || {})
|
||||||
.addClass('OxSmallVideoTimeline')
|
|
||||||
.css({
|
.css({
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
width: self.options.width + 'px'
|
width: self.options.width + 'px'
|
||||||
|
@ -84,6 +83,8 @@ Ox.SmallVideoTimelineImage = function(options, self) {
|
||||||
.appendTo(that.$element);
|
.appendTo(that.$element);
|
||||||
|
|
||||||
function getImageURL(image, callback) {
|
function getImageURL(image, callback) {
|
||||||
|
Ox.print(image == 'results' || image == 'selection' ?
|
||||||
|
self.options.width : Math.ceil(self.options.duration))
|
||||||
var width = image == 'results' || image == 'selection' ?
|
var width = image == 'results' || image == 'selection' ?
|
||||||
self.options.width : Math.ceil(self.options.duration),
|
self.options.width : Math.ceil(self.options.duration),
|
||||||
height = self.imageHeight,
|
height = self.imageHeight,
|
||||||
|
@ -160,21 +161,33 @@ Ox.SmallVideoTimelineImage = function(options, self) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} else if (image == 'timeline') {
|
} else if (image == 'timeline') {
|
||||||
var counter = 0,
|
var $image, counter, images,
|
||||||
images = Math.ceil(self.options.duration / 3600),
|
|
||||||
top = self.options.type == 'player' ? 0 : 1;
|
top = self.options.type == 'player' ? 0 : 1;
|
||||||
Ox.loop(images, function(i) {
|
if (Ox.isString(self.options.timeline)) {
|
||||||
var $image = $('<img>')
|
$image = $('<img>')
|
||||||
.attr({
|
.attr({
|
||||||
src: self.options.getTimelineURL(i)
|
src: self.options.getTimelineURL(0)
|
||||||
})
|
})
|
||||||
.load(function() {
|
.load(function() {
|
||||||
context.drawImage($image[0], i * 3600, top);
|
context.drawImage($image[0])
|
||||||
if (++counter == images) {
|
callback(canvas.toDataURL());
|
||||||
callback(canvas.toDataURL());
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
})
|
} else {
|
||||||
|
counter = 0;
|
||||||
|
images = Math.ceil(self.options.duration / 3600);
|
||||||
|
Ox.loop(images, function(i) {
|
||||||
|
var $image = $('<img>')
|
||||||
|
.attr({
|
||||||
|
src: self.options.getTimelineURL(i)
|
||||||
|
})
|
||||||
|
.load(function() {
|
||||||
|
context.drawImage($image[0], i * 3600, top);
|
||||||
|
if (++counter == images) {
|
||||||
|
callback(canvas.toDataURL());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (image != 'timeline') {
|
if (image != 'timeline') {
|
||||||
context.putImageData(imageData, 0, 0);
|
context.putImageData(imageData, 0, 0);
|
||||||
|
|
|
@ -14,6 +14,8 @@ Ox.VideoPlayer <f> Generic Video Player
|
||||||
is just empty space that separates left-aligned from right-aligned
|
is just empty space that separates left-aligned from right-aligned
|
||||||
controls
|
controls
|
||||||
duration <n|-1> Duration (sec)
|
duration <n|-1> Duration (sec)
|
||||||
|
enableFind <b|false> If true, enable find
|
||||||
|
enableFullscreen <b|false> If true, enable fullscreen
|
||||||
enableKeyboard <b|false> If true, enable keyboard controls
|
enableKeyboard <b|false> If true, enable keyboard controls
|
||||||
externalControls <b|false> If true, controls are outside the video
|
externalControls <b|false> If true, controls are outside the video
|
||||||
find <s|''> Query string
|
find <s|''> Query string
|
||||||
|
@ -66,7 +68,9 @@ Ox.VideoPlayer = function(options, self) {
|
||||||
.defaults({
|
.defaults({
|
||||||
annotations: [],
|
annotations: [],
|
||||||
controls: [],
|
controls: [],
|
||||||
duration: 86399,
|
duration: 0,
|
||||||
|
enableFind: false,
|
||||||
|
enableFullscreen: false,
|
||||||
enableKeyboard: false,
|
enableKeyboard: false,
|
||||||
externalControls: false,
|
externalControls: false,
|
||||||
find: '',
|
find: '',
|
||||||
|
@ -135,6 +139,13 @@ Ox.VideoPlayer = function(options, self) {
|
||||||
key_1: function() {
|
key_1: function() {
|
||||||
toggleScale();
|
toggleScale();
|
||||||
},
|
},
|
||||||
|
key_f: function() {
|
||||||
|
// need timeout so the "f" doesn't appear in the input field
|
||||||
|
setTimeout(self.$findInput.focusInput, 0);
|
||||||
|
},
|
||||||
|
key_g: function() {
|
||||||
|
goToNextResult(1);
|
||||||
|
},
|
||||||
key_left: function() {
|
key_left: function() {
|
||||||
setPosition(self.options.position - self.secondsPerFrame, true);
|
setPosition(self.options.position - self.secondsPerFrame, true);
|
||||||
},
|
},
|
||||||
|
@ -145,7 +156,10 @@ Ox.VideoPlayer = function(options, self) {
|
||||||
setPosition(self.options.position + self.secondsPerFrame, true);
|
setPosition(self.options.position + self.secondsPerFrame, true);
|
||||||
},
|
},
|
||||||
key_shift_f: function() {
|
key_shift_f: function() {
|
||||||
toggleFullscreen(true);
|
self.options.enableFullscreen && toggleFullscreen(true);
|
||||||
|
},
|
||||||
|
key_shift_g: function() {
|
||||||
|
goToNextResult(-1);
|
||||||
},
|
},
|
||||||
key_space: function() {
|
key_space: function() {
|
||||||
togglePaused(true);
|
togglePaused(true);
|
||||||
|
@ -196,15 +210,24 @@ Ox.VideoPlayer = function(options, self) {
|
||||||
} else {
|
} else {
|
||||||
Ox.get(self.options.subtitles, function(data) {
|
Ox.get(self.options.subtitles, function(data) {
|
||||||
self.options.subtitles = Ox.parseSRT(data);
|
self.options.subtitles = Ox.parseSRT(data);
|
||||||
|
self.results = find(self.options.find);
|
||||||
|
Ox.print('--setting results--', self.$timeline)
|
||||||
|
if (self.options.duration) {
|
||||||
|
self.$timeline && self.$timeline.options({
|
||||||
|
results: self.results,
|
||||||
|
subtitles: self.options.subtitles
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
});
|
});
|
||||||
//self.options.subtitles = [];
|
self.options.subtitles = [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
self.results = find(self.options.find);
|
||||||
|
|
||||||
self.buffered = [];
|
self.buffered = [];
|
||||||
self.controlsTimeout;
|
self.controlsTimeout;
|
||||||
self.dragTimeout;
|
|
||||||
|
|
||||||
self.$videoContainer = $('<div>')
|
self.$videoContainer = $('<div>')
|
||||||
.css({
|
.css({
|
||||||
|
@ -304,7 +327,7 @@ Ox.VideoPlayer = function(options, self) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self.options.subtitles.length) {
|
if (self.options.subtitles.length || true) { // fixme
|
||||||
self.$subtitle = $('<div>')
|
self.$subtitle = $('<div>')
|
||||||
//.addClass('OxSubtitle')
|
//.addClass('OxSubtitle')
|
||||||
.css({
|
.css({
|
||||||
|
@ -339,6 +362,114 @@ Ox.VideoPlayer = function(options, self) {
|
||||||
.appendTo(that.$element);
|
.appendTo(that.$element);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (self.options.enableFind) {
|
||||||
|
|
||||||
|
self.$find = $('<div>')
|
||||||
|
.addClass('OxInterface')
|
||||||
|
.css({
|
||||||
|
position: 'absolute',
|
||||||
|
right: '16px',
|
||||||
|
top: (self.options.title ? 32 : 16) + 'px',
|
||||||
|
width: '128px',
|
||||||
|
borderRadius: '8px',
|
||||||
|
opacity: 0
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
backgroundImage: '-moz-linear-gradient(top, rgba(64, 64, 64, 0.5), rgba(0, 0, 0, 0.5))'
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
backgroundImage: '-webkit-linear-gradient(top, rgba(64, 64, 64, 0.5), rgba(0, 0, 0, 0.5))'
|
||||||
|
})
|
||||||
|
.appendTo(that.$element);
|
||||||
|
|
||||||
|
self.$previousButton = Ox.Button({
|
||||||
|
style: 'symbol',
|
||||||
|
title: 'arrowLeft',
|
||||||
|
tooltip: 'Previous [Shift+G]',
|
||||||
|
type: 'image'
|
||||||
|
})
|
||||||
|
.css({float: 'left', opacity: 0.25})
|
||||||
|
.bindEvent({
|
||||||
|
click: function() {
|
||||||
|
goToNextResult(-1);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.appendTo(self.$find);
|
||||||
|
|
||||||
|
self.$nextButton = Ox.Button({
|
||||||
|
style: 'symbol',
|
||||||
|
title: 'arrowRight',
|
||||||
|
tooltip: 'Next [G]',
|
||||||
|
type: 'image'
|
||||||
|
})
|
||||||
|
.css({float: 'left', opacity: 0.25})
|
||||||
|
.bindEvent({
|
||||||
|
click: function() {
|
||||||
|
goToNextResult(1);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.appendTo(self.$find);
|
||||||
|
|
||||||
|
self.$findInput = Ox.Input({
|
||||||
|
placeholder: 'Find',
|
||||||
|
value: self.options.find,
|
||||||
|
width: 86
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
float: 'left',
|
||||||
|
background: 'rgba(0, 0, 0, 0)',
|
||||||
|
MozBoxShadow: '0 0 0',
|
||||||
|
WebkitBoxShadow: '0 0 0'
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
focus: function() {
|
||||||
|
self.inputHasFocus = true;
|
||||||
|
},
|
||||||
|
blur: function() {
|
||||||
|
self.inputHasFocus = false;
|
||||||
|
submitFindInput();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.appendTo(self.$find);
|
||||||
|
|
||||||
|
self.$findInput.children('input').css({
|
||||||
|
width: (self.positionWidth - 6) + 'px',
|
||||||
|
height: '16px',
|
||||||
|
padding: '0 3px 0 3px',
|
||||||
|
border: '0px',
|
||||||
|
borderRadius: '8px',
|
||||||
|
fontSize: '11px',
|
||||||
|
color: 'rgb(255, 255, 255)'
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
background: '-moz-linear-gradient(top, rgba(0, 0, 0, 0.5), rgba(64, 64, 64, 0.5))'
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
background: '-webkit-linear-gradient(top, rgba(0, 0, 0, 0.5), rgba(64, 64, 64, 0.5))'
|
||||||
|
});
|
||||||
|
|
||||||
|
self.$clearButton = Ox.Button({
|
||||||
|
style: 'symbol',
|
||||||
|
title: 'close',
|
||||||
|
tooltip: 'Clear',
|
||||||
|
type: 'image'
|
||||||
|
})
|
||||||
|
.css({float: 'left'})
|
||||||
|
.bindEvent({
|
||||||
|
click: function() {
|
||||||
|
self.$findInput
|
||||||
|
.options({value: ''})
|
||||||
|
.focusInput();
|
||||||
|
self.results = [];
|
||||||
|
self.$timeline && self.$timeline.options({
|
||||||
|
results: self.results
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.appendTo(self.$find);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (self.options.controls.length) {
|
if (self.options.controls.length) {
|
||||||
|
|
||||||
self.$controls = Ox.Bar({
|
self.$controls = Ox.Bar({
|
||||||
|
@ -463,39 +594,9 @@ Ox.VideoPlayer = function(options, self) {
|
||||||
.bindEvent('click', toggleSize)
|
.bindEvent('click', toggleSize)
|
||||||
.appendTo(self.$controls);
|
.appendTo(self.$controls);
|
||||||
|
|
||||||
}else if (control == 'timeline') {
|
} else if (control == 'timeline') {
|
||||||
|
|
||||||
self.$timeline = Ox.Element()
|
/*
|
||||||
.addClass('timeline')
|
|
||||||
.css({
|
|
||||||
float: 'left',
|
|
||||||
height: self.barHeight + 'px',
|
|
||||||
background: 'rgba(0, 0, 0, 0.75)',
|
|
||||||
borderRadius: self.barHeight / 2 + 'px'
|
|
||||||
})
|
|
||||||
.appendTo(self.$controls);
|
|
||||||
|
|
||||||
self.$timelineImages = Ox.Element()
|
|
||||||
.addClass('timelineimages')
|
|
||||||
.css({
|
|
||||||
float: 'left',
|
|
||||||
height: self.barHeight + 'px',
|
|
||||||
marginLeft: self.barHeight / 2 + 'px'
|
|
||||||
})
|
|
||||||
.appendTo(self.$timeline);
|
|
||||||
|
|
||||||
self.$timelineImage = $('<img>')
|
|
||||||
.addClass('timelineimage')
|
|
||||||
.attr({
|
|
||||||
src: self.options.timeline
|
|
||||||
})
|
|
||||||
.css({
|
|
||||||
float: 'left',
|
|
||||||
height: self.barHeight + 'px'
|
|
||||||
})
|
|
||||||
.appendTo(self.$timelineImages.$element);
|
|
||||||
|
|
||||||
///*
|
|
||||||
if (self.options.showProgress) {
|
if (self.options.showProgress) {
|
||||||
self.$progress = $('<img>')
|
self.$progress = $('<img>')
|
||||||
.attr({
|
.attr({
|
||||||
|
@ -507,46 +608,18 @@ Ox.VideoPlayer = function(options, self) {
|
||||||
})
|
})
|
||||||
.appendTo(self.$timelineImages.$element);
|
.appendTo(self.$timelineImages.$element);
|
||||||
}
|
}
|
||||||
//*/
|
*/
|
||||||
|
|
||||||
self.$positionMarker = $('<div>')
|
if (self.options.duration) {
|
||||||
.css({
|
self.$timeline = getTimeline()
|
||||||
float: 'left',
|
} else {
|
||||||
width: '14px',
|
self.$timeline = Ox.Element()
|
||||||
height: '14px',
|
.css({
|
||||||
border: '1px solid rgba(0, 0, 0, 0.5)',
|
float: 'left'
|
||||||
borderRadius: '8px'
|
})
|
||||||
})
|
.html(' ');
|
||||||
.append(
|
}
|
||||||
self.$positionMarkerRing = $('<div>')
|
self.$timeline.appendTo(self.$controls);
|
||||||
.css({
|
|
||||||
width: '10px',
|
|
||||||
height: '10px',
|
|
||||||
border: '2px solid rgba(255, 255, 255, 0.5)',
|
|
||||||
borderRadius: '7px',
|
|
||||||
})
|
|
||||||
.append(
|
|
||||||
$('<div>')
|
|
||||||
.css({
|
|
||||||
width: '8px',
|
|
||||||
height: '8px',
|
|
||||||
border: '1px solid rgba(0, 0, 0, 0.5)',
|
|
||||||
borderRadius: '5px',
|
|
||||||
})
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.appendTo(self.$timeline.$element);
|
|
||||||
|
|
||||||
self.$timelineInterface = Ox.Element()
|
|
||||||
.css({
|
|
||||||
float: 'left',
|
|
||||||
height: self.barHeight + 'px',
|
|
||||||
})
|
|
||||||
.appendTo(self.$controls);
|
|
||||||
|
|
||||||
self.$tooltip = Ox.Tooltip({
|
|
||||||
animate: false
|
|
||||||
});
|
|
||||||
|
|
||||||
} else if (control == 'space') {
|
} else if (control == 'space') {
|
||||||
|
|
||||||
|
@ -659,6 +732,16 @@ Ox.VideoPlayer = function(options, self) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function find(query) {
|
||||||
|
query = query.toLowerCase();
|
||||||
|
return query.length ? Ox.map(self.options.subtitles, function(subtitle) {
|
||||||
|
return subtitle.text.toLowerCase().indexOf(query) > -1 ? {
|
||||||
|
'in': subtitle['in'],
|
||||||
|
out: subtitle.out
|
||||||
|
} : null;
|
||||||
|
}) : [];
|
||||||
|
}
|
||||||
|
|
||||||
function formatPosition(position) {
|
function formatPosition(position) {
|
||||||
position = Ox.isUndefined(position) ? self.options.position : position;
|
position = Ox.isUndefined(position) ? self.options.position : position;
|
||||||
return Ox.formatDuration(position, self.options.showMilliseconds);
|
return Ox.formatDuration(position, self.options.showMilliseconds);
|
||||||
|
@ -712,13 +795,6 @@ Ox.VideoPlayer = function(options, self) {
|
||||||
padding: playIconPadding + 'px',
|
padding: playIconPadding + 'px',
|
||||||
borderRadius: Math.round(self.iconSize / 2) + 'px'
|
borderRadius: Math.round(self.iconSize / 2) + 'px'
|
||||||
};
|
};
|
||||||
} else if (element == 'positionMarker') {
|
|
||||||
var position = self.options.duration ?
|
|
||||||
(self.options.position - self['in']) / self.options.duration : 0;
|
|
||||||
css = {
|
|
||||||
marginLeft: position * self.timelineImageWidth -
|
|
||||||
self.timelineImageWidth - 8 + 'px',
|
|
||||||
};
|
|
||||||
} else if (element == 'poster' || element == 'video') {
|
} else if (element == 'poster' || element == 'video') {
|
||||||
var playerWidth = self.width,
|
var playerWidth = self.width,
|
||||||
playerHeight = self.height,
|
playerHeight = self.height,
|
||||||
|
@ -759,15 +835,6 @@ Ox.VideoPlayer = function(options, self) {
|
||||||
css = {
|
css = {
|
||||||
width: self.timelineWidth + 'px'
|
width: self.timelineWidth + 'px'
|
||||||
};
|
};
|
||||||
} else if (element == 'timelineImage' || element == 'timelineImages') {
|
|
||||||
css = {
|
|
||||||
width: self.timelineImageWidth + 'px'
|
|
||||||
};
|
|
||||||
} else if (element == 'timelineInterface') {
|
|
||||||
css = {
|
|
||||||
width: self.timelineWidth + 'px',
|
|
||||||
marginLeft: -self.timelineWidth + 'px'
|
|
||||||
};
|
|
||||||
} else if (element == 'videoContainer') {
|
} else if (element == 'videoContainer') {
|
||||||
css = {
|
css = {
|
||||||
width: self.width + 'px',
|
width: self.width + 'px',
|
||||||
|
@ -841,6 +908,61 @@ Ox.VideoPlayer = function(options, self) {
|
||||||
return subtitle;
|
return subtitle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getTimeline() {
|
||||||
|
var $timeline = Ox.SmallVideoTimeline({
|
||||||
|
_offset: getTimelineLeft(),
|
||||||
|
duration: self.options.duration,
|
||||||
|
getTimelineURL: Ox.isString(self.options.timeline) ?
|
||||||
|
function() { return self.options.timeline; } :
|
||||||
|
self.options.timeline,
|
||||||
|
'in': self.options['in'],
|
||||||
|
out: self.options.out,
|
||||||
|
paused: self.options.paused,
|
||||||
|
results: self.results,
|
||||||
|
showMilliseconds: self.options.showMilliseconds,
|
||||||
|
subtitles: self.options.subtitles,
|
||||||
|
type: 'player',
|
||||||
|
width: getTimelineWidth()
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
float: 'left'
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
position: function(data) {
|
||||||
|
setPosition(data.position, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
//Ox.print('??', $timeline.find('.OxInterface'))
|
||||||
|
$timeline.children().css({
|
||||||
|
marginLeft: getTimelineLeft() + 'px'
|
||||||
|
});
|
||||||
|
$timeline.find('.OxInterface').css({
|
||||||
|
marginLeft: getTimelineLeft() + 'px'
|
||||||
|
});
|
||||||
|
return $timeline;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTimelineLeft() {
|
||||||
|
var left = 0;
|
||||||
|
Ox.forEach(self.options.controls, function(control) {
|
||||||
|
if (control == 'timeline') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
left += control == 'position' ? self.positionWidth : 16
|
||||||
|
});
|
||||||
|
return left;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTimelineWidth() {
|
||||||
|
return (self.options.fullscreen ? window.innerWidth : self.options.width) -
|
||||||
|
self.options.controls.reduce(function(prev, curr) {
|
||||||
|
return prev + (
|
||||||
|
curr == 'timeline' || curr == 'space' ? 0 :
|
||||||
|
curr == 'position' ? self.positionWidth : 16
|
||||||
|
);
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
|
||||||
function hideInterface() {
|
function hideInterface() {
|
||||||
Ox.print('hideInterface');
|
Ox.print('hideInterface');
|
||||||
self.interfaceTimeout = setTimeout(function() {
|
self.interfaceTimeout = setTimeout(function() {
|
||||||
|
@ -874,6 +996,8 @@ Ox.VideoPlayer = function(options, self) {
|
||||||
|
|
||||||
function loadedmetadata() {
|
function loadedmetadata() {
|
||||||
|
|
||||||
|
var hadDuration = !!self.options.duration;
|
||||||
|
|
||||||
self.loaded = true;
|
self.loaded = true;
|
||||||
self.out = self.options.playInToOut &&
|
self.out = self.options.playInToOut &&
|
||||||
self.options.out < self.video.duration ?
|
self.options.out < self.video.duration ?
|
||||||
|
@ -893,46 +1017,19 @@ Ox.VideoPlayer = function(options, self) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (self.$timeline) {
|
||||||
|
if (!hadDuration) {
|
||||||
|
self.$timeline.replaceWith(self.$timeline = getTimeline());
|
||||||
|
}
|
||||||
|
self.$timeline.options({
|
||||||
|
duration: self.options.duration
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (self.options.enableKeyboard && self.options.focus == 'load') {
|
if (self.options.enableKeyboard && self.options.focus == 'load') {
|
||||||
that.gainFocus();
|
that.gainFocus();
|
||||||
}
|
}
|
||||||
self.$timeline && self.$timelineInterface
|
|
||||||
.bind({
|
|
||||||
mousedown: mousedownTrack,
|
|
||||||
mouseleave: mouseleaveTrack,
|
|
||||||
mousemove: mousemoveTrack,
|
|
||||||
})
|
|
||||||
.bindEvent({
|
|
||||||
drag: dragTrack,
|
|
||||||
dragpause: dragpauseTrack,
|
|
||||||
dragend: dragpauseTrack
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function dragTrack(e) {
|
|
||||||
setPosition(getPosition(e), true);
|
|
||||||
if (self.dragTimeout) {
|
|
||||||
clearTimeout(self.dragTimeout);
|
|
||||||
self.dragTimeout = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function dragpauseTrack(e) {
|
|
||||||
self.video.currentTime = self.options.position;
|
|
||||||
}
|
|
||||||
|
|
||||||
function mousedownTrack(e) {
|
|
||||||
setPosition(getPosition(e), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
function mouseleaveTrack(e) {
|
|
||||||
self.$tooltip.hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
function mousemoveTrack(e) {
|
|
||||||
self.$tooltip.options({
|
|
||||||
title: formatPosition(getPosition(e))
|
|
||||||
}).show(e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function parsePositionInput(str) {
|
function parsePositionInput(str) {
|
||||||
|
@ -1019,7 +1116,9 @@ Ox.VideoPlayer = function(options, self) {
|
||||||
self.posterIsVisible = false;
|
self.posterIsVisible = false;
|
||||||
}
|
}
|
||||||
self.$subtitle && setSubtitle();
|
self.$subtitle && setSubtitle();
|
||||||
self.$timeline && self.$positionMarker.css(getCSS('positionMarker'));
|
self.$timeline && self.$timeline.options({
|
||||||
|
position: self.options.position
|
||||||
|
});
|
||||||
self.$position && self.$position.html(formatPosition());
|
self.$position && self.$position.html(formatPosition());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1031,12 +1130,13 @@ Ox.VideoPlayer = function(options, self) {
|
||||||
self.iconLeft = parseInt((self.width - self.iconSize) / 2),
|
self.iconLeft = parseInt((self.width - self.iconSize) / 2),
|
||||||
self.iconTop = parseInt((self.height - self.iconSize) / 2);
|
self.iconTop = parseInt((self.height - self.iconSize) / 2);
|
||||||
if (self.$timeline || self.$space) {
|
if (self.$timeline || self.$space) {
|
||||||
self.timelineWidth = self.width - self.options.controls.reduce(function(prev, curr) {
|
self.timelineWidth = self.width -
|
||||||
return prev + (
|
self.options.controls.reduce(function(prev, curr) {
|
||||||
curr == 'timeline' || curr == 'space' ? 0 :
|
return prev + (
|
||||||
curr == 'position' ? self.positionWidth : 16
|
curr == 'timeline' || curr == 'space' ? 0 :
|
||||||
);
|
curr == 'position' ? self.positionWidth : 16
|
||||||
}, 0);
|
);
|
||||||
|
}, 0);
|
||||||
if (self.$timeline) {
|
if (self.$timeline) {
|
||||||
self.timelineImageWidth = self.timelineWidth - self.barHeight;
|
self.timelineImageWidth = self.timelineWidth - self.barHeight;
|
||||||
}
|
}
|
||||||
|
@ -1052,12 +1152,11 @@ Ox.VideoPlayer = function(options, self) {
|
||||||
self.$title && self.$title.animate(getCSS('title'), ms);
|
self.$title && self.$title.animate(getCSS('title'), ms);
|
||||||
self.$controls && self.$controls.animate(getCSS('controls'), ms);
|
self.$controls && self.$controls.animate(getCSS('controls'), ms);
|
||||||
if (self.$timeline) {
|
if (self.$timeline) {
|
||||||
self.$timeline.animate(getCSS('timeline'), ms);
|
self.$timeline.animate(getCSS('timeline'), ms, function() {
|
||||||
self.$timelineImages.animate(getCSS('timelineImages'), ms);
|
self.$timeline.options({
|
||||||
self.$timelineImage.animate(getCSS('timelineImage'), ms);
|
width: self.timelineWidth
|
||||||
self.$progress && self.$progress.animate(getCSS('progress'), ms);
|
})
|
||||||
self.$positionMarker.animate(getCSS('positionMarker'), ms);
|
});
|
||||||
self.$timelineInterface.animate(getCSS('timelineInterface'), ms);
|
|
||||||
}
|
}
|
||||||
self.$space && self.$space.animate(getCSS('space'), ms);
|
self.$space && self.$space.animate(getCSS('space'), ms);
|
||||||
}
|
}
|
||||||
|
@ -1115,6 +1214,37 @@ Ox.VideoPlayer = function(options, self) {
|
||||||
}).show();
|
}).show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function submitFindInput() {
|
||||||
|
self.options.find = self.$findInput.options('value');
|
||||||
|
self.results = find(self.options.find);
|
||||||
|
self.$timeline && self.$timeline.options({
|
||||||
|
results: self.results
|
||||||
|
});
|
||||||
|
if (self.results.length) {
|
||||||
|
setPosition(self.results[0]['in'] + self.secondsPerFrame, true);
|
||||||
|
self.currentResult = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function goToNextResult(direction) {
|
||||||
|
var found = false,
|
||||||
|
position = 0;
|
||||||
|
direction == -1 && self.results.reverse();
|
||||||
|
Ox.forEach(self.results, function(v) {
|
||||||
|
if (direction == 1 ? v['in'] > self.options.position : v['out'] < self.options.position) {
|
||||||
|
position = v['in'];
|
||||||
|
found = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
direction == -1 && self.results.reverse();
|
||||||
|
if (!found) {
|
||||||
|
position = self.results[direction == 1 ? 0 : self.results.length - 1]['in'];
|
||||||
|
}
|
||||||
|
Ox.print('>>', self.results, position)
|
||||||
|
setPosition(position + self.secondsPerFrame, true);
|
||||||
|
}
|
||||||
|
|
||||||
function submitPositionInput() {
|
function submitPositionInput() {
|
||||||
self.$positionInput.hide();
|
self.$positionInput.hide();
|
||||||
self.$position.html('').show();
|
self.$position.html('').show();
|
||||||
|
@ -1211,8 +1341,8 @@ Ox.VideoPlayer = function(options, self) {
|
||||||
|
|
||||||
function togglePaused(toggleButton) {
|
function togglePaused(toggleButton) {
|
||||||
self.options.paused = !self.options.paused;
|
self.options.paused = !self.options.paused;
|
||||||
self.$timeline && self.$positionMarkerRing.css({
|
self.$timeline && self.$timeline.options({
|
||||||
borderColor: 'rgba(255, 255, 255, ' + (self.options.paused ? 0.5 : 1) + ')'
|
paused: self.options.paused
|
||||||
});
|
});
|
||||||
if (self.options.paused) {
|
if (self.options.paused) {
|
||||||
self.video.pause();
|
self.video.pause();
|
||||||
|
|
|
@ -3864,11 +3864,12 @@ Ox.highlight <f> Highlight matches in a string
|
||||||
> Ox.highlight('foobar', 'foo', 'match')
|
> Ox.highlight('foobar', 'foo', 'match')
|
||||||
'<span class="match">foo</span>bar'
|
'<span class="match">foo</span>bar'
|
||||||
@*/
|
@*/
|
||||||
|
// fixme: with regexp, special chars would have to be escaped
|
||||||
Ox.highlight = function(txt, str, classname) {
|
Ox.highlight = function(txt, str, classname) {
|
||||||
return txt.replace(
|
return str.length ? txt.replace(
|
||||||
new RegExp('(' + str + ')', 'ig'),
|
new RegExp('(' + str + ')', 'ig'),
|
||||||
'<span class="' + classname + '">$1</span>'
|
'<span class="' + classname + '">$1</span>'
|
||||||
);
|
) : txt;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*@
|
/*@
|
||||||
|
|
Loading…
Reference in a new issue