Loading vendor/videojs/plugins/videojs-youtube.js +55 −175 Original line number Diff line number Diff line Loading @@ -21,26 +21,23 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*global define, YT*/ (function (root, factory) { if(typeof exports==='object' && typeof module!=='undefined') { module.exports = factory(require('video.js')); } else if(typeof define === 'function' && define.amd) { define(['videojs'], function(videojs){ if(typeof define === 'function' && define.amd) { define(['video.js'], function(videojs){ return (root.Youtube = factory(videojs)); }); } else if(typeof module === 'object' && module.exports) { module.exports = (root.Youtube = factory(require('video.js'))); } else { root.Youtube = factory(root.videojs); } }(this, function(videojs) { 'use strict'; var _isOnMobile = videojs.browser.IS_IOS || videojs.browser.IS_ANDROID; var Tech = videojs.getTech('Tech'); var Tech = videojs.getComponent('Tech'); var Youtube = videojs.extend(Tech, { constructor: function(options, ready) { loadScript('https://www.youtube.com/iframe_api', apiLoaded); Tech.call(this, options, ready); this.setPoster(options.poster); Loading @@ -48,8 +45,7 @@ THE SOFTWARE. */ // Set the vjs-youtube class to the player // Parent is not set yet so we have to wait a tick this.setTimeout(function() { if (this.el_) { setTimeout(function() { this.el_.parentNode.className += ' vjs-youtube'; if (_isOnMobile) { Loading @@ -61,42 +57,19 @@ THE SOFTWARE. */ } else { Youtube.apiReadyQueue.push(this); } } }.bind(this)); }, dispose: function() { if (this.ytPlayer) { //Dispose of the YouTube Player if (this.ytPlayer.stopVideo) { this.ytPlayer.stopVideo(); } if (this.ytPlayer.destroy) { this.ytPlayer.destroy(); } } else { //YouTube API hasn't finished loading or the player is already disposed var index = Youtube.apiReadyQueue.indexOf(this); if (index !== -1) { Youtube.apiReadyQueue.splice(index, 1); } } this.ytPlayer = null; this.el_.parentNode.className = this.el_.parentNode.className .replace(' vjs-youtube', '') .replace(' vjs-youtube-mobile', ''); this.el_.parentNode.removeChild(this.el_); //Needs to be called after the YouTube player is destroyed, otherwise there will be a null reference exception Tech.prototype.dispose.call(this); }, createEl: function() { var div = document.createElement('div'); div.setAttribute('id', this.options_.techId); div.setAttribute('style', 'width:100%;height:100%;top:0;left:0;position:absolute'); div.setAttribute('class', 'vjs-tech'); var divWrapper = document.createElement('div'); divWrapper.appendChild(div); Loading Loading @@ -215,14 +188,6 @@ THE SOFTWARE. */ playerVars.theme = this.options_.theme; } // Allow undocumented options to be passed along via customVars if (typeof this.options_.customVars !== 'undefined') { var customVars = this.options_.customVars; Object.keys(customVars).forEach(function(key) { playerVars[key] = customVars[key]; }); } this.activeVideoId = this.url ? this.url.videoId : null; this.activeList = playerVars.list; Loading @@ -232,32 +197,18 @@ THE SOFTWARE. */ events: { onReady: this.onPlayerReady.bind(this), onPlaybackQualityChange: this.onPlayerPlaybackQualityChange.bind(this), onPlaybackRateChange: this.onPlayerPlaybackRateChange.bind(this), onStateChange: this.onPlayerStateChange.bind(this), onVolumeChange: this.onPlayerVolumeChange.bind(this), onError: this.onPlayerError.bind(this) } }); }, onPlayerReady: function() { if (this.options_.muted) { this.ytPlayer.mute(); } var playbackRates = this.ytPlayer.getAvailablePlaybackRates(); if (playbackRates.length > 1) { this.featuresPlaybackRate = true; } this.playerReady_ = true; this.triggerReady(); if (this.playOnReady) { this.play(); } else if (this.cueOnReady) { this.cueVideoById_(this.url.videoId); this.activeVideoId = this.url.videoId; } }, Loading @@ -265,10 +216,6 @@ THE SOFTWARE. */ }, onPlayerPlaybackRateChange: function() { this.trigger('ratechange'); }, onPlayerStateChange: function(e) { var state = e.data; Loading @@ -276,14 +223,10 @@ THE SOFTWARE. */ return; } this.lastState = state; switch (state) { case -1: this.trigger('loadstart'); this.trigger('loadedmetadata'); this.trigger('durationchange'); this.trigger('ratechange'); break; case YT.PlayerState.ENDED: Loading Loading @@ -315,68 +258,43 @@ THE SOFTWARE. */ this.player_.trigger('waiting'); break; } }, onPlayerVolumeChange: function() { this.trigger('volumechange'); this.lastState = state; }, onPlayerError: function(e) { this.errorNumber = e.data; this.trigger('pause'); this.trigger('error'); this.ytPlayer.stopVideo(); this.ytPlayer.destroy(); this.ytPlayer = null; }, error: function() { var code = 1000 + this.errorNumber; // as smaller codes are reserved switch (this.errorNumber) { case 5: return { code: code, message: 'Error while trying to play the video' }; return { code: 'Error while trying to play the video' }; case 2: case 100: return { code: code, message: 'Unable to find the video' }; case 101: case 150: return { code: code, message: 'Playback on other Websites has been disabled by the video owner.' }; } return { code: code, message: 'YouTube unknown error (' + this.errorNumber + ')' }; }, return { code: 'Unable to find the video' }; loadVideoById_: function(id) { var options = { videoId: id }; if (this.options_.start) { options.startSeconds = this.options_.start; } if (this.options_.end) { options.endEnd = this.options_.end; case 101: return { code: 'Playback on other Websites has been disabled by the video owner.' }; } this.ytPlayer.loadVideoById(options); }, cueVideoById_: function(id) { var options = { videoId: id }; if (this.options_.start) { options.startSeconds = this.options_.start; } if (this.options_.end) { options.endEnd = this.options_.end; } this.ytPlayer.cueVideoById(options); return { code: 'YouTube unknown error (' + this.errorNumber + ')' }; }, src: function(src) { if (src) { this.setSrc({ src: src }); if (this.options_.autoplay && !_isOnMobile) { this.play(); } } return this.source; Loading Loading @@ -409,7 +327,6 @@ THE SOFTWARE. */ if (this.url.videoId) { // Set the low resolution first this.poster_ = 'https://img.youtube.com/vi/' + this.url.videoId + '/0.jpg'; this.trigger('posterchange'); // Check if their is a high res this.checkHighResPoster(); Loading @@ -422,32 +339,9 @@ THE SOFTWARE. */ } else { this.playOnReady = true; } } else if (this.activeVideoId !== this.url.videoId) { if (this.isReady_) { this.cueVideoById_(this.url.videoId); this.activeVideoId = this.url.videoId; } else { this.cueOnReady = true; } } }, autoplay: function() { return this.options_.autoplay; }, setAutoplay: function(val) { this.options_.autoplay = val; }, loop: function() { return this.options_.loop; }, setLoop: function(val) { this.options_.loop = val; }, play: function() { if (!this.url || !this.url.videoId) { return; Loading @@ -468,7 +362,7 @@ THE SOFTWARE. */ if (this.activeVideoId === this.url.videoId) { this.ytPlayer.playVideo(); } else { this.loadVideoById_(this.url.videoId); this.ytPlayer.loadVideoById(this.url.videoId); this.activeVideoId = this.url.videoId; } } else { Loading Loading @@ -524,18 +418,6 @@ THE SOFTWARE. */ } }, seeking: function () { return this.isSeeking; }, seekable: function () { if(!this.ytPlayer) { return videojs.createTimeRange(); } return videojs.createTimeRange(0, this.ytPlayer.getDuration()); }, onSeeked: function() { clearInterval(this.checkSeekedInPauseInterval); this.isSeeking = false; Loading @@ -557,6 +439,7 @@ THE SOFTWARE. */ } this.ytPlayer.setPlaybackRate(suggestedRate); this.trigger('ratechange'); }, duration: function() { Loading @@ -564,7 +447,7 @@ THE SOFTWARE. */ }, currentSrc: function() { return this.source && this.source.src; return this.source; }, ended: function() { Loading @@ -581,6 +464,10 @@ THE SOFTWARE. */ } this.ytPlayer.setVolume(percentAsDecimal * 100.0); this.setTimeout( function(){ this.trigger('volumechange'); }, 50); }, muted: function() { Loading @@ -607,16 +494,27 @@ THE SOFTWARE. */ buffered: function() { if(!this.ytPlayer || !this.ytPlayer.getVideoLoadedFraction) { return videojs.createTimeRange(); return { length: 0, start: function() { throw new Error('This TimeRanges object is empty'); }, end: function() { throw new Error('This TimeRanges object is empty'); } }; } var bufferedEnd = this.ytPlayer.getVideoLoadedFraction() * this.ytPlayer.getDuration(); var end = this.ytPlayer.getVideoLoadedFraction() * this.ytPlayer.getDuration(); return videojs.createTimeRange(0, bufferedEnd); return { length: this.ytPlayer.getDuration(), start: function() { return 0; }, end: function() { return end; } }; }, // TODO: Can we really do something with this on YouTUbe? preload: function() {}, load: function() {}, reset: function() {}, Loading Loading @@ -655,12 +553,10 @@ THE SOFTWARE. */ }; Youtube.canPlaySource = function(e) { return Youtube.canPlayType(e.type); return (e.type === 'video/youtube'); }; Youtube.canPlayType = function(e) { return (e === 'video/youtube'); }; var _isOnMobile = /(iPad|iPhone|iPod|Android)/g.test(navigator.userAgent); Youtube.parseUrl = function(url) { var result = { Loading @@ -684,34 +580,11 @@ THE SOFTWARE. */ return result; }; function apiLoaded() { YT.ready(function() { Youtube.isApiReady = true; for (var i = 0; i < Youtube.apiReadyQueue.length; ++i) { Youtube.apiReadyQueue[i].initYTPlayer(); } }); } function loadScript(src, callback) { var loaded = false; function loadApi() { var tag = document.createElement('script'); tag.src = 'https://www.youtube.com/iframe_api'; var firstScriptTag = document.getElementsByTagName('script')[0]; firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); tag.onload = function () { if (!loaded) { loaded = true; callback(); } }; tag.onreadystatechange = function () { if (!loaded && (this.readyState === 'complete' || this.readyState === 'loaded')) { loaded = true; callback(); } }; tag.src = src; } function injectCss() { Loading @@ -737,9 +610,16 @@ THE SOFTWARE. */ Youtube.apiReadyQueue = []; if (typeof document !== 'undefined'){ injectCss(); window.onYouTubeIframeAPIReady = function() { Youtube.isApiReady = true; for (var i = 0; i < Youtube.apiReadyQueue.length; ++i) { Youtube.apiReadyQueue[i].initYTPlayer(); } }; loadApi(); injectCss(); // Older versions of VJS5 doesn't have the registerTech function if (typeof videojs.registerTech !== 'undefined') { Loading Loading
vendor/videojs/plugins/videojs-youtube.js +55 −175 Original line number Diff line number Diff line Loading @@ -21,26 +21,23 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*global define, YT*/ (function (root, factory) { if(typeof exports==='object' && typeof module!=='undefined') { module.exports = factory(require('video.js')); } else if(typeof define === 'function' && define.amd) { define(['videojs'], function(videojs){ if(typeof define === 'function' && define.amd) { define(['video.js'], function(videojs){ return (root.Youtube = factory(videojs)); }); } else if(typeof module === 'object' && module.exports) { module.exports = (root.Youtube = factory(require('video.js'))); } else { root.Youtube = factory(root.videojs); } }(this, function(videojs) { 'use strict'; var _isOnMobile = videojs.browser.IS_IOS || videojs.browser.IS_ANDROID; var Tech = videojs.getTech('Tech'); var Tech = videojs.getComponent('Tech'); var Youtube = videojs.extend(Tech, { constructor: function(options, ready) { loadScript('https://www.youtube.com/iframe_api', apiLoaded); Tech.call(this, options, ready); this.setPoster(options.poster); Loading @@ -48,8 +45,7 @@ THE SOFTWARE. */ // Set the vjs-youtube class to the player // Parent is not set yet so we have to wait a tick this.setTimeout(function() { if (this.el_) { setTimeout(function() { this.el_.parentNode.className += ' vjs-youtube'; if (_isOnMobile) { Loading @@ -61,42 +57,19 @@ THE SOFTWARE. */ } else { Youtube.apiReadyQueue.push(this); } } }.bind(this)); }, dispose: function() { if (this.ytPlayer) { //Dispose of the YouTube Player if (this.ytPlayer.stopVideo) { this.ytPlayer.stopVideo(); } if (this.ytPlayer.destroy) { this.ytPlayer.destroy(); } } else { //YouTube API hasn't finished loading or the player is already disposed var index = Youtube.apiReadyQueue.indexOf(this); if (index !== -1) { Youtube.apiReadyQueue.splice(index, 1); } } this.ytPlayer = null; this.el_.parentNode.className = this.el_.parentNode.className .replace(' vjs-youtube', '') .replace(' vjs-youtube-mobile', ''); this.el_.parentNode.removeChild(this.el_); //Needs to be called after the YouTube player is destroyed, otherwise there will be a null reference exception Tech.prototype.dispose.call(this); }, createEl: function() { var div = document.createElement('div'); div.setAttribute('id', this.options_.techId); div.setAttribute('style', 'width:100%;height:100%;top:0;left:0;position:absolute'); div.setAttribute('class', 'vjs-tech'); var divWrapper = document.createElement('div'); divWrapper.appendChild(div); Loading Loading @@ -215,14 +188,6 @@ THE SOFTWARE. */ playerVars.theme = this.options_.theme; } // Allow undocumented options to be passed along via customVars if (typeof this.options_.customVars !== 'undefined') { var customVars = this.options_.customVars; Object.keys(customVars).forEach(function(key) { playerVars[key] = customVars[key]; }); } this.activeVideoId = this.url ? this.url.videoId : null; this.activeList = playerVars.list; Loading @@ -232,32 +197,18 @@ THE SOFTWARE. */ events: { onReady: this.onPlayerReady.bind(this), onPlaybackQualityChange: this.onPlayerPlaybackQualityChange.bind(this), onPlaybackRateChange: this.onPlayerPlaybackRateChange.bind(this), onStateChange: this.onPlayerStateChange.bind(this), onVolumeChange: this.onPlayerVolumeChange.bind(this), onError: this.onPlayerError.bind(this) } }); }, onPlayerReady: function() { if (this.options_.muted) { this.ytPlayer.mute(); } var playbackRates = this.ytPlayer.getAvailablePlaybackRates(); if (playbackRates.length > 1) { this.featuresPlaybackRate = true; } this.playerReady_ = true; this.triggerReady(); if (this.playOnReady) { this.play(); } else if (this.cueOnReady) { this.cueVideoById_(this.url.videoId); this.activeVideoId = this.url.videoId; } }, Loading @@ -265,10 +216,6 @@ THE SOFTWARE. */ }, onPlayerPlaybackRateChange: function() { this.trigger('ratechange'); }, onPlayerStateChange: function(e) { var state = e.data; Loading @@ -276,14 +223,10 @@ THE SOFTWARE. */ return; } this.lastState = state; switch (state) { case -1: this.trigger('loadstart'); this.trigger('loadedmetadata'); this.trigger('durationchange'); this.trigger('ratechange'); break; case YT.PlayerState.ENDED: Loading Loading @@ -315,68 +258,43 @@ THE SOFTWARE. */ this.player_.trigger('waiting'); break; } }, onPlayerVolumeChange: function() { this.trigger('volumechange'); this.lastState = state; }, onPlayerError: function(e) { this.errorNumber = e.data; this.trigger('pause'); this.trigger('error'); this.ytPlayer.stopVideo(); this.ytPlayer.destroy(); this.ytPlayer = null; }, error: function() { var code = 1000 + this.errorNumber; // as smaller codes are reserved switch (this.errorNumber) { case 5: return { code: code, message: 'Error while trying to play the video' }; return { code: 'Error while trying to play the video' }; case 2: case 100: return { code: code, message: 'Unable to find the video' }; case 101: case 150: return { code: code, message: 'Playback on other Websites has been disabled by the video owner.' }; } return { code: code, message: 'YouTube unknown error (' + this.errorNumber + ')' }; }, return { code: 'Unable to find the video' }; loadVideoById_: function(id) { var options = { videoId: id }; if (this.options_.start) { options.startSeconds = this.options_.start; } if (this.options_.end) { options.endEnd = this.options_.end; case 101: return { code: 'Playback on other Websites has been disabled by the video owner.' }; } this.ytPlayer.loadVideoById(options); }, cueVideoById_: function(id) { var options = { videoId: id }; if (this.options_.start) { options.startSeconds = this.options_.start; } if (this.options_.end) { options.endEnd = this.options_.end; } this.ytPlayer.cueVideoById(options); return { code: 'YouTube unknown error (' + this.errorNumber + ')' }; }, src: function(src) { if (src) { this.setSrc({ src: src }); if (this.options_.autoplay && !_isOnMobile) { this.play(); } } return this.source; Loading Loading @@ -409,7 +327,6 @@ THE SOFTWARE. */ if (this.url.videoId) { // Set the low resolution first this.poster_ = 'https://img.youtube.com/vi/' + this.url.videoId + '/0.jpg'; this.trigger('posterchange'); // Check if their is a high res this.checkHighResPoster(); Loading @@ -422,32 +339,9 @@ THE SOFTWARE. */ } else { this.playOnReady = true; } } else if (this.activeVideoId !== this.url.videoId) { if (this.isReady_) { this.cueVideoById_(this.url.videoId); this.activeVideoId = this.url.videoId; } else { this.cueOnReady = true; } } }, autoplay: function() { return this.options_.autoplay; }, setAutoplay: function(val) { this.options_.autoplay = val; }, loop: function() { return this.options_.loop; }, setLoop: function(val) { this.options_.loop = val; }, play: function() { if (!this.url || !this.url.videoId) { return; Loading @@ -468,7 +362,7 @@ THE SOFTWARE. */ if (this.activeVideoId === this.url.videoId) { this.ytPlayer.playVideo(); } else { this.loadVideoById_(this.url.videoId); this.ytPlayer.loadVideoById(this.url.videoId); this.activeVideoId = this.url.videoId; } } else { Loading Loading @@ -524,18 +418,6 @@ THE SOFTWARE. */ } }, seeking: function () { return this.isSeeking; }, seekable: function () { if(!this.ytPlayer) { return videojs.createTimeRange(); } return videojs.createTimeRange(0, this.ytPlayer.getDuration()); }, onSeeked: function() { clearInterval(this.checkSeekedInPauseInterval); this.isSeeking = false; Loading @@ -557,6 +439,7 @@ THE SOFTWARE. */ } this.ytPlayer.setPlaybackRate(suggestedRate); this.trigger('ratechange'); }, duration: function() { Loading @@ -564,7 +447,7 @@ THE SOFTWARE. */ }, currentSrc: function() { return this.source && this.source.src; return this.source; }, ended: function() { Loading @@ -581,6 +464,10 @@ THE SOFTWARE. */ } this.ytPlayer.setVolume(percentAsDecimal * 100.0); this.setTimeout( function(){ this.trigger('volumechange'); }, 50); }, muted: function() { Loading @@ -607,16 +494,27 @@ THE SOFTWARE. */ buffered: function() { if(!this.ytPlayer || !this.ytPlayer.getVideoLoadedFraction) { return videojs.createTimeRange(); return { length: 0, start: function() { throw new Error('This TimeRanges object is empty'); }, end: function() { throw new Error('This TimeRanges object is empty'); } }; } var bufferedEnd = this.ytPlayer.getVideoLoadedFraction() * this.ytPlayer.getDuration(); var end = this.ytPlayer.getVideoLoadedFraction() * this.ytPlayer.getDuration(); return videojs.createTimeRange(0, bufferedEnd); return { length: this.ytPlayer.getDuration(), start: function() { return 0; }, end: function() { return end; } }; }, // TODO: Can we really do something with this on YouTUbe? preload: function() {}, load: function() {}, reset: function() {}, Loading Loading @@ -655,12 +553,10 @@ THE SOFTWARE. */ }; Youtube.canPlaySource = function(e) { return Youtube.canPlayType(e.type); return (e.type === 'video/youtube'); }; Youtube.canPlayType = function(e) { return (e === 'video/youtube'); }; var _isOnMobile = /(iPad|iPhone|iPod|Android)/g.test(navigator.userAgent); Youtube.parseUrl = function(url) { var result = { Loading @@ -684,34 +580,11 @@ THE SOFTWARE. */ return result; }; function apiLoaded() { YT.ready(function() { Youtube.isApiReady = true; for (var i = 0; i < Youtube.apiReadyQueue.length; ++i) { Youtube.apiReadyQueue[i].initYTPlayer(); } }); } function loadScript(src, callback) { var loaded = false; function loadApi() { var tag = document.createElement('script'); tag.src = 'https://www.youtube.com/iframe_api'; var firstScriptTag = document.getElementsByTagName('script')[0]; firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); tag.onload = function () { if (!loaded) { loaded = true; callback(); } }; tag.onreadystatechange = function () { if (!loaded && (this.readyState === 'complete' || this.readyState === 'loaded')) { loaded = true; callback(); } }; tag.src = src; } function injectCss() { Loading @@ -737,9 +610,16 @@ THE SOFTWARE. */ Youtube.apiReadyQueue = []; if (typeof document !== 'undefined'){ injectCss(); window.onYouTubeIframeAPIReady = function() { Youtube.isApiReady = true; for (var i = 0; i < Youtube.apiReadyQueue.length; ++i) { Youtube.apiReadyQueue[i].initYTPlayer(); } }; loadApi(); injectCss(); // Older versions of VJS5 doesn't have the registerTech function if (typeof videojs.registerTech !== 'undefined') { Loading