diff --git a/source/Ox.UI/css/Ox.UI.css b/source/Ox.UI/css/Ox.UI.css index 1dd7cf4d..6e64b24d 100644 --- a/source/Ox.UI/css/Ox.UI.css +++ b/source/Ox.UI/css/Ox.UI.css @@ -1969,6 +1969,15 @@ Video +.OxVideoPlayer .OxCopyrightIcon { + position: absolute; + left: 0; + top: 0; + right: 0; + bottom: 0; + margin: auto; +} + .OxVideoPlayer .OxLoadingIcon { position: absolute; left: 0; diff --git a/source/Ox.UI/js/Video/Ox.VideoEditor.js b/source/Ox.UI/js/Video/Ox.VideoEditor.js index c180f13f..a7d824fc 100644 --- a/source/Ox.UI/js/Video/Ox.VideoEditor.js +++ b/source/Ox.UI/js/Video/Ox.VideoEditor.js @@ -15,6 +15,7 @@ Ox.VideoEditor = function(options, self) { var that = Ox.Element({}, self) .defaults({ annotationsSize: 0, + censored: [], cuts: [], duration: 0, find: '', @@ -165,6 +166,7 @@ Ox.VideoEditor = function(options, self) { ['play', 'in', 'out'].forEach(function(type, i) { self.$player[i] = Ox.VideoPlayer({ + censored: self.options.censored, controlsBottom: type == 'play' ? ['play', 'playInToOut', 'volume', 'size', 'space', 'position'] : ['goto', 'set', 'space', 'position'], diff --git a/source/Ox.UI/js/Video/Ox.VideoElement.js b/source/Ox.UI/js/Video/Ox.VideoElement.js index 51ad51a3..e451253e 100644 --- a/source/Ox.UI/js/Video/Ox.VideoElement.js +++ b/source/Ox.UI/js/Video/Ox.VideoElement.js @@ -18,7 +18,8 @@ Ox.VideoElement = function(options, self) { preload: 'none', src: [] }) - .options(options || {}); + .options(options || {}) + .css({width: '100%', height: '100%'}); Ox.print('VIDEO ELEMENT OPTIONS', self.options) @@ -190,6 +191,13 @@ Ox.VideoElement = function(options, self) { item.videos = item.$videos.map(function($video) { return $video[0]; }); + self.$brightness = $('
').css({ + width: '100%', + height: '100%', + background: 'rgb(0, 0, 0)', + opacity: 0 + }) + .appendTo(that.$element); return item; } @@ -284,6 +292,20 @@ Ox.VideoElement = function(options, self) { return that; }; + /*@ + brightness get/set brightness + @*/ + that.brightness = function() { + var ret; + if (arguments.length == 0) { + ret = 1 - parseFloat(self.$brightness.css('opacity')); + } else { + self.$brightness.css({opacity: 1 - arguments[0]}); + ret = that; + } + return ret; + }; + /*@ buffered buffered @*/ diff --git a/source/Ox.UI/js/Video/Ox.VideoPanelPlayer.js b/source/Ox.UI/js/Video/Ox.VideoPanelPlayer.js index 4695c5fc..d2e86b58 100644 --- a/source/Ox.UI/js/Video/Ox.VideoPanelPlayer.js +++ b/source/Ox.UI/js/Video/Ox.VideoPanelPlayer.js @@ -15,6 +15,7 @@ Ox.VideoPanelPlayer = function(options, self) { var that = Ox.Element({}, self) .defaults({ annotationsSize: 256, + censored: [], duration: 0, height: 0, 'in': 0, @@ -65,6 +66,7 @@ Ox.VideoPanelPlayer = function(options, self) { }); self.$video = Ox.VideoPlayer({ + censored: self.options.censored, controlsTop: ['fullscreen', 'title', 'find'], controlsBottom: ['play', 'volume', 'scale', 'timeline', 'position', 'resolution'], enableFind: true, diff --git a/source/Ox.UI/js/Video/Ox.VideoPlayer.js b/source/Ox.UI/js/Video/Ox.VideoPlayer.js index 93057161..3e30ea33 100644 --- a/source/Ox.UI/js/Video/Ox.VideoPlayer.js +++ b/source/Ox.UI/js/Video/Ox.VideoPlayer.js @@ -10,6 +10,7 @@ Ox.VideoPlayer Generic Video Player in In point (sec) out Out point (sec) text Text + censored Array of censored ranges controlsBottom <[s]|[]> Bottom controls, from left to right Can be 'fullscreen', 'scale', 'title', 'find', 'menu', 'play', 'playInToOut', 'previous', 'next', 'mute', 'volume', 'size', 'timeline', 'space', @@ -76,6 +77,8 @@ Ox.VideoPlayer = function(options, self) { var that = Ox.Element({}, self) .defaults({ annotations: [], + brightness: 1, + censored: [], controlsBottom: [], controlsTop: [], duration: 0, @@ -313,13 +316,27 @@ Ox.VideoPlayer = function(options, self) { } }); - self.$video = $('') + self.$video = $('
') + .appendTo(self.$videoContainer); + self.$image = $('') .attr({ src: Ox.UI.PATH + 'png/transparent.png' }) - .appendTo(self.$videoContainer); - - loadImage(); + .css({ + position: 'absolute', + width: '100%', + height: '100%' + }) + .appendTo(self.$video) + self.$brightness = $('
') + .css({ + position: 'absolute', + width: '100%', + height: '100%', + background: 'rgb(0, 0, 0)', + opacity: 1 - self.options.brightness + }) + .appendTo(self.$video); } @@ -392,6 +409,20 @@ Ox.VideoPlayer = function(options, self) { } } + if (self.options.censored.length) { + self.$copyrightIcon = Ox.Element({ + element: '', + // fixme: make this configurable + tooltip: 'This part of this video is not available in
your part of your country. Sorry for that.' + }) + .addClass('OxCopyrightIcon OxVideo') + .attr({ + src: Ox.UI.getImageURL('symbolNoCopyright', 'modern'), + }) + .hide() + .appendTo(self.$videoContainer); + } + /* ---------------------------------------------------------------------------- Markers @@ -977,7 +1008,7 @@ Ox.VideoPlayer = function(options, self) { } - self.options.type != 'play' && self.options.showMarkers && setMarkers(); + self.options.type != 'play' && setPosition(self.options.position); self.results = []; if (self.options.subtitles) { @@ -999,6 +1030,19 @@ Ox.VideoPlayer = function(options, self) { setSizes(); + function censor() { + if (self.options.type == 'play') { + self.$video + .brightness(self.censored ? 0.01 : self.options.brightness) + .volume(self.censored ? 0.01 : self.options.volume); + } else { + self.$brightness.css({ + opacity: 1 - (self.censored ? 0.01 : self.options.brightness) + }); + } + self.$copyrightIcon[self.censored ? 'show' : 'hide'](); + } + function clearInterfaceTimeout() { clearTimeout(self.interfaceTimeout); self.interfaceTimeout = 0; @@ -1071,9 +1115,28 @@ Ox.VideoPlayer = function(options, self) { return Ox.formatDuration(position, self.options.showMilliseconds); } + function getCensored() { + var censored = false; + Ox.forEach(self.options.censored, function(v) { + if ( + v['in'] < self.options.position + && v.out > self.options.position + ) { + censored = true; + return false; + } + }); + return censored; + } + function getCSS(element) { var css; - if (element == 'controlsTop' || element == 'controlsBottom') { + if (element == 'copyrightIcon') { + css = { + width: self.iconSize + 'px', + height: self.iconSize + 'px' + }; + } else if (element == 'controlsTop' || element == 'controlsBottom') { css = { width: self.width + 'px' }; @@ -1234,8 +1297,8 @@ Ox.VideoPlayer = function(options, self) { var subtitle = ''; Ox.forEach(self.options.subtitles, function(v) { if ( - v['in'] <= self.options.position && - v.out >= self.options.position + v['in'] <= self.options.position + && v.out >= self.options.position ) { subtitle = v.text; return false; @@ -1448,7 +1511,7 @@ Ox.VideoPlayer = function(options, self) { } function loadImage() { - self.$video + self.$image .one({ load: function() { hideLoadingIcon(); @@ -1491,7 +1554,9 @@ Ox.VideoPlayer = function(options, self) { self.options.duration = self.out - self['in']; Ox.print('---------------------------------------- POS', self.options.position) //self.options.position = Ox.limit(self.options.position, self['in'], self.out); - self.$video.currentTime(self.options.position); + //self.$video.currentTime(self.options.position); + + setPosition(self.options.position); // if not paused, but playInToOut, we haven't set autoplay before, // since autoplay seems to always play from the beginning @@ -1500,7 +1565,6 @@ Ox.VideoPlayer = function(options, self) { togglePaused('button'); } - self.options.paused && self.options.showMarkers && setMarkers(); self.options.paused && self.playOnLoad && togglePaused('button'); self.$playButton && self.$playButton.options({ disabled: false @@ -1662,6 +1726,7 @@ Ox.VideoPlayer = function(options, self) { ) / self.options.fps; */ self.options.paused && self.options.showMarkers && setMarkers(); + self.options.censored.length && setCensored(); self.$subtitle && setSubtitle(); self.$position && self.$position.html(formatPosition()); if (self.options.type == 'play') { @@ -1720,7 +1785,7 @@ Ox.VideoPlayer = function(options, self) { self.width = self.options.fullscreen ? window.innerWidth : self.options.width; self.height = self.options.fullscreen ? window.innerHeight : self.options.height; self.videoCSS = getVideoCSS(); - self.iconSize = Math.max(Math.round(self.height / 10), 16); + self.iconSize = Ox.limit(Math.round(self.height / 10), 16, 32); if (self.$timeline || self.$spaceBottom) { self.timelineWidth = getTimelineWidth(); if (self.$timeline) { @@ -1734,6 +1799,7 @@ Ox.VideoPlayer = function(options, self) { setSize(self.$logo, getCSS('logo'), animate); setSize(self.$loadingIcon, getCSS('loadingIcon'), animate); setSize(self.$playIcon, getCSS('playIcon'), animate); + setSize(self.$copyrightIcon, getCSS('copyrightIcon'), animate); setSize(self.$subtitle, getCSS('subtitle'), animate); setSize(self.$controlsTop, getCSS('controlsTop'), animate); setSize(self.$title, getCSS('title'), animate); @@ -1767,6 +1833,14 @@ Ox.VideoPlayer = function(options, self) { } } + function setCensored() { + var censored = getCensored(); + if (censored != self.censored) { + self.censored = censored; + censor(); + } + } + function setSubtitle() { var subtitle = getSubtitle(); if (subtitle != self.subtitle) { @@ -1809,7 +1883,7 @@ Ox.VideoPlayer = function(options, self) { self.$video.muted(self.options.muted); self.$muteButton.toggleTitle(); } - self.$video.volume(self.options.volume); + !self.censored && self.$video.volume(self.options.volume); self.$volumeButton.attr({ src: getVolumeImageURL() });