some improvements to Ox.VideoPlayer

This commit is contained in:
rolux 2011-05-12 22:02:22 +02:00
parent 57618c850f
commit a19c271e8f
6 changed files with 213 additions and 49 deletions

View file

@ -9,9 +9,23 @@ Ox.load('UI', {
padding: '16px' padding: '16px'
}); });
Ox.VideoPlayer({ Ox.VideoPlayer({
height: 288, height: 96 * 256/180,
timeline: timeline,
title: 'Brick',
url: url,
width: 256
}).appendTo(Ox.UI.$body);
/*
var id = '0133093';
var url = 'http://next.0xdb.org/' + id + '/96p.webm?' + Ox.random(1000000);
var timeline = 'http://next.0xdb.org/' + id + '/timeline.16.png';
Ox.VideoPlayer({
height: 96 * 256/230,
timeline: timeline, timeline: timeline,
url: url, url: url,
width: 540 width: 256
}).css({
left: '300px'
}).appendTo(Ox.UI.$body); }).appendTo(Ox.UI.$body);
*/
}); });

View file

@ -1647,6 +1647,7 @@ Video
margin-left: 4px; margin-left: 4px;
} }
.OxVideoPlayer > .OxBar .OxInputGroup { .OxVideoPlayer > .OxBar .OxInputGroup {
//width: 98px; //width: 98px;
} }

View file

