/** * @requires $ jQuery * @requires _ UnderscoreJS * @requires $.fn.required */ (function (/* Object */ ns) { 'use strict'; ns.YoutubeVideo = function (options) { this.iOS = qs.isIOS() !== false; this.android = qs.isAndroid(); this.player = undefined; this.options = { containerId: undefined, autoshow: true, videoContainerId: undefined, playButtonSelector: '.youtube-play-button', ratio: 16 / 9, maxHeight: 700, mute: false, /* Show video on iOS devices */ iOsSupport: true, /* Show video on Android devices */ androidSupport: true, player: { videoId: undefined, width: '100%', height: '100%', playerVars: { /** * https://developers.google.com/youtube/player_parameters?playerVersion=HTML5#Parameters */ iv_load_policy: 3, modestbranding: 1, start: 0, rel:1, loop: false, autoplay: 0, controls: 1, showinfo: 0, wmode: 'opaque', autohide: 0 } } }; $.extend(true, this.options, options); if (this.iOS) { this.options.autoshow = true; } this.container = $('#' + this.options.containerId); this.videoContainer = $('#' + this.options.videoContainerId); this.playButton = $(this.options.playButtonSelector); this.playButton.on('click', this.play.bind(this)); this.initHeight(); $(window).on('resize', _.bind(this.onResize, this)); if (this.iOS && !this.options.iOsSupport) { return; } if (this.android && !this.options.androidSupport) { return; } this.loadApi(); }; var proto = ns.YoutubeVideo.prototype; proto.loadApi = function () { window.onYouTubeIframeAPIReady = _.bind(function () { this.player = new YT.Player(this.options.videoContainerId, $.extend({}, this.options.player, { events: { 'onReady': _.bind(this.onPlayerReady, this), 'onStateChange': _.bind(this.onPlayerStateChange, this) } })); }, this); var tag = document.createElement('script'); tag.src = "//www.youtube.com/iframe_api"; var firstScriptTag = document.getElementsByTagName('script')[0]; firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); }; proto.onPlayerReady = function (event) { /* reinit container since it is replaced by iframe */ this.videoContainer = $('#' + this.options.videoContainerId); this.initVisibility(); this.initMute(); this.initAutoplay(); }; proto.initVisibility = function () { if (this.options.autoshow) { this.show(); } else { this.playButton.show(); } }; proto.initMute = function () { /* don't mute/autoplay on iOS via YouTube iframe API since those functions are not supported and causes infinite video loading */ if (!this.iOS && this.options.mute) { event.target.mute(); } }; proto.play = function () { this.playButton.hide(); this.show(); this.player.playVideo(); }; proto.initAutoplay = function() { if (this.iOS) { return; } if ((this.android && this.options.androidSupport || !this.android) && this.options.player.playerVars.autoplay ) { /* initiate autoplay for Android devices */ this.player.playVideo(); } }; proto.show = function () { this.videoContainer.fadeIn(1000); }; /** * YT.PlayerState: * - BUFFERING: 3 * - CUED: 5 * - ENDED: 0 * - PAUSED: 2 * - PLAYING: 1 * - UNSTARTED:-1 * @param event */ proto.onPlayerStateChange = function (event) { this.container.trigger('playerReadyState', event); if (event.data === YT.PlayerState.PLAYING && !this.videoContainer.is(':visible')) { this.initVisibility(); } else if (this.options.player.playerVars.loop && event.data === YT.PlayerState.ENDED) { this.player.seekTo(this.options.player.playerVars.start); } }; proto.onResize = function (event) { this.initHeight(); }; proto.initHeight = function () { var height = this.calcHeight(); this.container.height(Math.min(height, this.options.maxHeight)); this.videoContainer.height(height); this.playButton.css('margin-top', height/2 - this.playButton.height()/2); }; proto.calcHeight = function () { return this.container.width() / this.options.ratio; } })(qs.defineNS('qs'));