diff --git a/demos/video/js/video.js b/demos/video/js/video.js index 0af32b8d..0de7ac3e 100644 --- a/demos/video/js/video.js +++ b/demos/video/js/video.js @@ -3,7 +3,7 @@ Ox.load('UI', { theme: 'modern' }, function() { var id = '0393109', - poster = 'http://next.0xdb.org/' + id + '/poster.jpg', + poster = 'png/poster.png', timeline = 'http://next.0xdb.org/' + id + '/timeline.16.png', url = 'http://next.0xdb.org/' + id + '/96p.webm', videoSize = getVideoSize(), @@ -32,7 +32,7 @@ Ox.load('UI', { }), Ox.VideoPlayer({ enableKeyboard: true, - height: 192, + height: videoSize.height, 'in': 3128.725, //keepIconVisible: true, out: 3130.725, @@ -42,7 +42,7 @@ Ox.load('UI', { showIcon: true, timeline: timeline, video: url + '?' + + Ox.random(1000000), - width: 360 + width: videoSize.width }) .css({ left: '16px', @@ -51,7 +51,7 @@ Ox.load('UI', { Ox.VideoPlayer({ controls: ['play', 'playInToOut', 'mute', 'size', 'space', 'position'], externalControls: true, - height: videoSize.height, + height: 192, 'in': 3128.725, out: 3130.725, paused: true, @@ -59,7 +59,7 @@ Ox.load('UI', { subtitles: 'srt/' + id + '.srt', timeline: timeline, video: url + '?' + + Ox.random(1000000), - width: videoSize.width + width: 360 }) .css({ left: '16px', diff --git a/demos/video/png/poster.png b/demos/video/png/poster.png new file mode 100644 index 00000000..9abcc663 Binary files /dev/null and b/demos/video/png/poster.png differ diff --git a/source/Ox.UI/js/Video/Ox.VideoPlayer.js b/source/Ox.UI/js/Video/Ox.VideoPlayer.js index ef39b2df..5e7c7fa2 100644 --- a/source/Ox.UI/js/Video/Ox.VideoPlayer.js +++ b/source/Ox.UI/js/Video/Ox.VideoPlayer.js @@ -130,20 +130,23 @@ Ox.VideoPlayer = function(options, self) { if (self.options.enableKeyboard) { that.bindEvent({ + key_1: function() { + toggleScale(); + }, key_left: function() { - setPosition(self.options.position - self.secondsPerFrame); - self.video.currentTime = self.options.position; + setPosition(self.options.position - self.secondsPerFrame, true); + }, + key_p: function() { + playInToOut(); }, key_right: function() { - setPosition(self.options.position + self.secondsPerFrame); - self.video.currentTime = self.options.position; + setPosition(self.options.position + self.secondsPerFrame, true); }, key_shift_f: function() { toggleFullscreen(); }, key_space: function() { - self.$playButton && self.$playButton.toggleTitle(); - togglePaused(); + togglePaused(true); } }) } @@ -192,8 +195,7 @@ Ox.VideoPlayer = function(options, self) { }) .bind({ click: function() { - togglePaused(); - self.$playButton && self.$playButton.toggleTitle(); + togglePaused(true); } }) .appendTo(that.$element) @@ -357,7 +359,9 @@ Ox.VideoPlayer = function(options, self) { type: 'image' }) .css({float: 'left'}) - .bindEvent('click', togglePaused) + .bindEvent('click', function() { + togglePaused(); + }) .appendTo(self.$controls); } else if (control == 'playInToOut') { @@ -549,8 +553,7 @@ Ox.VideoPlayer = function(options, self) { click: function() { if (!self.options.paused) { self.wasPlaying = true; - togglePaused(); - self.$playButton && self.$playButton.toggleTitle(); + togglePaused(true); } self.$position.hide(); self.$positionInput @@ -617,8 +620,7 @@ Ox.VideoPlayer = function(options, self) { function ended() { if (!self.options.paused) { - togglePaused(); - self.$playButton && self.$playButton.toggleTitle(); + togglePaused(true); } if (self.options.poster) { self.$poster.animate({ @@ -639,6 +641,119 @@ Ox.VideoPlayer = function(options, self) { return Ox.formatDuration(position, self.options.showMilliseconds); } + function getCSS(element) { + var css; + if (element == 'controls' || element == 'titlebar') { + css = { + width: self.width + 'px' + }; + } else if (element == 'loadingIcon') { + css = { + left: self.iconLeft + 'px', + top: self.iconTop + 'px', + width: self.iconSize + 'px', + height: self.iconSize + 'px' + }; + } else if (element == 'logo') { + var logoHeight = Math.round(self.height / 10); + self.logoMargin = Math.round(self.height / 20); + css = { + left: self.logoMargin + 'px', + top: self.logoMargin + 'px', + height: logoHeight + 'px', + }; + } else if (element == 'player') { + css = Ox.extend({ + width: self.width + 'px', + height: (self.options.fullscreen + ? window.innerHeight + : self.height + ( + self.options.externalControls + ? (!!self.options.controls.length + !!self.options.title) * self.barHeight + : 0)) + 'px' + }, self.options.fullscreen ? { + left: 0, + top: 0 + } : {}, self.exitFullscreen ? { + left: self.absoluteOffset.left, + top: self.absoluteOffset.top + } : {}); + } else if (element == 'playIcon') { + var playIconPadding = Math.round(self.iconSize * 1/8), + playIconSize = self.iconSize - 2 * playIconPadding - 4; + css = { + left: self.iconLeft + 'px', + top: self.iconTop + 'px', + width: playIconSize + 'px', + height: playIconSize + 'px', + padding: playIconPadding + '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') { + var playerWidth = self.width, + playerHeight = self.height, + playerRatio = playerWidth / playerHeight, + videoWidth = self.video.videoWidth, + videoHeight = self.video.videoHeight, + videoRatio = videoWidth / videoHeight, + videoIsWider = videoRatio > playerRatio, + width, height; + if (self.options.scaleToFill) { + width = videoIsWider ? playerHeight * videoRatio : playerWidth; + height = videoIsWider ? playerHeight : playerWidth / videoRatio; + } else { + width = videoIsWider ? playerWidth : playerHeight * videoRatio; + height = videoIsWider ? playerWidth / videoRatio : playerHeight; + } + width = Math.round(width); + height = Math.round(height); + css = { + width: width + 'px', + height: height + 'px', + marginLeft: parseInt((playerWidth - width) / 2), + marginTop: parseInt((playerHeight - height) / 2) + }; + } else if (element == 'progress') { + css = { + width: self.timelineImageWidth + 'px', + marginLeft: -self.timelineImageWidth + 'px' + }; + } else if (element == 'subtitle') { + css = { + bottom: parseInt(self.height / 16) + 'px', + width: self.width + 'px', + fontSize: parseInt(self.height / 20) + 'px', + WebkitTextStroke: (self.height / 1000) + 'px rgb(0, 0, 0)' + }; + } else if (element == 'space' || element == 'timeline') { + css = { + 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') { + css = { + width: self.width + 'px', + height: self.height + 'px' + }; + } + return css; + } + function getPosition(e) { // fixme: no offsetX in firefox??? if ($.browser.mozilla) { @@ -769,8 +884,7 @@ Ox.VideoPlayer = function(options, self) { } function dragTrack(e) { - setPosition(getPosition(e)); - self.video.currentTime = self.options.position; + setPosition(getPosition(e), true); if (self.dragTimeout) { clearTimeout(self.dragTimeout); self.dragTimeout = 0; @@ -782,8 +896,7 @@ Ox.VideoPlayer = function(options, self) { } function mousedownTrack(e) { - setPosition(getPosition(e)); - self.video.currentTime = self.options.position; + setPosition(getPosition(e), true); } function mouseleaveTrack(e) { @@ -812,26 +925,20 @@ Ox.VideoPlayer = function(options, self) { (self.options.playInToOut || self.playInToOut) && self.options.position >= self.options.out ) { - ///* - togglePaused(); - setPosition(self.options.out); - //self.video.currentTime = self.options.position; - self.$playButton && self.$playButton.toggleTitle(); - //*/ + togglePaused(true); + setPosition(self.options.out/*, true*/); //ended(); self.playInToOut = false; } else { - setPosition(); + setPosition(self.options.position); } } function playInToOut() { self.playInToOut = true; - setPosition(self.options['in']); - self.video.currentTime = self.options['in']; + setPosition(self.options['in'], true); if (self.options.paused) { - togglePaused(); - self.$playButton && self.$playButton.toggleTitle(); + togglePaused(true); } } @@ -862,13 +969,14 @@ Ox.VideoPlayer = function(options, self) { }, 250); } - function setPosition(position) { - if (!Ox.isUndefined(position)) { - self.options.position = Ox.limit(position, self['in'], self['out']); - } + function setPosition(position, setVideo) { + position = Ox.limit(position, self['in'], self['out']); self.options.position = Math.round( - self.options.position * self.options.fps + position * self.options.fps ) / self.options.fps; + if (setVideo && self.loaded) { + self.video.currentTime = self.options.position; + } if (self.iconIsVisible) { self.$playIcon.animate({ opacity: 0 @@ -886,119 +994,6 @@ Ox.VideoPlayer = function(options, self) { self.$position && self.$position.html(formatPosition()); } - function getCSS(element) { - var css; - if (element == 'controls' || element == 'titlebar') { - css = { - width: self.width + 'px' - }; - } else if (element == 'loadingIcon') { - css = { - left: self.iconLeft + 'px', - top: self.iconTop + 'px', - width: self.iconSize + 'px', - height: self.iconSize + 'px' - }; - } else if (element == 'logo') { - var logoHeight = Math.round(self.height / 10); - self.logoMargin = Math.round(self.height / 20); - css = { - left: self.logoMargin + 'px', - top: self.logoMargin + 'px', - height: logoHeight + 'px', - }; - } else if (element == 'player') { - css = Ox.extend({ - width: self.width + 'px', - height: (self.options.fullscreen - ? window.innerHeight - : self.height + ( - self.options.externalControls - ? (!!self.options.controls.length + !!self.options.title) * self.barHeight - : 0)) + 'px' - }, self.options.fullscreen ? { - left: 0, - top: 0 - } : {}, self.exitFullscreen ? { - left: self.absoluteOffset.left, - top: self.absoluteOffset.top - } : {}); - } else if (element == 'playIcon') { - var playIconPadding = Math.round(self.iconSize * 1/8), - playIconSize = self.iconSize - 2 * playIconPadding - 4; - css = { - left: self.iconLeft + 'px', - top: self.iconTop + 'px', - width: playIconSize + 'px', - height: playIconSize + 'px', - padding: playIconPadding + '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') { - var playerWidth = self.width, - playerHeight = self.height, - playerRatio = playerWidth / playerHeight, - videoWidth = self.video.videoWidth, - videoHeight = self.video.videoHeight, - videoRatio = videoWidth / videoHeight, - videoIsWider = videoRatio > playerRatio, - width, height; - if (self.options.scaleToFill) { - width = videoIsWider ? playerHeight * videoRatio : playerWidth; - height = videoIsWider ? playerHeight : playerWidth / videoRatio; - } else { - width = videoIsWider ? playerWidth : playerHeight * videoRatio; - height = videoIsWider ? playerWidth / videoRatio : playerHeight; - } - width = Math.round(width); - height = Math.round(height); - css = { - width: width + 'px', - height: height + 'px', - marginLeft: parseInt((playerWidth - width) / 2), - marginTop: parseInt((playerHeight - height) / 2) - }; - } else if (element == 'progress') { - css = { - width: self.timelineImageWidth + 'px', - marginLeft: -self.timelineImageWidth + 'px' - }; - } else if (element == 'subtitle') { - css = { - bottom: parseInt(self.height / 16) + 'px', - width: self.width + 'px', - fontSize: parseInt(self.height / 20) + 'px', - WebkitTextStroke: (self.height / 1000) + 'px rgb(0, 0, 0)' - }; - } else if (element == 'space' || element == 'timeline') { - css = { - 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') { - css = { - width: self.width + 'px', - height: self.height + 'px' - }; - } - return css; - } - function setSizes(callback) { var ms = callback ? 250 : 0; self.width = self.options.fullscreen ? window.innerWidth : self.options.width; @@ -1087,14 +1082,10 @@ Ox.VideoPlayer = function(options, self) { function submitPositionInput() { self.$positionInput.hide(); self.$position.html('').show(); - setPosition(parsePositionInput(self.$positionInput.options('value'))); - if (self.loaded) { - self.video.currentTime = self.options.position; - } + setPosition(parsePositionInput(self.$positionInput.options('value')), true); if (self.wasPlaying) { - togglePaused(); + togglePaused(true); self.video.play(); - self.$playButton && self.$playButton.toggleTitle(); self.wasPlaying = false; } } @@ -1144,7 +1135,7 @@ Ox.VideoPlayer = function(options, self) { self.video.muted = self.options.muted; } - function togglePaused() { + function togglePaused(togglePlayButton) { self.options.paused = !self.options.paused; self.$timeline && self.$positionMarkerRing.css({ borderColor: 'rgba(255, 255, 255, ' + (self.options.paused ? 0.5 : 1) + ')' @@ -1160,8 +1151,7 @@ Ox.VideoPlayer = function(options, self) { } } else { if (self.options.playInToOut && self.options.position > self.options.out - self.secondsPerFrame) { - setPosition(self.options['in']); - self.video.currentTime = self.options.position; + setPosition(self.options['in'], true); } self.video.play(); self.playInterval = setInterval(playing, self.millisecondsPerFrame); @@ -1171,6 +1161,9 @@ Ox.VideoPlayer = function(options, self) { }, 250, togglePlayIcon); } } + if (togglePlayButton && self.$playButton) { + self.$playButton.toggleTitle(); + } } function togglePlayIcon() { @@ -1203,9 +1196,9 @@ Ox.VideoPlayer = function(options, self) { toggleMuted(); self.$muteButton && self.$muteButton.toggleTitle(); } else if (key == 'paused') { - togglePaused(); + togglePaused(true); } else if (key == 'position') { - setPosition(); + setPosition(value); } else if (key == 'scaleToFill') { self.$video.css(getVideoCSS()); }