@ -13,6 +13,10 @@ Ox.Focus = function() {
_print: function() { _print: function() {
Ox.print(stack); Ox.print(stack);
}, },
_reset: function() {
$('.OxFocus').removeClass('OxFocus');
stack = [];
},
blur: function(id) { blur: function(id) {
var index = stack.indexOf(id); var index = stack.indexOf(id);
if (index > -1 && index == stack.length - 1) { if (index > -1 && index == stack.length - 1) {

View file

@ -729,12 +729,18 @@ Ox.Input = function(options, self) {
} }
}; };
that.focusInput = function() { that.focusInput = function(select) {
select = Ox.isUndefined(select) ? true : select;
self.$input.focus(); self.$input.focus();
if (select) {
cursor(0, self.$input.val().length); cursor(0, self.$input.val().length);
} else {
cursor(self.$input.val().length);
}
return that; return that;
}; };
// fixme: deprecate, options are enough
that.value = function() { that.value = function() {
return self.$input.hasClass('OxPlaceholder') ? '' : self.$input.val(); return self.$input.hasClass('OxPlaceholder') ? '' : self.$input.val();
}; };

View file

@ -11,6 +11,7 @@ Ox.VideoPlayer = function(options, self) {
}) })
.options(options || {}) .options(options || {})
.css({ .css({
position: 'absolute',
width: self.options.width + 'px', width: self.options.width + 'px',
height: self.options.height + 'px' height: self.options.height + 'px'
//background: 'red' //background: 'red'
@ -27,9 +28,7 @@ Ox.VideoPlayer = function(options, self) {
self.barHeight = 16; self.barHeight = 16;
self.outerBarWidth = self.options.width - 96; self.outerBarWidth = self.options.width - 96;
self.innerBarWidth = self.outerBarWidth - self.barHeight; self.innerBarWidth = self.outerBarWidth - self.barHeight;
self.markerSize = 12; self.markerOffset = -self.innerBarWidth - 8;
self.markerBorderSize = 2;
self.markerOffset = -self.innerBarWidth - self.markerSize / 2;
self.$video = Ox.VideoElement({ self.$video = Ox.VideoElement({
height: self.options.height, height: self.options.height,
@ -44,10 +43,12 @@ Ox.VideoPlayer = function(options, self) {
loadedmetadata: loadedmetadata, loadedmetadata: loadedmetadata,
paused: function(data) { paused: function(data) {
// called when playback ends // called when playback ends
/*
self.$playButton.toggleTitle(); self.$playButton.toggleTitle();
self.$positionMarker.css({ self.$positionMarkerRing.css({
borderColor: 'rgb(192, 192, 192)' borderColor: 'rgba(255, 255, 255, 0.5)'
}); });
*/
}, },
playing: function(data) { playing: function(data) {
setPosition(data.position); setPosition(data.position);
@ -60,7 +61,7 @@ Ox.VideoPlayer = function(options, self) {
if (self.buffered[i][0] > self.buffered[i][1]) { if (self.buffered[i][0] > self.buffered[i][1]) {
self.buffered[i][0] = 0; self.buffered[i][0] = 0;
} }
Ox.print(i, self.buffered[i][0], self.buffered[i][1]) //Ox.print(i, self.buffered[i][0], self.buffered[i][1])
} }
self.$buffered.attr({ self.$buffered.attr({
src: getBufferedImageURL() src: getBufferedImageURL()
@ -72,14 +73,33 @@ Ox.VideoPlayer = function(options, self) {
}) })
.appendTo(that); .appendTo(that);
if (self.options.title) {
self.$titlebar = $('<div>')
.css({
position: 'absolute',
width: self.options.width + 'px',
height: '15px',
paddingTop: '1px',
textAlign: 'center'
})
.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))'
})
.html(self.options.title)
.appendTo(that.$element);
}
self.$loadingIcon = $('<img>') self.$loadingIcon = $('<img>')
.attr({ .attr({
src: Ox.UI.getImagePath('symbolLoadingAnimated.svg') src: Ox.UI.getImagePath('symbolLoadingAnimated.svg').replace('/classic/', '/modern/')
}) })
.css({ .css({
position: 'absolute', position: 'absolute',
left: self.options.width / 2 - 16 + 'px', left: parseInt(self.options.width / 2) - 16 + 'px', // fixme
top: self.options.height / 2 - 16 + 'px', top: parseInt(self.options.height / 2) - 16 + 'px',
width: '32px', width: '32px',
height: '32px' height: '32px'
}) })
@ -93,6 +113,12 @@ Ox.VideoPlayer = function(options, self) {
width: self.options.width + 'px', width: self.options.width + 'px',
marginTop: self.options.height - self.barHeight + 'px', marginTop: self.options.height - self.barHeight + 'px',
}) })
.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); .appendTo(that);
self.$buttons = Ox.Element() self.$buttons = Ox.Element()
@ -150,9 +176,17 @@ Ox.VideoPlayer = function(options, self) {
float: 'left', float: 'left',
width: self.outerBarWidth + 'px', width: self.outerBarWidth + 'px',
height: self.barHeight + 'px', height: self.barHeight + 'px',
background: 'rgb(0, 0, 0)', background: 'rgba(0, 0, 0, 0.75)',
borderRadius: self.barHeight / 2 + 'px' borderRadius: self.barHeight / 2 + 'px'
}) })
/*
.css({
backgroundImage: '-moz-linear-gradient(top, rgba(0, 0, 0, 0.75), rgba(64, 64, 64, 0.75))'
})
.css({
backgroundImage: '-webkit-linear-gradient(top, rgba(0, 0, 0, 0.75), rgba(64, 64, 64, 0.75))'
})
*/
.appendTo(self.$controls); .appendTo(self.$controls);
self.$innerBar = Ox.Element() self.$innerBar = Ox.Element()
@ -187,21 +221,36 @@ Ox.VideoPlayer = function(options, self) {
}) })
.appendTo(self.$innerBar.$element); .appendTo(self.$innerBar.$element);
self.$positionMarker = Ox.Element() self.$positionMarker = $('<div>')
.css({ .css({
float: 'left', float: 'left',
width: self.markerSize - self.markerBorderSize * 2 + 'px', width: '14px',
height: self.markerSize - self.markerBorderSize * 2 + 'px', height: '14px',
marginTop: (self.barHeight - self.markerSize) / 2 + 'px',
marginLeft: self.markerOffset + 'px', marginLeft: self.markerOffset + 'px',
border: self.markerBorderSize + 'px solid rgb(192, 192, 192)', border: '1px solid rgba(0, 0, 0, 0.5)',
borderRadius: self.markerSize - self.markerBorderSize * 2 + 'px', borderRadius: '8px'
//background: 'rgba(0, 0, 0, 0.5)',
boxShadow: '0 0 ' + (self.barHeight - self.markerSize) / 2 + 'px black'
}) })
.appendTo(self.$outerBar); .append(
self.$positionMarkerRing = $('<div>')
.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.$outerBar.$element);
self.$interfaceBar = Ox.Element() self.$trackInterface = Ox.Element()
.css({ .css({
float: 'left', float: 'left',
width: self.outerBarWidth + 'px', width: self.outerBarWidth + 'px',
@ -214,7 +263,7 @@ Ox.VideoPlayer = function(options, self) {
animate: false animate: false
}); });
self.$position = Ox.Element() self.$position = $('<div>')
.css({ .css({
float: 'left', float: 'left',
width: '44px', width: '44px',
@ -224,7 +273,81 @@ Ox.VideoPlayer = function(options, self) {
textAlign: 'center' textAlign: 'center'
}) })
.html(Ox.formatDuration(self.options.position)) .html(Ox.formatDuration(self.options.position))
.appendTo(self.$controls) .bind({
click: function() {
if (!self.$video.paused()) {
self.wasPlaying = true;
self.$video.pause();
self.$playButton.toggleTitle();
}
self.$position.hide();
self.$positionInput
.options({
value: Ox.formatDuration(self.options.position)
})
.show()
.focusInput(false);
}
})
.appendTo(self.$controls.$element)
self.$positionInput = Ox.Input({
value: Ox.formatDuration(self.options.position),
width: 48
})
.css({
float: 'left',
background: 'rgba(0, 0, 0, 0)',
MozBoxShadow: '0 0 0',
WebkitBoxShadow: '0 0 0'
})
.bindEvent({
blur: submitPositionInput,
change: submitPositionInput,
//submit: submitPositionInput
})
.hide()
.appendTo(self.$controls.$element);
self.$positionInput.children('input').css({
width: '42px',
height: '16px',
padding: '0 3px 0 3px',
border: '0px',
borderRadius: '8px',
fontSize: '9px',
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))'
});
function submitPositionInput() {
self.$positionInput.hide();
self.$position.html('').show();
setPosition(parsePositionInput(self.$positionInput.options('value')));
self.$video.position(self.options.position);
if (self.wasPlaying) {
self.$video.play();
self.$playButton.toggleTitle();
self.wasPlaying = false;
}
}
function parsePositionInput(str) {
var position,
split = str.split(':').reverse();
while (split.length > 3) {
split.pop();
}
position = split.reduce(function(prev, curr, i) {
return prev + (parseFloat(curr) || 0) * Math.pow(60, i);
}, 0)
return Ox.limit(position, 0, self.duration);
}
function getPosition(e) { function getPosition(e) {
// fixme: no offsetX in firefox??? // fixme: no offsetX in firefox???
@ -235,7 +358,10 @@ Ox.VideoPlayer = function(options, self) {
0, self.duration 0, self.duration
); );
} else { } else {
Ox.print(e.offsetX) /*Ox.print(e.offsetX, Ox.limit(
(e.offsetX - self.barHeight / 2) / self.innerBarWidth * self.duration,
0, self.duration
))*/
return Ox.limit( return Ox.limit(
(e.offsetX - self.barHeight / 2) / self.innerBarWidth * self.duration, (e.offsetX - self.barHeight / 2) / self.innerBarWidth * self.duration,
0, self.duration 0, self.duration
@ -274,12 +400,19 @@ Ox.VideoPlayer = function(options, self) {
} }
function hideControls() { function hideControls() {
Ox.print('!!!!!!', self.$positionInput.hasFocus())
if (!self.$positionInput.hasFocus()) {
self.controlsTimeout = setTimeout(function() { self.controlsTimeout = setTimeout(function() {
// fixme: use class
self.$titlebar.animate({
opacity: 0
}, 250);
self.$controls.animate({ self.$controls.animate({
opacity: 0 opacity: 0
}, 250); }, 250);
}, 1000); }, 1000);
} }
}
function hideLoadingIcon() { function hideLoadingIcon() {
self.$loadingIcon.animate({ self.$loadingIcon.animate({
@ -289,9 +422,9 @@ Ox.VideoPlayer = function(options, self) {
function loadedmetadata(data) { function loadedmetadata(data) {
//self.$position.html(Ox.formatDuration(data.video.duration)) //self.$position.html(Ox.formatDuration(data.video.duration))
Ox.print('!!!!', data.video.width, data.video.height, data.video.videoWidth, data.video.videoHeight) //Ox.print('!!!!', data.video.width, data.video.height, data.video.videoWidth, data.video.videoHeight)
self.duration = data.video.duration; self.duration = data.video.duration;
Ox.print('DURATION', Ox.formatDuration(self.duration)); //Ox.print('DURATION', Ox.formatDuration(self.duration));
hideLoadingIcon(); hideLoadingIcon();
that.gainFocus().bindEvent({ that.gainFocus().bindEvent({
key_space: function() { key_space: function() {
@ -299,38 +432,41 @@ Ox.VideoPlayer = function(options, self) {
togglePlay(); togglePlay();
} }
}); });
self.$interfaceBar self.$trackInterface
.bind({ .bind({
mousedown: mousedownBar, mousedown: mousedownTrack,
mouseleave: mouseleaveBar, mouseleave: mouseleaveTrack,
mousemove: mousemoveBar, mousemove: mousemoveTrack,
}) })
.bindEvent({ .bindEvent({
drag: dragBar, drag: dragTrack,
dragpause: dragpauseTrack,
dragend: dragpauseTrack
}); });
} }
function dragBar(e) { function dragTrack(e) {
setPosition(getPosition(e)); setPosition(getPosition(e));
if (self.dragTimeout) { if (self.dragTimeout) {
clearTimeout(self.dragTimeout); clearTimeout(self.dragTimeout);
self.dragTimeout = 0; self.dragTimeout = 0;
} }
self.dragTimeout = setTimeout(function() {
self.$video.position(self.options.position);
}, 1000);
} }
function mousedownBar(e) { function dragpauseTrack(e) {
self.$video.position(self.options.position);
}
function mousedownTrack(e) {
setPosition(getPosition(e)); setPosition(getPosition(e));
self.$video.position(self.options.position); self.$video.position(self.options.position);
} }
function mouseleaveBar(e) { function mouseleaveTrack(e) {
self.$tooltip.hide(); self.$tooltip.hide();
} }
function mousemoveBar(e) { function mousemoveTrack(e) {
self.$tooltip.options({ self.$tooltip.options({
title: Ox.formatDuration(getPosition(e)) title: Ox.formatDuration(getPosition(e))
}).show(e.clientX, e.clientY); }).show(e.clientX, e.clientY);
@ -338,6 +474,9 @@ Ox.VideoPlayer = function(options, self) {
function showControls() { function showControls() {
clearTimeout(self.controlsTimeout); clearTimeout(self.controlsTimeout);
self.$titlebar.animate({
opacity: 1
}, 250);
self.$controls.animate({ self.$controls.animate({
opacity: 1 opacity: 1
}, 250); }, 250);
@ -363,8 +502,8 @@ Ox.VideoPlayer = function(options, self) {
function togglePlay() { function togglePlay() {
self.$video.togglePlay(); self.$video.togglePlay();
self.$positionMarker.css({ self.$positionMarkerRing.css({
borderColor: self.$video.paused() ? 'rgb(192, 192, 192)' : 'rgb(255, 255, 255)' borderColor: 'rgba(255, 255, 255, ' + (self.$video.paused() ? 0.5 : 1) + ')'
}); });
} }

View file

@ -40,7 +40,7 @@
height: 256px; height: 256px;
} }
</style> </style>
<script src="../../../../build/js/jquery/jquery.js"></script> <script src="../../../../build/jquery/jquery.js"></script>
<script src="../../../Ox.js"></script> <script src="../../../Ox.js"></script>
<script> <script>
$(function() { $(function() {