Commit 9967b75eef7c8466cf7e62217026bc3c013ff8a9
1 parent
4f216c98
Exists in
staging
and in
4 other branches
falta escolher qual galeria apresentar no bloco
Showing
11 changed files
with
1029 additions
and
94 deletions
Show diff stats
plugins/video/lib/ext/article.rb
... | ... | @@ -2,6 +2,8 @@ require_dependency 'article' |
2 | 2 | |
3 | 3 | class Article |
4 | 4 | |
5 | + scope :video_gallery, :conditions => ["articles.type == 'VideoGallery'"] | |
6 | + | |
5 | 7 | #FIXME This should be done via hotspot |
6 | 8 | def self.folder_types_with_video |
7 | 9 | self.folder_types_without_video << 'VideoPlugin::VideoGallery' |
... | ... | @@ -11,5 +13,35 @@ class Article |
11 | 13 | class << self |
12 | 14 | alias_method_chain :folder_types, :video |
13 | 15 | end |
16 | + | |
14 | 17 | |
18 | +# def self.articles_columns | |
19 | +# Article.column_names.map {|c| "articles.#{c}"} .join(",") | |
20 | +# end | |
21 | +# | |
22 | +# def self.most_accessed(owner, limit = nil) | |
23 | +# conditions = owner.kind_of?(Environment) ? ["hits > 0"] : ["profile_id = ? and hits > 0", owner.id] | |
24 | +# result = Article.relevant_content.find( | |
25 | +# :all, | |
26 | +# :order => 'hits desc', | |
27 | +# :limit => limit, | |
28 | +# :conditions => conditions) | |
29 | +# result.paginate({:page => 1, :per_page => limit}) | |
30 | +# end | |
31 | + | |
32 | + def self.can_be_listed | |
33 | + conditions = owner.kind_of?(Environment) ? ["hits > 0"] : ["profile_id = ? and hits > 0", owner.id] | |
34 | + result = Article.video_gallery.find( | |
35 | + :all, | |
36 | + :order => 'hits desc', | |
37 | + :conditions => conditions) | |
38 | + end | |
39 | + | |
40 | + | |
15 | 41 | end |
42 | + | |
43 | + | |
44 | + | |
45 | + | |
46 | + | |
47 | + | ... | ... |
plugins/video/lib/video_plugin.rb
plugins/video/lib/video_plugin/video_gallery_helper.rb
... | ... | @@ -6,7 +6,7 @@ module VideoPlugin::VideoGalleryHelper |
6 | 6 | if !configure[:contents].blank? |
7 | 7 | configure[:contents] = configure[:contents].paginate( |
8 | 8 | :order => "updated_at DESC", |
9 | - :per_page => 16, | |
9 | + :per_page => 17, | |
10 | 10 | :page => params[:npage] |
11 | 11 | ) |
12 | 12 | render :file => 'shared/video_list', :locals => configure | ... | ... |
plugins/video/public/javascripts/videojs/vjs.youtube.js
1 | -!function(){function addEventListener(element,event,cb){element.addEventListener?element.addEventListener(event,cb,!0):element.attachEvent(event,cb)}function setInnerText(element,text){if("undefined"==typeof element)return!1;var textProperty="innerText"in element?"innerText":"textContent";try{element[textProperty]=text}catch(anException){element.setAttribute("innerText",text)}}videojs.Youtube=videojs.MediaTechController.extend({init:function(player,options,ready){if(this.features.progressEvents=!1,this.features.timeupdateEvents=!1,videojs.MediaTechController.call(this,player,options,ready),this.isIos=/(iPad|iPhone|iPod)/g.test(navigator.userAgent),this.isAndroid=/(Android)/g.test(navigator.userAgent),this.playVideoIsAllowed=!(this.isIos||this.isAndroid),"undefined"!=typeof options.source)for(var key in options.source)options.source.hasOwnProperty(key)&&(player.options()[key]=options.source[key]);this.userQuality=videojs.Youtube.convertQualityName(player.options().quality),this.player_=player,this.playerEl_=document.getElementById(player.id()),this.playerEl_.className+=" vjs-youtube",this.qualityButton=document.createElement("div"),this.qualityButton.setAttribute("class","vjs-quality-button vjs-menu-button vjs-control"),this.qualityButton.setAttribute("tabindex",0);var qualityContent=document.createElement("div");this.qualityButton.appendChild(qualityContent),this.qualityTitle=document.createElement("span"),qualityContent.appendChild(this.qualityTitle),"undefined"!==player.options().quality&&setInnerText(this.qualityTitle,player.options().quality||"auto");var qualityMenu=document.createElement("div");if(qualityMenu.setAttribute("class","vjs-menu"),this.qualityButton.appendChild(qualityMenu),this.qualityMenuContent=document.createElement("ul"),this.qualityMenuContent.setAttribute("class","vjs-menu-content"),qualityMenu.appendChild(this.qualityMenuContent),this.id_=this.player_.id()+"_youtube_api",this.el_=videojs.Component.prototype.createEl("iframe",{id:this.id_,className:"vjs-tech",scrolling:"no",marginWidth:0,marginHeight:0,frameBorder:0}),this.el_.setAttribute("allowFullScreen",""),this.playerEl_.insertBefore(this.el_,this.playerEl_.firstChild),/MSIE (\d+\.\d+);/.test(navigator.userAgent)){var ieVersion=Number(RegExp.$1);this.addIframeBlocker(ieVersion)}else/(iPad|iPhone|iPod|android)/g.test(navigator.userAgent)||(this.el_.className+=" onDesktop",this.addIframeBlocker());this.parseSrc(player.options().src),this.playOnReady=this.player_.options().autoplay||!1,this.forceSSL=!("undefined"!=typeof this.player_.options().forceSSL&&this.player_.options().forceSSL!==!0),this.forceHTML5=!("undefined"!=typeof this.player_.options().forceHTML5&&this.player_.options().forceHTML5!==!0),this.updateIframeSrc();var self=this;player.ready(function(){var controlBar=self.playerEl_.querySelectorAll(".vjs-control-bar")[0];controlBar.appendChild(self.qualityButton),self.playOnReady&&!self.player_.options().ytcontrols&&("undefined"!=typeof self.player_.loadingSpinner&&self.player_.loadingSpinner.show(),"undefined"!=typeof self.player_.bigPlayButton&&self.player_.bigPlayButton.hide()),player.trigger("loadstart")}),this.on("dispose",function(){this.ytplayer&&this.ytplayer.destroy(),this.player_.options().ytcontrols||this.player_.off("waiting",this.bindedWaiting),this.playerEl_.querySelectorAll(".vjs-poster")[0].style.backgroundImage="none",this.el_.parentNode&&this.el_.parentNode.removeChild(this.el_),this.qualityButton.parentNode&&this.qualityButton.parentNode.removeChild(this.qualityButton),"undefined"!=typeof this.player_.loadingSpinner&&this.player_.loadingSpinner.hide(),"undefined"!=typeof this.player_.bigPlayButton&&this.player_.bigPlayButton.hide(),this.iframeblocker&&this.playerEl_.removeChild(this.iframeblocker)})}}),videojs.Youtube.prototype.updateIframeSrc=function(){var params={enablejsapi:1,iv_load_policy:3,playerapiid:this.id(),disablekb:1,wmode:"transparent",controls:this.player_.options().ytcontrols?1:0,html5:this.player_.options().forceHTML5?1:null,playsinline:this.player_.options().playsInline?1:0,showinfo:0,modestbranding:1,rel:0,autoplay:this.playOnReady?1:0,loop:this.player_.options().loop?1:0,list:this.playlistId,vq:this.userQuality,origin:window.location.protocol+"//"+window.location.host};"file:"===window.location.protocol&&delete params.origin;for(var prop in params)!params.hasOwnProperty(prop)||"undefined"!=typeof params[prop]&&null!==params[prop]||delete params[prop];var self=this;if(null===this.videoId)this.el_.src="about:blank",setTimeout(function(){self.triggerReady()},500);else if(this.el_.src=(this.forceSSL||"file:"===window.location.protocol?"https:":window.location.protocol)+"//www.youtube.com/embed/"+this.videoId+"?"+videojs.Youtube.makeQueryString(params),this.player_.options().ytcontrols?this.player_.controls(!1):"undefined"==typeof this.player_.poster()&&setTimeout(function(){var posterEl=self.playerEl_.querySelectorAll(".vjs-poster")[0];posterEl.style.backgroundImage="url(https://img.youtube.com/vi/"+self.videoId+"/0.jpg)",posterEl.style.display=""},100),this.bindedWaiting=function(){self.onWaiting()},this.player_.on("waiting",this.bindedWaiting),videojs.Youtube.apiReady)this.loadYoutube();else if(videojs.Youtube.loadingQueue.push(this),!videojs.Youtube.apiLoading){var tag=document.createElement("script");tag.onerror=function(e){self.onError(e)},tag.src=this.forceSSL||"file:"===window.location.protocol?"https://www.youtube.com/iframe_api":"//www.youtube.com/iframe_api";var firstScriptTag=document.getElementsByTagName("script")[0];firstScriptTag.parentNode.insertBefore(tag,firstScriptTag),videojs.Youtube.apiLoading=!0}},videojs.Youtube.prototype.onWaiting=function(){this.player_.bigPlayButton.hide()},videojs.Youtube.prototype.addIframeBlocker=function(ieVersion){this.iframeblocker=videojs.Component.prototype.createEl("div"),this.iframeblocker.className="iframeblocker",this.iframeblocker.style.position="absolute",this.iframeblocker.style.left=0,this.iframeblocker.style.right=0,this.iframeblocker.style.top=0,this.iframeblocker.style.bottom=0,this.iframeblocker.style.zIndex=9999,ieVersion&&9>ieVersion?this.iframeblocker.style.opacity=.01:this.iframeblocker.style.background="rgba(255, 255, 255, 0.01)";var self=this;addEventListener(this.iframeblocker,"mousemove",function(e){self.player_.userActive()||self.player_.userActive(!0),e.stopPropagation(),e.preventDefault()}),addEventListener(this.iframeblocker,"click",function(){self.paused()?self.play():self.pause()}),this.playerEl_.insertBefore(this.iframeblocker,this.el_.nextSibling)},videojs.Youtube.prototype.parseSrc=function(src){if(this.srcVal=src,src){var regId=/^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/,match=src.match(regId);this.videoId=match&&11===match[2].length?match[2]:null;var regPlaylist=/[?&]list=([^#\&\?]+)/;match=src.match(regPlaylist),null!==match&&match.length>1?this.playlistId=match[1]:this.playlistId&&delete this.playlistId;var regVideoQuality=/[?&]vq=([^#\&\?]+)/;match=src.match(regVideoQuality),null!==match&&match.length>1&&(this.userQuality=match[1],setInnerText(this.qualityTitle,videojs.Youtube.parseQualityName(this.userQuality)))}},videojs.Youtube.prototype.src=function(src){if("undefined"!=typeof src){if(this.parseSrc(src),"about:blank"===this.el_.src)return void this.updateIframeSrc();delete this.defaultQuality,null!==this.videoId&&(this.player_.options().autoplay&&this.playVideoIsAllowed?this.ytplayer.loadVideoById({videoId:this.videoId,suggestedQuality:this.userQuality}):this.ytplayer.cueVideoById({videoId:this.videoId,suggestedQuality:this.userQuality}),this.playerEl_.querySelectorAll(".vjs-poster")[0].style.backgroundImage="url(https://img.youtube.com/vi/"+this.videoId+"/0.jpg)",this.player_.poster("https://img.youtube.com/vi/"+this.videoId+"/0.jpg"))}return this.srcVal},videojs.Youtube.prototype.load=function(){},videojs.Youtube.prototype.play=function(){null!==this.videoId&&(this.player_.options().ytcontrols||this.player_.trigger("waiting"),this.isReady_?(this.ytplayer.setVolume(100*this.player_.volume()),this.volumeVal>0?this.ytplayer.unMute():this.ytplayer.mute(),this.playVideoIsAllowed&&this.ytplayer.playVideo()):this.playOnReady=!0)},videojs.Youtube.prototype.pause=function(){this.ytplayer.pauseVideo()},videojs.Youtube.prototype.paused=function(){return this.ytplayer?this.lastState!==YT.PlayerState.PLAYING&&this.lastState!==YT.PlayerState.BUFFERING:!0},videojs.Youtube.prototype.currentTime=function(){return this.ytplayer&&this.ytplayer.getCurrentTime?this.ytplayer.getCurrentTime():0},videojs.Youtube.prototype.setCurrentTime=function(seconds){this.ytplayer.seekTo(seconds,!0),this.player_.trigger("timeupdate")},videojs.Youtube.prototype.duration=function(){return this.ytplayer&&this.ytplayer.getDuration?this.ytplayer.getDuration():0},videojs.Youtube.prototype.currentSrc=function(){return this.srcVal},videojs.Youtube.prototype.volume=function(){return this.ytplayer&&isNaN(this.volumeVal)&&(this.volumeVal=this.ytplayer.getVolume()/100,this.player_.volume(this.volumeVal)),this.volumeVal},videojs.Youtube.prototype.setVolume=function(percentAsDecimal){"undefined"!=typeof percentAsDecimal&&percentAsDecimal!==this.volumeVal&&(this.ytplayer.setVolume(100*percentAsDecimal),this.volumeVal=percentAsDecimal,this.player_.trigger("volumechange"))},videojs.Youtube.prototype.muted=function(){return this.mutedVal},videojs.Youtube.prototype.setMuted=function(muted){muted?(this.ytplayer.mute(),this.player_.volume(0)):(this.ytplayer.unMute(),this.player_.volume(this.volumeVal)),this.mutedVal=muted,this.player_.trigger("volumechange")},videojs.Youtube.prototype.buffered=function(){if(this.ytplayer&&this.ytplayer.getVideoBytesLoaded){var loadedBytes=this.ytplayer.getVideoBytesLoaded(),totalBytes=this.ytplayer.getVideoBytesTotal();if(!loadedBytes||!totalBytes)return 0;var duration=this.ytplayer.getDuration(),secondsBuffered=loadedBytes/totalBytes*duration,secondsOffset=this.ytplayer.getVideoStartBytes()/totalBytes*duration;return videojs.createTimeRange(secondsOffset,secondsOffset+secondsBuffered)}return videojs.createTimeRange(0,0)},videojs.Youtube.prototype.supportsFullScreen=function(){return!0},videojs.Youtube.isSupported=function(){return!0},videojs.Youtube.canPlaySource=function(srcObj){return"video/youtube"===srcObj.type},videojs.Youtube.canControlVolume=function(){return!0},videojs.Youtube.loadingQueue=[],videojs.Youtube.prototype.loadYoutube=function(){this.ytplayer=new YT.Player(this.id_,{events:{onReady:function(e){e.target.vjsTech.onReady()},onStateChange:function(e){e.target.vjsTech.onStateChange(e.data)},onPlaybackQualityChange:function(e){e.target.vjsTech.onPlaybackQualityChange(e.data)},onError:function(e){e.target.vjsTech.onError(e.data)}}}),this.ytplayer.vjsTech=this},videojs.Youtube.makeQueryString=function(args){var array=[];for(var key in args)args.hasOwnProperty(key)&&array.push(key+"="+args[key]);return array.join("&")},window.onYouTubeIframeAPIReady=function(){for(var yt;yt=videojs.Youtube.loadingQueue.shift();)yt.loadYoutube();videojs.Youtube.loadingQueue=[],videojs.Youtube.apiReady=!0},videojs.Youtube.prototype.onReady=function(){this.isReady_=!0,this.triggerReady(),this.player_.trigger("loadedmetadata"),this.player_.trigger("durationchange"),this.player_.trigger("timeupdate"),"undefined"!=typeof this.player_.loadingSpinner&&this.player_.loadingSpinner.hide(),this.player_.options().muted&&this.setMuted(!0),this.playOnReady&&(this.playOnReady=!1,this.play())},videojs.Youtube.prototype.updateQualities=function(){function setupEventListener(el){addEventListener(el,"click",function(){var quality=this.getAttribute("data-val");self.ytplayer.setPlaybackQuality(quality),self.userQuality=quality,setInnerText(self.qualityTitle,videojs.Youtube.parseQualityName(quality));var selected=self.qualityMenuContent.querySelector(".vjs-selected");selected&&videojs.Youtube.removeClass(selected,"vjs-selected"),videojs.Youtube.addClass(this,"vjs-selected")})}var qualities=this.ytplayer.getAvailableQualityLevels(),self=this;if(qualities.indexOf(this.userQuality)<0&&setInnerText(self.qualityTitle,videojs.Youtube.parseQualityName(this.defaultQuality)),0===qualities.length)this.qualityButton.style.display="none";else{for(this.qualityButton.style.display="";this.qualityMenuContent.hasChildNodes();)this.qualityMenuContent.removeChild(this.qualityMenuContent.lastChild);for(var i=0;i<qualities.length;++i){var el=document.createElement("li");el.setAttribute("class","vjs-menu-item"),setInnerText(el,videojs.Youtube.parseQualityName(qualities[i])),el.setAttribute("data-val",qualities[i]),qualities[i]===this.quality&&videojs.Youtube.addClass(el,"vjs-selected"),setupEventListener(el),this.qualityMenuContent.appendChild(el)}}},videojs.Youtube.prototype.onStateChange=function(state){if(state!==this.lastState){switch(state){case-1:this.player_.trigger("durationchange");break;case YT.PlayerState.ENDED:this.player_.options().ytcontrols||(this.playerEl_.querySelectorAll(".vjs-poster")[0].style.display="block","undefined"!=typeof this.player_.bigPlayButton&&this.player_.bigPlayButton.show()),this.player_.trigger("ended");break;case YT.PlayerState.PLAYING:this.playVideoIsAllowed=!0,this.updateQualities(),this.player_.trigger("timeupdate"),this.player_.trigger("durationchange"),this.player_.trigger("playing"),this.player_.trigger("play");break;case YT.PlayerState.PAUSED:this.player_.trigger("pause");break;case YT.PlayerState.BUFFERING:this.player_.trigger("timeupdate"),this.player_.options().ytcontrols||this.player_.trigger("waiting");break;case YT.PlayerState.CUED:}this.lastState=state}},videojs.Youtube.convertQualityName=function(name){switch(name){case"144p":return"tiny";case"240p":return"small";case"360p":return"medium";case"480p":return"large";case"720p":return"hd720";case"1080p":return"hd1080"}return"auto"},videojs.Youtube.parseQualityName=function(name){switch(name){case"tiny":return"144p";case"small":return"240p";case"medium":return"360p";case"large":return"480p";case"hd720":return"720p";case"hd1080":return"1080p"}return"auto"},videojs.Youtube.prototype.onPlaybackQualityChange=function(quality){if("undefined"!=typeof this.defaultQuality||(this.defaultQuality=quality,"undefined"==typeof this.userQuality)){switch(this.quality=quality,setInnerText(this.qualityTitle,videojs.Youtube.parseQualityName(quality)),quality){case"medium":this.player_.videoWidth=480,this.player_.videoHeight=360;break;case"large":this.player_.videoWidth=640,this.player_.videoHeight=480;break;case"hd720":this.player_.videoWidth=960,this.player_.videoHeight=720;break;case"hd1080":this.player_.videoWidth=1440,this.player_.videoHeight=1080;break;case"highres":this.player_.videoWidth=1920,this.player_.videoHeight=1080;break;case"small":this.player_.videoWidth=320,this.player_.videoHeight=240;break;case"tiny":this.player_.videoWidth=144,this.player_.videoHeight=108;break;default:this.player_.videoWidth=0,this.player_.videoHeight=0}this.player_.trigger("ratechange")}},videojs.Youtube.prototype.onError=function(error){this.player_.error(error),(100===error||101===error||150===error)&&(this.player_.bigPlayButton.hide(),this.player_.loadingSpinner.hide(),this.player_.posterImage.hide())},videojs.Youtube.addClass=function(element,classToAdd){-1===(" "+element.className+" ").indexOf(" "+classToAdd+" ")&&(element.className=""===element.className?classToAdd:element.className+" "+classToAdd)},videojs.Youtube.removeClass=function(element,classToRemove){var classNames,i;if(-1!==element.className.indexOf(classToRemove)){for(classNames=element.className.split(" "),i=classNames.length-1;i>=0;i--)classNames[i]===classToRemove&&classNames.splice(i,1);element.className=classNames.join(" ")}};var style=document.createElement("style"),def=" .vjs-youtube .vjs-poster { background-size: 100%!important; }.vjs-youtube .vjs-poster, .vjs-youtube .vjs-loading-spinner, .vjs-youtube .vjs-text-track-display{ pointer-events: none !important; }.vjs-youtube.vjs-user-active .iframeblocker { display: none; }.vjs-youtube.vjs-user-inactive .vjs-tech.onDesktop { pointer-events: none; }.vjs-quality-button > div:first-child > span:first-child { position:relative;top:7px }";style.setAttribute("type","text/css"),document.getElementsByTagName("head")[0].appendChild(style),style.styleSheet?style.styleSheet.cssText=def:style.appendChild(document.createTextNode(def)),Array.prototype.indexOf||(Array.prototype.indexOf=function(elt){var len=this.length>>>0,from=Number(arguments[1])||0;for(from=0>from?Math.ceil(from):Math.floor(from),0>from&&(from+=len);len>from;from++)if(from in this&&this[from]===elt)return from;return-1})}(); | |
2 | 1 | \ No newline at end of file |
2 | +/* global videojs, YT */ | |
3 | +/* jshint browser: true */ | |
4 | + | |
5 | +(function() { | |
6 | + /** | |
7 | + * @fileoverview YouTube Media Controller - Wrapper for YouTube Media API | |
8 | + */ | |
9 | + | |
10 | + /** | |
11 | + * YouTube Media Controller - Wrapper for YouTube Media API | |
12 | + * @param {videojs.Player|Object} player | |
13 | + * @param {Object=} options | |
14 | + * @param {Function=} ready | |
15 | + * @constructor | |
16 | + */ | |
17 | + | |
18 | + function addEventListener(element, event, cb) { | |
19 | + if(!element.addEventListener) { | |
20 | + element.attachEvent(event, cb); | |
21 | + } else { | |
22 | + element.addEventListener(event, cb, true); | |
23 | + } | |
24 | + } | |
25 | + | |
26 | + videojs.Youtube = videojs.MediaTechController.extend({ | |
27 | + /** @constructor */ | |
28 | + init: function(player, options, ready) { | |
29 | + // Save this for internal usage | |
30 | + this.player_ = player; | |
31 | + | |
32 | + // No event is triggering this for YouTube | |
33 | + this['featuresProgressEvents'] = false; | |
34 | + this['featuresTimeupdateEvents'] = false; | |
35 | + // Enable rate changes | |
36 | + this['featuresPlaybackRate'] = true; | |
37 | + | |
38 | + videojs.MediaTechController.call(this, player, options, ready); | |
39 | + | |
40 | + this.isIos = /(iPad|iPhone|iPod)/g.test( navigator.userAgent ); | |
41 | + this.isAndroid = /(Android)/g.test( navigator.userAgent ); | |
42 | + //used to prevent play events on IOS7 and Android > 4.2 until the user has clicked the player | |
43 | + this.playVideoIsAllowed = !(this.isIos || this.isAndroid); | |
44 | + | |
45 | + // autoplay is disabled for mobile | |
46 | + if (this.isIos || this.isAndroid) { | |
47 | + this.player_.options()['autoplay'] = false; | |
48 | + } | |
49 | + | |
50 | + // Copy the JavaScript options if they exists | |
51 | + if(typeof options['source'] !== 'undefined') { | |
52 | + for(var key in options['source']) { | |
53 | + if(options['source'].hasOwnProperty(key)) { | |
54 | + player.options()[key] = options['source'][key]; | |
55 | + } | |
56 | + } | |
57 | + } | |
58 | + | |
59 | + this.userQuality = videojs.Youtube.convertQualityName(player.options()['quality']); | |
60 | + | |
61 | + this.playerEl_ = document.getElementById(player.id()); | |
62 | + this.playerEl_.className += ' vjs-youtube'; | |
63 | + | |
64 | + // Create the Quality button | |
65 | + this.qualityButton = document.createElement('div'); | |
66 | + this.qualityButton.setAttribute('class', 'vjs-quality-button vjs-menu-button vjs-control'); | |
67 | + this.qualityButton.setAttribute('tabindex', 0); | |
68 | + | |
69 | + var qualityContent = document.createElement('div'); | |
70 | + qualityContent.setAttribute('class', 'vjs-control-content'); | |
71 | + this.qualityButton.appendChild(qualityContent); | |
72 | + | |
73 | + this.qualityTitle = document.createElement('span'); | |
74 | + this.qualityTitle.setAttribute('class', 'vjs-control-text'); | |
75 | + qualityContent.appendChild(this.qualityTitle); | |
76 | + | |
77 | + if(player.options()['quality'] !== 'undefined') { | |
78 | + setInnerText(this.qualityTitle, player.options()['quality'] || 'auto'); | |
79 | + } | |
80 | + | |
81 | + var qualityMenu = document.createElement('div'); | |
82 | + qualityMenu.setAttribute('class', 'vjs-menu'); | |
83 | + qualityContent.appendChild(qualityMenu); | |
84 | + | |
85 | + this.qualityMenuContent = document.createElement('ul'); | |
86 | + this.qualityMenuContent.setAttribute('class', 'vjs-menu-content'); | |
87 | + qualityMenu.appendChild(this.qualityMenuContent); | |
88 | + | |
89 | + this.id_ = this.player_.id() + '_youtube_api'; | |
90 | + | |
91 | + this.el_ = videojs.Component.prototype.createEl('iframe', { | |
92 | + id: this.id_, | |
93 | + className: 'vjs-tech', | |
94 | + scrolling: 'no', | |
95 | + marginWidth: 0, | |
96 | + marginHeight: 0, | |
97 | + frameBorder: 0 | |
98 | + }); | |
99 | + | |
100 | + this.el_.setAttribute('allowFullScreen', ''); | |
101 | + | |
102 | + this.playerEl_.insertBefore(this.el_, this.playerEl_.firstChild); | |
103 | + | |
104 | + if(/MSIE (\d+\.\d+);/.test(navigator.userAgent)) { | |
105 | + var ieVersion = Number(RegExp.$1); | |
106 | + this.addIframeBlocker(ieVersion); | |
107 | + } else if(!/(iPad|iPhone|iPod|Android)/g.test(navigator.userAgent)) { | |
108 | + // the pointer-events: none block the mobile player | |
109 | + this.el_.className += ' onDesktop'; | |
110 | + this.addIframeBlocker(); | |
111 | + } | |
112 | + | |
113 | + this.parseSrc(player.options()['src']); | |
114 | + | |
115 | + this.playOnReady = this.player_.options()['autoplay'] && this.playVideoIsAllowed; | |
116 | + this.forceSSL = !!( | |
117 | + typeof this.player_.options()['forceSSL'] === 'undefined' || | |
118 | + this.player_.options()['forceSSL'] === true | |
119 | + ); | |
120 | + this.forceHTML5 = !!( | |
121 | + typeof this.player_.options()['forceHTML5'] === 'undefined' || | |
122 | + this.player_.options()['forceHTML5'] === true | |
123 | + ); | |
124 | + | |
125 | + this.updateIframeSrc(); | |
126 | + | |
127 | + var self = this; | |
128 | + | |
129 | + player.ready(function() { | |
130 | + if (self.player_.options()['controls']) { | |
131 | + var controlBar = self.playerEl_.querySelectorAll('.vjs-control-bar')[0]; | |
132 | + if (controlBar) { | |
133 | + controlBar.appendChild(self.qualityButton); | |
134 | + } | |
135 | + } | |
136 | + | |
137 | + if(self.playOnReady && !self.player_.options()['ytcontrols']) { | |
138 | + if(typeof self.player_.loadingSpinner !== 'undefined') { | |
139 | + self.player_.loadingSpinner.show(); | |
140 | + } | |
141 | + if(typeof self.player_.bigPlayButton !== 'undefined') { | |
142 | + self.player_.bigPlayButton.hide(); | |
143 | + } | |
144 | + } | |
145 | + | |
146 | + player.trigger('loadstart'); | |
147 | + }); | |
148 | + | |
149 | + this.on('dispose', function() { | |
150 | + if(this.ytplayer) { | |
151 | + this.ytplayer.destroy(); | |
152 | + } | |
153 | + | |
154 | + if(!this.player_.options()['ytcontrols']) { | |
155 | + this.player_.off('waiting', this.bindedWaiting); | |
156 | + } | |
157 | + | |
158 | + // Remove the poster | |
159 | + this.playerEl_.querySelectorAll('.vjs-poster')[0].style.backgroundImage = 'none'; | |
160 | + | |
161 | + // If still connected to the DOM, remove it. | |
162 | + if(this.el_.parentNode) { | |
163 | + this.el_.parentNode.removeChild(this.el_); | |
164 | + } | |
165 | + | |
166 | + // Get rid of the created DOM elements | |
167 | + if (this.qualityButton.parentNode) { | |
168 | + this.qualityButton.parentNode.removeChild(this.qualityButton); | |
169 | + } | |
170 | + | |
171 | + if(typeof this.player_.loadingSpinner !== 'undefined') { | |
172 | + this.player_.loadingSpinner.hide(); | |
173 | + } | |
174 | + if(typeof this.player_.bigPlayButton !== 'undefined') { | |
175 | + this.player_.bigPlayButton.hide(); | |
176 | + } | |
177 | + | |
178 | + if(this.iframeblocker) { | |
179 | + this.playerEl_.removeChild(this.iframeblocker); | |
180 | + } | |
181 | + }); | |
182 | + } | |
183 | + }); | |
184 | + | |
185 | + videojs.Youtube.prototype.updateIframeSrc = function() { | |
186 | + var params = { | |
187 | + enablejsapi: 1, | |
188 | + /*jshint -W106 */ | |
189 | + iv_load_policy: 3, | |
190 | + /*jshint +W106 */ | |
191 | + playerapiid: this.id(), | |
192 | + disablekb: 1, | |
193 | + wmode: 'transparent', | |
194 | + controls: (this.player_.options()['ytcontrols']) ? 1 : 0, | |
195 | + html5: (this.player_.options()['forceHTML5']) ? 1 : null, | |
196 | + playsinline: (this.player_.options()['playsInline']) ? 1 : 0, | |
197 | + showinfo: 0, | |
198 | + rel: 0, | |
199 | + autoplay: (this.playOnReady) ? 1 : 0, | |
200 | + loop: (this.player_.options()['loop']) ? 1 : 0, | |
201 | + list: this.playlistId, | |
202 | + vq: this.userQuality, | |
203 | + origin: window.location.protocol + '//' + window.location.host | |
204 | + }; | |
205 | + | |
206 | + // When running with no Web server, we can't specify the origin or it will break the YouTube API messages | |
207 | + if(window.location.protocol === 'file:') { | |
208 | + delete params.origin; | |
209 | + } | |
210 | + | |
211 | + // Delete unset properties | |
212 | + for(var prop in params) { | |
213 | + if(params.hasOwnProperty(prop) && | |
214 | + ( typeof params[ prop ] === 'undefined' || params[ prop ] === null ) | |
215 | + ) { | |
216 | + delete params[ prop ]; | |
217 | + } | |
218 | + } | |
219 | + var self = this; | |
220 | + | |
221 | + if(!this.videoId) { | |
222 | + this.el_.src = 'about:blank'; | |
223 | + setTimeout(function() { | |
224 | + self.triggerReady(); | |
225 | + }, 500); | |
226 | + } else { | |
227 | + this.el_.src = ( | |
228 | + (this.forceSSL || window.location.protocol === 'file:') ? | |
229 | + 'https:' | |
230 | + : window.location.protocol | |
231 | + ) + '//www.youtube.com/embed/' + this.videoId + '?' + videojs.Youtube.makeQueryString(params); | |
232 | + | |
233 | + if(this.player_.options()['ytcontrols']) { | |
234 | + // Disable the video.js controls if we use the YouTube controls | |
235 | + this.player_.controls(false); | |
236 | + } else if(typeof this.player_.poster() === 'undefined' || this.player_.poster().length === 0) { | |
237 | + // Wait here because the tech is still null in constructor | |
238 | + setTimeout(function() { | |
239 | + self.player_.poster('https://img.youtube.com/vi/' + self.videoId + '/0.jpg'); | |
240 | + }, 100); | |
241 | + } | |
242 | + | |
243 | + this.bindedWaiting = function() { | |
244 | + self.onWaiting(); | |
245 | + }; | |
246 | + | |
247 | + this.player_.on('waiting', this.bindedWaiting); | |
248 | + | |
249 | + if(videojs.Youtube.apiReady) { | |
250 | + this.loadYoutube(); | |
251 | + } else { | |
252 | + // Add to the queue because the YouTube API is not ready | |
253 | + videojs.Youtube.loadingQueue.push(this); | |
254 | + | |
255 | + // Load the YouTube API if it is the first YouTube video | |
256 | + if(!videojs.Youtube.apiLoading) { | |
257 | + var tag = document.createElement('script'); | |
258 | + tag.onerror = function(e) { | |
259 | + self.onError(e); | |
260 | + }; | |
261 | + tag.src = ( !this.forceSSL && window.location.protocol !== 'file:' ) ? | |
262 | + '//www.youtube.com/iframe_api' | |
263 | + : 'https://www.youtube.com/iframe_api'; | |
264 | + var firstScriptTag = document.getElementsByTagName('script')[0]; | |
265 | + firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); | |
266 | + videojs.Youtube.apiLoading = true; | |
267 | + } | |
268 | + } | |
269 | + } | |
270 | + }; | |
271 | + | |
272 | + videojs.Youtube.prototype.onWaiting = function(/*e*/) { | |
273 | + // Make sure to hide the play button while the spinner is there | |
274 | + if(typeof this.player_.bigPlayButton !== 'undefined') { | |
275 | + this.player_.bigPlayButton.hide(); | |
276 | + } | |
277 | + }; | |
278 | + | |
279 | + videojs.Youtube.prototype.addIframeBlocker = function(ieVersion) { | |
280 | + this.iframeblocker = videojs.Component.prototype.createEl('div'); | |
281 | + | |
282 | + this.iframeblocker.className = 'iframeblocker'; | |
283 | + | |
284 | + this.iframeblocker.style.position = 'absolute'; | |
285 | + this.iframeblocker.style.left = 0; | |
286 | + this.iframeblocker.style.right = 0; | |
287 | + this.iframeblocker.style.top = 0; | |
288 | + this.iframeblocker.style.bottom = 0; | |
289 | + | |
290 | + // Odd quirk for IE8 (doesn't support rgba) | |
291 | + if(ieVersion && ieVersion < 9) { | |
292 | + this.iframeblocker.style.opacity = 0.01; | |
293 | + } else { | |
294 | + this.iframeblocker.style.background = 'rgba(255, 255, 255, 0.01)'; | |
295 | + } | |
296 | + | |
297 | + var self = this; | |
298 | + addEventListener(this.iframeblocker, 'mousemove', function(e) { | |
299 | + if(!self.player_.userActive()) { | |
300 | + self.player_.userActive(true); | |
301 | + } | |
302 | + | |
303 | + e.stopPropagation(); | |
304 | + e.preventDefault(); | |
305 | + }); | |
306 | + | |
307 | + addEventListener(this.iframeblocker, 'click', function(/*e*/) { | |
308 | + if(self.paused()) { | |
309 | + self.play(); | |
310 | + } else { | |
311 | + self.pause(); | |
312 | + } | |
313 | + }); | |
314 | + | |
315 | + this.playerEl_.insertBefore(this.iframeblocker, this.el_.nextSibling); | |
316 | + }; | |
317 | + | |
318 | + videojs.Youtube.prototype.parseSrc = function(src) { | |
319 | + this.srcVal = src; | |
320 | + | |
321 | + if(src) { | |
322 | + // Regex to parse the video ID | |
323 | + var regId = /^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/; | |
324 | + var match = src.match(regId); | |
325 | + | |
326 | + if(match && match[2].length === 11) { | |
327 | + this.videoId = match[2]; | |
328 | + } else { | |
329 | + this.videoId = null; | |
330 | + } | |
331 | + | |
332 | + // Regex to parse the playlist ID | |
333 | + var regPlaylist = /[?&]list=([^#\&\?]+)/; | |
334 | + match = src.match(regPlaylist); | |
335 | + | |
336 | + if(match !== null && match.length > 1) { | |
337 | + this.playlistId = match[1]; | |
338 | + } else { | |
339 | + // Make sure their is no playlist | |
340 | + if(this.playlistId) { | |
341 | + delete this.playlistId; | |
342 | + } | |
343 | + } | |
344 | + | |
345 | + // Parse video quality option | |
346 | + var regVideoQuality = /[?&]vq=([^#\&\?]+)/; | |
347 | + match = src.match(regVideoQuality); | |
348 | + | |
349 | + if(match !== null && match.length > 1) { | |
350 | + this.userQuality = match[1]; | |
351 | + setInnerText(this.qualityTitle, videojs.Youtube.parseQualityName(this.userQuality)); | |
352 | + } | |
353 | + } | |
354 | + }; | |
355 | + | |
356 | + videojs.Youtube.prototype.src = function(src) { | |
357 | + if(typeof src !== 'undefined') { | |
358 | + this.parseSrc(src); | |
359 | + | |
360 | + if(this.el_.src === 'about:blank') { | |
361 | + this.updateIframeSrc(); | |
362 | + return; | |
363 | + } | |
364 | + | |
365 | + delete this.defaultQuality; | |
366 | + | |
367 | + if(this.videoId !== null) { | |
368 | + if(this.player_.options()['autoplay'] && this.playVideoIsAllowed) { | |
369 | + this.ytplayer.loadVideoById({ | |
370 | + videoId: this.videoId, | |
371 | + suggestedQuality: this.userQuality | |
372 | + }); | |
373 | + } else { | |
374 | + this.ytplayer.cueVideoById({ | |
375 | + videoId: this.videoId, | |
376 | + suggestedQuality: this.userQuality | |
377 | + }); | |
378 | + } | |
379 | + | |
380 | + // Update the poster | |
381 | + this.playerEl_.querySelectorAll('.vjs-poster')[0].style.backgroundImage = | |
382 | + 'url(https://img.youtube.com/vi/' + this.videoId + '/0.jpg)'; | |
383 | + this.player_.poster('https://img.youtube.com/vi/' + this.videoId + '/0.jpg'); | |
384 | + } | |
385 | + /* else Invalid URL */ | |
386 | + } | |
387 | + | |
388 | + return this.srcVal; | |
389 | + }; | |
390 | + | |
391 | + videojs.Youtube.prototype.load = function() { | |
392 | + }; | |
393 | + | |
394 | + videojs.Youtube.prototype.play = function() { | |
395 | + if(this.videoId !== null) { | |
396 | + | |
397 | + // Make sure to not display the spinner for mobile | |
398 | + if(!this.player_.options()['ytcontrols']) { | |
399 | + // Display the spinner until the video is playing by YouTube | |
400 | + this.player_.trigger('waiting'); | |
401 | + } | |
402 | + | |
403 | + if(this.isReady_) { | |
404 | + // Sync the player volume with YouTube | |
405 | + this.ytplayer.setVolume(this.player_.volume() * 100); | |
406 | + | |
407 | + if(this.volumeVal > 0) { | |
408 | + this.ytplayer.unMute(); | |
409 | + } else { | |
410 | + this.ytplayer.mute(); | |
411 | + } | |
412 | + | |
413 | + if(this.playVideoIsAllowed) { | |
414 | + this.ytplayer.playVideo(); | |
415 | + } | |
416 | + } else { | |
417 | + this.playOnReady = true; | |
418 | + } | |
419 | + } | |
420 | + }; | |
421 | + | |
422 | + videojs.Youtube.prototype.pause = function() { | |
423 | + this.ytplayer.pauseVideo(); | |
424 | + }; | |
425 | + videojs.Youtube.prototype.paused = function() { | |
426 | + return (this.ytplayer) ? | |
427 | + (this.lastState !== YT.PlayerState.PLAYING && this.lastState !== YT.PlayerState.BUFFERING) | |
428 | + : true; | |
429 | + }; | |
430 | + videojs.Youtube.prototype.currentTime = function() { | |
431 | + return (this.ytplayer && this.ytplayer.getCurrentTime) ? this.ytplayer.getCurrentTime() : 0; | |
432 | + }; | |
433 | + videojs.Youtube.prototype.setCurrentTime = function(seconds) { | |
434 | + this.ytplayer.seekTo(seconds, true); | |
435 | + this.player_.trigger('timeupdate'); | |
436 | + this.player_.trigger('seeking'); | |
437 | + this.isSeeking = true; | |
438 | + }; | |
439 | + videojs.Youtube.prototype.playbackRate = function() { | |
440 | + return (this.ytplayer && this.ytplayer.getPlaybackRate) ? this.ytplayer.getPlaybackRate() : 1.0; | |
441 | + }; | |
442 | + videojs.Youtube.prototype.setPlaybackRate = function(suggestedRate) { | |
443 | + if (this.ytplayer && this.ytplayer.setPlaybackRate) { | |
444 | + this.ytplayer.setPlaybackRate(suggestedRate); | |
445 | + this.player_.trigger('ratechange'); | |
446 | + } | |
447 | + }; | |
448 | + videojs.Youtube.prototype.duration = function() { | |
449 | + return (this.ytplayer && this.ytplayer.getDuration) ? this.ytplayer.getDuration() : 0; | |
450 | + }; | |
451 | + videojs.Youtube.prototype.currentSrc = function() { | |
452 | + return this.srcVal; | |
453 | + }; | |
454 | + videojs.Youtube.prototype.ended = function() { | |
455 | + return (this.ytplayer) ? (this.lastState === YT.PlayerState.ENDED) : false; | |
456 | + }; | |
457 | + | |
458 | + videojs.Youtube.prototype.volume = function() { | |
459 | + if(this.ytplayer && isNaN(this.volumeVal)) { | |
460 | + this.volumeVal = this.ytplayer.getVolume() / 100.0; | |
461 | + this.player_.volume(this.volumeVal); | |
462 | + } | |
463 | + | |
464 | + return this.volumeVal; | |
465 | + }; | |
466 | + | |
467 | + videojs.Youtube.prototype.setVolume = function(percentAsDecimal) { | |
468 | + if(typeof(percentAsDecimal) !== 'undefined' && percentAsDecimal !== this.volumeVal) { | |
469 | + this.ytplayer.setVolume(percentAsDecimal * 100.0); | |
470 | + this.volumeVal = percentAsDecimal; | |
471 | + this.player_.trigger('volumechange'); | |
472 | + } | |
473 | + }; | |
474 | + | |
475 | + videojs.Youtube.prototype.muted = function() { | |
476 | + return this.mutedVal; | |
477 | + }; | |
478 | + videojs.Youtube.prototype.setMuted = function(muted) { | |
479 | + if(muted) { | |
480 | + this.storedVolume = this.volumeVal; | |
481 | + this.ytplayer.mute(); | |
482 | + this.player_.volume(0); | |
483 | + } else { | |
484 | + this.ytplayer.unMute(); | |
485 | + this.player_.volume(this.storedVolume); | |
486 | + } | |
487 | + | |
488 | + this.mutedVal = muted; | |
489 | + | |
490 | + this.player_.trigger('volumechange'); | |
491 | + }; | |
492 | + | |
493 | + videojs.Youtube.prototype.buffered = function() { | |
494 | + if(this.ytplayer && this.ytplayer.getVideoBytesLoaded) { | |
495 | + var loadedBytes = this.ytplayer.getVideoBytesLoaded(); | |
496 | + var totalBytes = this.ytplayer.getVideoBytesTotal(); | |
497 | + if(!loadedBytes || !totalBytes) { | |
498 | + return 0; | |
499 | + } | |
500 | + | |
501 | + var duration = this.ytplayer.getDuration(); | |
502 | + var secondsBuffered = (loadedBytes / totalBytes) * duration; | |
503 | + var secondsOffset = (this.ytplayer.getVideoStartBytes() / totalBytes) * duration; | |
504 | + | |
505 | + return videojs.createTimeRange(secondsOffset, secondsOffset + secondsBuffered); | |
506 | + } else { | |
507 | + return videojs.createTimeRange(0, 0); | |
508 | + } | |
509 | + }; | |
510 | + | |
511 | + videojs.Youtube.prototype.supportsFullScreen = function() { | |
512 | + if (typeof this.el_.webkitEnterFullScreen === 'function') { | |
513 | + | |
514 | + // Seems to be broken in Chromium/Chrome && Safari in Leopard | |
515 | + if (/Android/.test(videojs.USER_AGENT) || !/Chrome|Mac OS X 10.5/.test(videojs.USER_AGENT)) { | |
516 | + return true; | |
517 | + } | |
518 | + } | |
519 | + return false; | |
520 | + }; | |
521 | + | |
522 | + // YouTube is supported on all platforms | |
523 | + videojs.Youtube.isSupported = function() { | |
524 | + return true; | |
525 | + }; | |
526 | + | |
527 | + // You can use video/youtube as a media in your HTML5 video to specify the source | |
528 | + videojs.Youtube.canPlaySource = function(srcObj) { | |
529 | + return (srcObj.type === 'video/youtube'); | |
530 | + }; | |
531 | + | |
532 | + // Always can control the volume | |
533 | + videojs.Youtube.canControlVolume = function() { | |
534 | + return true; | |
535 | + }; | |
536 | + | |
537 | + ////////////////////////////// YouTube specific functions ////////////////////////////// | |
538 | + | |
539 | + // All videos created before YouTube API is loaded | |
540 | + videojs.Youtube.loadingQueue = []; | |
541 | + | |
542 | + // Create the YouTube player | |
543 | + videojs.Youtube.prototype.loadYoutube = function() { | |
544 | + this.ytplayer = new YT.Player(this.id_, { | |
545 | + events: { | |
546 | + onReady: function(e) { | |
547 | + e.target.vjsTech.onReady(); | |
548 | + }, | |
549 | + onStateChange: function(e) { | |
550 | + e.target.vjsTech.onStateChange(e.data); | |
551 | + }, | |
552 | + onPlaybackQualityChange: function(e) { | |
553 | + e.target.vjsTech.onPlaybackQualityChange(e.data); | |
554 | + }, | |
555 | + onError: function(e) { | |
556 | + e.target.vjsTech.onError(e.data); | |
557 | + } | |
558 | + } | |
559 | + }); | |
560 | + | |
561 | + this.ytplayer.vjsTech = this; | |
562 | + }; | |
563 | + | |
564 | + // Transform a JavaScript object into URL params | |
565 | + videojs.Youtube.makeQueryString = function(args) { | |
566 | + var array = ['modestbranding=1']; | |
567 | + for(var key in args) { | |
568 | + if(args.hasOwnProperty(key)) { | |
569 | + array.push(key + '=' + args[key]); | |
570 | + } | |
571 | + } | |
572 | + | |
573 | + return array.join('&'); | |
574 | + }; | |
575 | + | |
576 | + // Called when YouTube API is ready to be used | |
577 | + window.onYouTubeIframeAPIReady = function() { | |
578 | + var yt; | |
579 | + while((yt = videojs.Youtube.loadingQueue.shift())) { | |
580 | + yt.loadYoutube(); | |
581 | + } | |
582 | + videojs.Youtube.loadingQueue = []; | |
583 | + videojs.Youtube.apiReady = true; | |
584 | + }; | |
585 | + | |
586 | + videojs.Youtube.prototype.onReady = function() { | |
587 | + this.isReady_ = true; | |
588 | + this.triggerReady(); | |
589 | + | |
590 | + this.player_.trigger('loadedmetadata'); | |
591 | + | |
592 | + // The duration is loaded so we might as well fire off the timeupdate and duration events | |
593 | + // this allows for the duration of the video (timeremaining) to be displayed if styled | |
594 | + // to show the control bar initially. This gives the user the ability to see how long the video | |
595 | + // is before clicking play | |
596 | + this.player_.trigger('durationchange'); | |
597 | + this.player_.trigger('timeupdate'); | |
598 | + | |
599 | + // Let the player take care of itself as soon as the YouTube is ready | |
600 | + // The loading spinner while waiting for the tech would be impossible otherwise | |
601 | + if (typeof this.player_.loadingSpinner !== 'undefined' && !this.isIos && !this.isAndroid) { | |
602 | + this.player_.loadingSpinner.hide(); | |
603 | + } | |
604 | + | |
605 | + if(this.player_.options()['muted']) { | |
606 | + this.setMuted(true); | |
607 | + } | |
608 | + | |
609 | + // Play ASAP if they clicked play before it's ready | |
610 | + if(this.playOnReady) { | |
611 | + this.playOnReady = false; | |
612 | + this.play(); | |
613 | + } | |
614 | + }; | |
615 | + | |
616 | + videojs.Youtube.prototype.updateQualities = function() { | |
617 | + | |
618 | + function setupEventListener(el) { | |
619 | + addEventListener(el, 'click', function() { | |
620 | + var quality = this.getAttribute('data-val'); | |
621 | + self.ytplayer.setPlaybackQuality(quality); | |
622 | + | |
623 | + self.userQuality = quality; | |
624 | + setInnerText(self.qualityTitle, videojs.Youtube.parseQualityName(quality)); | |
625 | + | |
626 | + var selected = self.qualityMenuContent.querySelector('.vjs-selected'); | |
627 | + if(selected) { | |
628 | + videojs.Youtube.removeClass(selected, 'vjs-selected'); | |
629 | + } | |
630 | + | |
631 | + videojs.Youtube.addClass(this, 'vjs-selected'); | |
632 | + }); | |
633 | + } | |
634 | + | |
635 | + var qualities = this.ytplayer.getAvailableQualityLevels(); | |
636 | + var self = this; | |
637 | + | |
638 | + if(qualities.indexOf(this.userQuality) < 0) { | |
639 | + setInnerText(self.qualityTitle, videojs.Youtube.parseQualityName(this.defaultQuality)); | |
640 | + } | |
641 | + | |
642 | + if(qualities.length === 0) { | |
643 | + this.qualityButton.style.display = 'none'; | |
644 | + } else { | |
645 | + this.qualityButton.style.display = ''; | |
646 | + | |
647 | + while(this.qualityMenuContent.hasChildNodes()) { | |
648 | + this.qualityMenuContent.removeChild(this.qualityMenuContent.lastChild); | |
649 | + } | |
650 | + | |
651 | + for(var i = 0; i < qualities.length; ++i) { | |
652 | + var el = document.createElement('li'); | |
653 | + el.setAttribute('class', 'vjs-menu-item'); | |
654 | + setInnerText(el, videojs.Youtube.parseQualityName(qualities[i])); | |
655 | + el.setAttribute('data-val', qualities[i]); | |
656 | + if(qualities[i] === this.quality) { | |
657 | + videojs.Youtube.addClass(el, 'vjs-selected'); | |
658 | + } | |
659 | + setupEventListener(el); | |
660 | + | |
661 | + | |
662 | + this.qualityMenuContent.appendChild(el); | |
663 | + } | |
664 | + } | |
665 | + }; | |
666 | + | |
667 | + videojs.Youtube.prototype.onStateChange = function(state) { | |
668 | + if(state !== this.lastState) { | |
669 | + switch(state) { | |
670 | + case -1: | |
671 | + this.player_.trigger('durationchange'); | |
672 | + break; | |
673 | + | |
674 | + case YT.PlayerState.ENDED: | |
675 | + // Replace YouTube play button by our own | |
676 | + if(!this.player_.options()['ytcontrols']) { | |
677 | + this.playerEl_.querySelectorAll('.vjs-poster')[0].style.display = 'block'; | |
678 | + if(typeof this.player_.bigPlayButton !== 'undefined') { | |
679 | + this.player_.bigPlayButton.show(); | |
680 | + } | |
681 | + } | |
682 | + | |
683 | + this.player_.trigger('ended'); | |
684 | + break; | |
685 | + | |
686 | + case YT.PlayerState.PLAYING: | |
687 | + this.playerEl_.querySelectorAll('.vjs-poster')[0].style.display = ''; | |
688 | + | |
689 | + this.playVideoIsAllowed = true; | |
690 | + this.updateQualities(); | |
691 | + this.player_.trigger('timeupdate'); | |
692 | + this.player_.trigger('durationchange'); | |
693 | + this.player_.trigger('playing'); | |
694 | + this.player_.trigger('play'); | |
695 | + | |
696 | + if (this.isSeeking) { | |
697 | + this.player_.trigger('seeked'); | |
698 | + this.isSeeking = false; | |
699 | + } | |
700 | + break; | |
701 | + | |
702 | + case YT.PlayerState.PAUSED: | |
703 | + this.player_.trigger('pause'); | |
704 | + break; | |
705 | + | |
706 | + case YT.PlayerState.BUFFERING: | |
707 | + this.player_.trigger('timeupdate'); | |
708 | + | |
709 | + // Make sure to not display the spinner for mobile | |
710 | + if(!this.player_.options()['ytcontrols']) { | |
711 | + this.player_.trigger('waiting'); | |
712 | + } | |
713 | + break; | |
714 | + | |
715 | + case YT.PlayerState.CUED: | |
716 | + break; | |
717 | + } | |
718 | + | |
719 | + this.lastState = state; | |
720 | + } | |
721 | + }; | |
722 | + | |
723 | + videojs.Youtube.convertQualityName = function(name) { | |
724 | + switch(name) { | |
725 | + case '144p': | |
726 | + return 'tiny'; | |
727 | + | |
728 | + case '240p': | |
729 | + return 'small'; | |
730 | + | |
731 | + case '360p': | |
732 | + return 'medium'; | |
733 | + | |
734 | + case '480p': | |
735 | + return 'large'; | |
736 | + | |
737 | + case '720p': | |
738 | + return 'hd720'; | |
739 | + | |
740 | + case '1080p': | |
741 | + return 'hd1080'; | |
742 | + } | |
743 | + | |
744 | + return 'auto'; | |
745 | + }; | |
746 | + | |
747 | + videojs.Youtube.parseQualityName = function(name) { | |
748 | + switch(name) { | |
749 | + case 'tiny': | |
750 | + return '144p'; | |
751 | + | |
752 | + case 'small': | |
753 | + return '240p'; | |
754 | + | |
755 | + case 'medium': | |
756 | + return '360p'; | |
757 | + | |
758 | + case 'large': | |
759 | + return '480p'; | |
760 | + | |
761 | + case 'hd720': | |
762 | + return '720p'; | |
763 | + | |
764 | + case 'hd1080': | |
765 | + return '1080p'; | |
766 | + } | |
767 | + | |
768 | + return 'auto'; | |
769 | + }; | |
770 | + | |
771 | + videojs.Youtube.prototype.onPlaybackQualityChange = function(quality) { | |
772 | + if(typeof this.defaultQuality === 'undefined') { | |
773 | + this.defaultQuality = quality; | |
774 | + | |
775 | + if(typeof this.userQuality !== 'undefined') { | |
776 | + return; | |
777 | + } | |
778 | + } | |
779 | + | |
780 | + this.quality = quality; | |
781 | + setInnerText(this.qualityTitle, videojs.Youtube.parseQualityName(quality)); | |
782 | + | |
783 | + switch(quality) { | |
784 | + case 'medium': | |
785 | + this.player_.videoWidth = 480; | |
786 | + this.player_.videoHeight = 360; | |
787 | + break; | |
788 | + | |
789 | + case 'large': | |
790 | + this.player_.videoWidth = 640; | |
791 | + this.player_.videoHeight = 480; | |
792 | + break; | |
793 | + | |
794 | + case 'hd720': | |
795 | + this.player_.videoWidth = 960; | |
796 | + this.player_.videoHeight = 720; | |
797 | + break; | |
798 | + | |
799 | + case 'hd1080': | |
800 | + this.player_.videoWidth = 1440; | |
801 | + this.player_.videoHeight = 1080; | |
802 | + break; | |
803 | + | |
804 | + case 'highres': | |
805 | + this.player_.videoWidth = 1920; | |
806 | + this.player_.videoHeight = 1080; | |
807 | + break; | |
808 | + | |
809 | + case 'small': | |
810 | + this.player_.videoWidth = 320; | |
811 | + this.player_.videoHeight = 240; | |
812 | + break; | |
813 | + | |
814 | + case 'tiny': | |
815 | + this.player_.videoWidth = 144; | |
816 | + this.player_.videoHeight = 108; | |
817 | + break; | |
818 | + | |
819 | + default: | |
820 | + this.player_.videoWidth = 0; | |
821 | + this.player_.videoHeight = 0; | |
822 | + break; | |
823 | + } | |
824 | + | |
825 | + this.player_.trigger('ratechange'); | |
826 | + }; | |
827 | + | |
828 | + videojs.Youtube.prototype.onError = function(error) { | |
829 | + this.player_.error(error); | |
830 | + | |
831 | + if(error === 100 || error === 101 || error === 150) { | |
832 | + this.player_.bigPlayButton.hide(); | |
833 | + this.player_.loadingSpinner.hide(); | |
834 | + this.player_.posterImage.hide(); | |
835 | + } | |
836 | + }; | |
837 | + | |
838 | + /** | |
839 | + * Add a CSS class name to an element | |
840 | + * @param {Element} element Element to add class name to | |
841 | + * @param {String} classToAdd Classname to add | |
842 | + */ | |
843 | + videojs.Youtube.addClass = function(element, classToAdd) { | |
844 | + if((' ' + element.className + ' ').indexOf(' ' + classToAdd + ' ') === -1) { | |
845 | + element.className = element.className === '' ? classToAdd : element.className + ' ' + classToAdd; | |
846 | + } | |
847 | + }; | |
848 | + | |
849 | + /** | |
850 | + * Remove a CSS class name from an element | |
851 | + * @param {Element} element Element to remove from class name | |
852 | + * @param {String} classToRemove Classname to remove | |
853 | + */ | |
854 | + videojs.Youtube.removeClass = function(element, classToRemove) { | |
855 | + var classNames, i; | |
856 | + | |
857 | + if(element.className.indexOf(classToRemove) === -1) { | |
858 | + return; | |
859 | + } | |
860 | + | |
861 | + classNames = element.className.split(' '); | |
862 | + | |
863 | + // no arr.indexOf in ie8, and we don't want to add a big shim | |
864 | + for(i = classNames.length - 1; i >= 0; i--) { | |
865 | + if(classNames[i] === classToRemove) { | |
866 | + classNames.splice(i, 1); | |
867 | + } | |
868 | + } | |
869 | + | |
870 | + element.className = classNames.join(' '); | |
871 | + }; | |
872 | + | |
873 | + // Cross-browsers support (IE8 wink wink) | |
874 | + function setInnerText(element, text) { | |
875 | + if(typeof element === 'undefined') { | |
876 | + return false; | |
877 | + } | |
878 | + | |
879 | + var textProperty = ('innerText' in element) ? 'innerText' : 'textContent'; | |
880 | + | |
881 | + try { | |
882 | + element[textProperty] = text; | |
883 | + } catch(anException) { | |
884 | + //IE<9 FIX | |
885 | + element.setAttribute('innerText', text); | |
886 | + } | |
887 | + } | |
888 | + | |
889 | + | |
890 | +// Stretch the YouTube poster | |
891 | + var style = document.createElement('style'); | |
892 | + var def = ' ' + | |
893 | + '.vjs-youtube .vjs-poster { background-size: 100%!important; }' + | |
894 | + '.vjs-youtube .vjs-poster, ' + | |
895 | + '.vjs-youtube .vjs-loading-spinner, ' + | |
896 | + '.vjs-youtube .vjs-big-play-button, .vjs-youtube .vjs-text-track-display{ pointer-events: none !important; }' + | |
897 | + '.vjs-youtube.vjs-user-active .iframeblocker { display: none; }' + | |
898 | + '.vjs-youtube.vjs-user-inactive .vjs-tech.onDesktop { pointer-events: none; }' + | |
899 | + '.vjs-quality-button > div:first-child > span:first-child { position:relative;top:7px }'; | |
900 | + | |
901 | + style.setAttribute('type', 'text/css'); | |
902 | + document.getElementsByTagName('head')[0].appendChild(style); | |
903 | + | |
904 | + if(style.styleSheet) { | |
905 | + style.styleSheet.cssText = def; | |
906 | + } else { | |
907 | + style.appendChild(document.createTextNode(def)); | |
908 | + } | |
909 | + | |
910 | + // IE8 fix for indexOf | |
911 | + if(!Array.prototype.indexOf) { | |
912 | + Array.prototype.indexOf = function(elt /*, from*/) { | |
913 | + var len = this.length >>> 0; // jshint ignore:line | |
914 | + | |
915 | + var from = Number(arguments[1]) || 0; | |
916 | + from = (from < 0) ? | |
917 | + Math.ceil(from) | |
918 | + : Math.floor(from); | |
919 | + if(from < 0) { | |
920 | + from += len; | |
921 | + } | |
922 | + | |
923 | + for(; from < len; from++) { | |
924 | + if(from in this && this[from] === elt) { | |
925 | + return from; | |
926 | + } | |
927 | + } | |
928 | + return -1; | |
929 | + }; | |
930 | + } | |
931 | +})(); | ... | ... |
plugins/video/public/style.css
... | ... | @@ -38,5 +38,23 @@ |
38 | 38 | } |
39 | 39 | |
40 | 40 | .video-gallery-thumbnail:hover div{ |
41 | - display: inline-block; | |
41 | + display: inline-block; | |
42 | +} | |
43 | + | |
44 | +.video-gallery-table-big{ | |
45 | + width: 100%; | |
46 | + overflow: hidden; | |
47 | +} | |
48 | + | |
49 | +.video-gallery-left-column-big{ | |
50 | + width: 350px; | |
51 | + float: left; | |
52 | +} | |
53 | + | |
54 | +.video-gallery-right-column-big{ | |
55 | + margin-left: 370px; | |
56 | +} | |
57 | + | |
58 | +.video-title-big{ | |
59 | + font-size: 2em; | |
42 | 60 | } |
43 | 61 | \ No newline at end of file | ... | ... |
plugins/video/views/content_viewer/video_plugin/_video.html.erb
1 | 1 | <div align="center"> |
2 | 2 | <%if @page.video_provider=='youtube' %> |
3 | 3 | <link type="text/css" rel="stylesheet" href="/plugins/video/css/video-js-4.5.1.css" /> |
4 | - <video id="embedded_video" src="" class="video-js vjs-default-skin vjs-big-play-centered" controls preload="auto" | |
4 | + <video id="embedded_video<%= rand %>" src="" class="video-js vjs-default-skin vjs-big-play-centered" controls preload="auto" | |
5 | 5 | width="<%= @page.fitted_width %>" height="<%= @page.fitted_height %>" |
6 | 6 | data-setup='<%=CGI::escapeHTML("{ \"techOrder\": [\"youtube\"], \"src\": \"#{@page.video_url}\" }") %>'> |
7 | 7 | <%= @page.no_browser_support_message %> |
... | ... | @@ -10,7 +10,7 @@ |
10 | 10 | <script src="/plugins/video/javascripts/videojs/vjs.youtube.js"></script> |
11 | 11 | <% elsif @page.video_provider=='vimeo' %> |
12 | 12 | <link type="text/css" rel="stylesheet" href="/plugins/video/css/video-js-4.5.1.css" /> |
13 | - <video id="embedded_video" src="" class="video-js vjs-default-skin vjs-big-play-centered" controls preload="auto" | |
13 | + <video id="embedded_video<%= rand %>" src="" class="video-js vjs-default-skin vjs-big-play-centered" controls preload="auto" | |
14 | 14 | width="<%= @page.fitted_width %>" height="<%= @page.fitted_height %>" |
15 | 15 | data-setup='<%=CGI::escapeHTML("{ \"techOrder\": [\"vimeo\"], \"src\": \"#{@page.video_url}\", \"loop\": true, \"autoplay\": false }") %>'> |
16 | 16 | <%= @page.no_browser_support_message %> |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | <% elsif @page.video_provider=='file' %> |
21 | 21 | <link href="/plugins/video/css/video-js-4.8.5.css" rel="stylesheet"> |
22 | 22 | <script src="/plugins/video/javascripts/videojs/video-4.8.5.js"></script> |
23 | - <video id="embedded_video" class="video-js vjs-default-skin vjs-big-play-centered" | |
23 | + <video id="embedded_video<%= rand %>" class="video-js vjs-default-skin vjs-big-play-centered" | |
24 | 24 | height="353" width="499" |
25 | 25 | controls preload="auto" |
26 | 26 | data-setup='<%=CGI::escapeHTML("{ \"example_option\":true}") %>'> | ... | ... |
plugins/video/views/content_viewer/video_plugin/video_video.html.erb
... | ... | @@ -1,34 +0,0 @@ |
1 | -<div align="center"> | |
2 | -<%if @page.video_provider=='youtube' %> | |
3 | - <link type="text/css" rel="stylesheet" href="https://vjs.zencdn.net/4.5.1/video-js.css" /> | |
4 | - <video id="embedded_video" src="" class="video-js vjs-default-skin vjs-big-play-centered" controls preload="auto" | |
5 | - width="<%= @page.fitted_width %>" height="<%= @page.fitted_height %>" | |
6 | - data-setup='{ "techOrder": ["youtube"], "src": "<%= @page.video_url %>" }'> | |
7 | - <%= @page.no_browser_support_message %> | |
8 | - </video> | |
9 | - <script src="https://vjs.zencdn.net/4.5.1/video.js"></script> | |
10 | - <script src="/plugins/video/javascripts/videojs/vjs.youtube.js"></script> | |
11 | - <% elsif @page.video_provider=='vimeo' %> | |
12 | - <link type="text/css" rel="stylesheet" href="https://vjs.zencdn.net/4.5.1/video-js.css" /> | |
13 | - <video id="embedded_video" src="" class="video-js vjs-default-skin vjs-big-play-centered" controls preload="auto" | |
14 | - width="<%= @page.fitted_width %>" height="<%= @page.fitted_height %>" | |
15 | - data-setup='{ "techOrder": ["vimeo"], "src": "<%= @page.video_url %>", "loop": true, "autoplay": false }'> | |
16 | - <%= @page.no_browser_support_message %> | |
17 | - </video> | |
18 | - <script src="https://vjs.zencdn.net/4.5.1/video.js"></script> | |
19 | - <script src="/plugins/video/javascripts/videojs/vjs.vimeo.js"></script> | |
20 | -<% elsif @page.video_provider=='file' %> | |
21 | - <link href="https://vjs.zencdn.net/4.8/video-js.css" rel="stylesheet"> | |
22 | - <script src="https://vjs.zencdn.net/4.8/video.js"></script> | |
23 | - <video id="embedded_video" class="video-js vjs-default-skin vjs-big-play-centered" | |
24 | - height="353" width="499" | |
25 | - controls preload="auto" | |
26 | - data-setup='{"example_option":true}'> | |
27 | - <source src="<%= @page.video_url %>" type='<%= @page.video_format %>' /> | |
28 | - <%= @page.no_browser_support_message %> | |
29 | - </video> | |
30 | -<% end %> | |
31 | -<br style="clear:both" /> | |
32 | -</div> | |
33 | -<% _("Description:") %> | |
34 | -<%= @page.body %> | |
35 | 0 | \ No newline at end of file |
plugins/video/views/content_viewer/video_plugin/video_video_gallery.html.erb
... | ... | @@ -1,28 +0,0 @@ |
1 | -<% | |
2 | -def self.list_videos(configure={}) | |
3 | - configure[:recursive] ||= false | |
4 | - configure[:list_type] ||= :folder | |
5 | - if !configure[:contents].blank? | |
6 | - configure[:contents] = configure[:contents].paginate( | |
7 | - :order => "updated_at DESC", | |
8 | - :per_page => 16, | |
9 | - :page => params[:npage] | |
10 | - ) | |
11 | - render :file => 'shared/video_list', :locals => configure | |
12 | - else | |
13 | - content_tag('em', _('(empty folder)')) | |
14 | - end | |
15 | - end | |
16 | -%> | |
17 | -<% unless video_gallery.body.blank? %> | |
18 | - <div> | |
19 | - <%= video_gallery.body %> | |
20 | - </div> | |
21 | - <hr/> | |
22 | -<% end %> | |
23 | - | |
24 | -<% if video_gallery.children.empty? %> | |
25 | - <em><%= _('(empty video gallery)') %></em> | |
26 | -<% else %> | |
27 | - <%= list_videos(:contents=>video_gallery.children) %> | |
28 | -<% end %> | |
29 | 0 | \ No newline at end of file |
plugins/video/views/shared/video_list.html.erb
1 | 1 | <div> |
2 | - <% contents.each do |content| %> | |
2 | + <% | |
3 | + first_video = contents[0] | |
4 | + first_video_arr = Array.new | |
5 | + first_video_arr.push(first_video) | |
6 | + other_videos = contents - first_video_arr %> | |
7 | + <% if first_video.display_to?(user) %> | |
8 | + <div class="video-gallery-table-big"> | |
9 | + <div class="video-gallery-left-column-big"> | |
10 | + <%= link_to first_video.view_url do %> | |
11 | + <img width="320" height="320" src='<%= first_video.video_thumbnail_url %>' class="disable-zoom"/> | |
12 | + <% end %> | |
13 | + </div> | |
14 | + <div class="video-gallery-right-column-big"> | |
15 | + <div class="video-title-big"><%= first_video.title %></div> | |
16 | + <div class="video-author-big"> | |
17 | + <%= _("by") %> <%= first_video.author_name %> <%= _("updated at") %> <%= time_ago_as_sentence(first_video.updated_at) %> | |
18 | + </div> | |
19 | + </div> | |
20 | + </div> | |
21 | + <% end %> | |
22 | + <% other_videos.each do |content| %> | |
3 | 23 | <% if content.display_to?(user) %> |
4 | 24 | <div class="video-gallery-thumbnail"> |
5 | 25 | <div class="video-gallery-top-box"> |
6 | 26 | <%= link_to content.view_url do %> |
7 | - <img width="<%= content.thumbnail_fitted_width %>" height="<%= content.thumbnail_fitted_width %>" src='<%= content.video_thumbnail_url %>' class="disable-zoom"/> | |
27 | + <img width="<%= content.thumbnail_fitted_width %>" height="<%= content.thumbnail_fitted_height %>" src='<%= content.video_thumbnail_url %>' class="disable-zoom"/> | |
8 | 28 | <% end %> |
9 | 29 | </div> |
10 | 30 | <div class="video-gallery-botton-box"> | ... | ... |
plugins/video/views/shared/video_plugin/apagar_video_block.html.erb
0 → 100644
... | ... | @@ -0,0 +1,21 @@ |
1 | +<h3 class="block-title"> | |
2 | + <span><%=block.title%></span> | |
3 | +</h3> | |
4 | +<div class="video-block-data"> | |
5 | + <% if block.is_youtube? %> | |
6 | + <div class='youtube'> | |
7 | + <%= render :partial => 'box_organizer/iframe_video_block', :locals => { :url => block.format_embed_video_url_for_youtube, :width => block.width, :height => block.height }%> | |
8 | + </div> | |
9 | + <% elsif block.is_vimeo? %> | |
10 | + <div class='vimeo'> | |
11 | + <%= render :partial => 'box_organizer/iframe_video_block', :locals => { :url => block.format_embed_video_url_for_vimeo, :width => block.width, :height => block.height }%> | |
12 | + </div> | |
13 | + <% elsif block.is_video_file? %> | |
14 | + <div class='video'> | |
15 | + <%= render :partial => 'box_organizer/html5_video_block', :locals => { :url => block.url, :width => block.width, :height => block.height }%> | |
16 | + </div> | |
17 | + <% else %> | |
18 | + <span class='alert-block'><%= _("Register a valid url (Vimeo, Youtube, video files)") %></span> | |
19 | + <% end %> | |
20 | + | |
21 | +</div> | ... | ... |
plugins/video/views/shared/video_plugin/video_block.html.erb
... | ... | @@ -1,21 +0,0 @@ |
1 | -<h3 class="block-title"> | |
2 | - <span><%=block.title%></span> | |
3 | -</h3> | |
4 | -<div class="video-block-data"> | |
5 | - <% if block.is_youtube? %> | |
6 | - <div class='youtube'> | |
7 | - <%= render :partial => 'box_organizer/iframe_video_block', :locals => { :url => block.format_embed_video_url_for_youtube, :width => block.width, :height => block.height }%> | |
8 | - </div> | |
9 | - <% elsif block.is_vimeo? %> | |
10 | - <div class='vimeo'> | |
11 | - <%= render :partial => 'box_organizer/iframe_video_block', :locals => { :url => block.format_embed_video_url_for_vimeo, :width => block.width, :height => block.height }%> | |
12 | - </div> | |
13 | - <% elsif block.is_video_file? %> | |
14 | - <div class='video'> | |
15 | - <%= render :partial => 'box_organizer/html5_video_block', :locals => { :url => block.url, :width => block.width, :height => block.height }%> | |
16 | - </div> | |
17 | - <% else %> | |
18 | - <span class='alert-block'><%= _("Register a valid url (Vimeo, Youtube, video files)") %></span> | |
19 | - <% end %> | |
20 | - | |
21 | -</div> |