PageSourceSearch

https://www.bassquatchhunter.com/wp-content/plugins/pt-mato-addons/assets/js/youtube-video.js?ver=1.6.18

js bassquatchhunter.com collected 2026-10-10 02:02:49 UTC 18,513 bytes, 738 lines download raw bytes

1/*! @license html5-youtube.js by Ginpei https://github.com/ginpei/html5-youtube.js MIT License */
2
3/* global YT */
4(function(window, document) {
5	/**
6	 * The interface.
7	 */
8	window.youtube = function(options) {
9		return new Player(options);
10	};
11
12	/**
13	 * The constructor.
14	 */
15	var Player = window.youtube.Player = function(options) {
16		// define property's getters and setters if they have not yet
17		if (Player._undefinedProperties) {
18			Player._execDefineProperties();
19			delete Player._undefinedProperties;
20		}
21
22		this.initialize(options);
23	};
24
25	/**
26	 * The definition of available playbackRate values on YouTube API.
27	 * @see https://developers.google.com/youtube/js_api_reference#Playback_rate
28	 */
29	window.youtube.availablePlaybackRates = [0.25, 0.5, 1, 1.5, 2];
30
31	// shortcut
32	var prototype = Player.prototype;
33
34	// ----------------------------------------------------------------
35	// Statics
36
37	/**
38	 * These values are used to detect states in onStateChange event.
39	 * They are same as YouTube API's `YT.PlayerState`.
40	 * @see https://developers.google.com/youtube/iframe_api_reference#onStateChange
41	 */
42	Player.PlayerState = { UNSTARTED:-1, ENDED:0, PLAYING:1, PAUSED:2, BUFFERING:3, CUED:5 };
43
44	/**
45	 * Proxy for `Function#bind`.
46	 * It can be placed for compat.
47	 * @param {Function} fn
48	 * @returns {Function}
49	 */
50	Player.bind = function(fn) {
51		var args = Array.prototype.slice.call(arguments, 1);
52		return Function.prototype.bind.apply(fn, args);
53	};
54
55	/**
56	 * Execute property definig for stored values in `_undefinedProperties`.
57	 * This method is called only once when the first instance is created.
58	 */
59	Player._execDefineProperties = function() {
60		var obj = this.prototype;
61		var properties = this._undefinedProperties;
62		for (var name in properties) {
63			this._execDefineProperty(obj, name, properties[name]);
64		}
65	};
66
67	/**
68	 * Proxy for `Object.defineProperty`.
69	 * It can be placed for compat.
70	 */
71	Player._execDefineProperty = function(obj, prop, descriptor) {
72		Object.defineProperty(obj, prop, descriptor);
73	};
74
75	/**
76	 * Parse data attributes to number or string
77	 * Examples:
78	 * Player._parseDataAttribute('true') // 1
79	 * Player._parseDataAttribute('0') // 0
80	 * Player._parseDataAttribute('2EEsa_pqGAs') // '2EEsa_pqGAs'
81	 * @param {String} the data-attribute content
82	 * @returns {Number or String}
83	 */
84	Player._parseDataAttribute = function(string) {
85		var isNaN = function(val){
86			// NaN is the only value to return false when compared to itself
87			return val !== val;
88		}
89
90		if (typeof(string) === 'string'){
91			var toNum = Number(string);
92			if (!isNaN(toNum) && typeof toNum === 'number'){
93				return Number(string);
94			} else if (string === 'true') {
95				return true;
96			} else if (string === 'false') {
97				return false;
98			} else {
99				return string;
100			}
101		}
102	}
103
104	/**
105	 * Load YouTube API script.
106	 * @param {Function} callback
107	 */
108	Player.prepareYTScript = function(callback) {
109		// Status is changed as: initial->loading->ready.
110		// * The callback will run later if initial
111		// * The callback is queued and will run if loading
112		// * The callback run immediately if ready
113		//
114
115		var status = this._ytStatus;
116		if (status === undefined) {  // initial; not started
117			// initialize the callback queue
118			var callbacks = this._ytCallbacks = [];
119			callbacks.push(callback);
120
121			// load YouTube script
122			var url = 'https://www.youtube.com/iframe_api';
123			var elScript = document.createElement('script');
124			elScript.src = url;
125			document.body.appendChild(elScript);
126
127			// set callbacks
128			window.onYouTubeIframeAPIReady = Player.bind(function() {
129				callbacks.forEach(function(callback, index) {
130					callback();
131				});
132				delete this._ytCallbacks;
133				this._ytStatus = 2;
134			}, this);
135
136			// update status
137			this._ytStatus = 1;
138		}
139		else if (status === 1) {  // loading; started but not loaded yet
140			this._ytCallbacks.push(callback);
141		}
142		else if (status === 2) {  // ready; script is completely loaded
143			callback();
144		}
145	};
146
147	// ----------------------------------------------------------------
148	// Constructing
149
150	/**
151	 * Initialize the instance ownself.
152	 * @param {Object} options
153	 */
154	prototype.initialize = function(options) {
155		if (!this.player) {
156			this._events = [];
157			this._resetProperties();
158
159			this._initializeEventer();
160			this._buildPlayer(options);
161		}
162	};
163
164	/**
165	 * Good bye!
166	 */
167	prototype.destroy = function() {
168		if (this.player) {
169			this._removeAllEventListeners();
170			this._clearEventer();
171			this._stopAllObservings();
172			this._resetProperties();
173			this._destroyPlayer();
174		}
175	};
176
177	/**
178	 * Load YouTube API and setup video UI.
179	 * It can be placed for compat.
180	 * @param {Object} options
181	 */
182	prototype._buildPlayer = function(options) {
183		Player.prepareYTScript(Player.bind(this._setupVideo, this, options));
184	};
185
186	/**
187	 * @see #destroy
188	 */
189	prototype._destroyPlayer = function() {
190		this.player.destroy();
191		this.player = null;
192	};
193
194	/**
195	 * YT.Player has add/removeEventListener methods but they doesn't work correctly
196	 * It can be placed for compat.
197	 */
198	prototype._initializeEventer = function() {
199		this._eventer = document.createElement('ytapiplayer');
200		document.body.appendChild(this._eventer);
201	};
202
203	/**
204	 * It can be placed for compat.
205	 * @see #destroy
206	 */
207	prototype._clearEventer = function() {
208		document.body.removeChild(this._eventer);
209		this._eventer = null;
210	};
211
212	/**
213	 * Setup viode UI.
214	 * @param {Object} options
215	 */
216	prototype._setupVideo = function(options) {
217		var videoOptions = this._getVideoOptions(options);
218		this.player = this._createPlayer(videoOptions.el, {
219			events: this._getVideoEvents(),
220			height: videoOptions.height,
221			playerVars: videoOptions.playerVars,
222			videoId: videoOptions.videoId,
223			width: videoOptions.width
224		});
225	};
226
227	prototype._getVideoOptions = function(options) {
228		var el = options && options.el;
229		if (!el || !el.getAttribute) {
230			throw new Error('`options.el` is require.');
231		}
232
233		var ytPlayerVars = [
234			'autohide',
235			'autoplay',
236			'cc_load_policy',
237			'color',
238			'controls',
239			'disablekb',
240			'enablejsapi',
241			'end',
242			'fs',
243			'hl',
244			'iv_load_policy',
245			'list',
246			'listType',
247			'loop',
248			'modestbranding',
249			'origin',
250			'playerapiid',
251			'playlist',
252			'playsinline',
253			'rel',
254			'showinfo',
255			'start',
256			'theme',
257			'vq'
258		];
259
260		var videoId = options.id || el.getAttribute('data-youtube-videoid');
261		var playerVars = {};
262		ytPlayerVars.forEach(function(propName){
263			playerVars[propName] = this._getPlayerVarsOption(options, propName)
264		}.bind(this))
265
266		var width;
267		var height = el.clientHeight;
268		if (height) {
269			width  = el.clientWidth;
270		}
271		else {
272			height = 390;
273			width = 640;
274		}
275
276		return {
277			el: el,
278			height: height,
279			playerVars: playerVars,
280			videoId: videoId,
281			width: width
282		};
283	};
284
285	prototype._getPlayerVarsOption = function(options, name) {
286		var value;
287
288		if (options[name] == undefined) {  // or null
289			var attribute = options.el.getAttribute('data-youtube-' + name);
290			value = Player._parseDataAttribute(attribute);
291		}
292		else {
293			value = options[name];
294		}
295
296		if ((typeof value == 'number' && value >= 0) || typeof value == 'string') {
297			// OK, nothing to do
298		}
299		else if (typeof value == 'boolean') {
300			// Convert booleans to number
301			value = Number(value);
302		}
303		else {
304			// Let's set the value to nothing and let the youtube player fallback to defaults
305			value = undefined;
306		}
307
308		return value;
309	};
310
311	prototype._getVideoEvents = function() {
312		var events = {};
313
314		[
315			'onApiChange',
316			'onError',
317			'onPlaybackQualityChange',
318			'onPlaybackRateChange',
319			'onReady',
320			'onStateChange',
321		].forEach(function(type, index) {
322			events[type] = Player.bind(this[type], this);
323		}.bind(this));
324
325		return events;
326	};
327
328	prototype._createPlayer = function(el, options) {
329		return new YT.Player(el, options);
330	};
331
332	// ----------------------------------------------------------------
333	// Events
334
335	/**
336	 * Attach an event handler function.
337	 * @param {String} type A event type like `"play"`, '"timeupdate"` or `"onReady"`.
338	 * @param {Function} listener A function to execute when the event is triggered.
339	 * @see {#removeEventListener}
340	 */
341	prototype.addEventListener = function(type, listener) {
342		var binded = this._pushListener(type, listener);
343		this._eventer.addEventListener(type, binded);
344	};
345
346	/**
347	 * Dettach an event handler function.
348	 * @param {String} type
349	 * @param {Function} listener
350	 * @see {#addEventListener}
351	 */
352	prototype.removeEventListener = function(type, listener) {
353		var data = this._popListener(type, listener);
354		if (data) {
355			this._eventer.removeEventListener(type, data.binded);
356		}
357	};
358
359	/**
360	 * A shortcut for `addEventListener` and returns `this`.
361	 * You can use method chaining.
362	 * @param {String} type
363	 * @param {Function} listener
364	 * @returns {Player}
365	 */
366	prototype.on = function(type, listener) {
367		this.addEventListener(type, listener);
368		return this;
369	};
370
371	/**
372	 * A shortcut for `removeEventListener` and returns `this`.
373	 * You can use method chaining.
374	 * @param {String} type
375	 * @param {Function} listener
376	 * @returns {Player}
377	 */
378	prototype.off = function(type, listener) {
379		this.removeEventListener(type, listener);
380		return this;
381	};
382
383	/**
384	 * Trigger an event.
385	 * It can be placed for compat.
386	 * @param {String} type A event type like `"play"`, '"timeupdate"` or `"onReady"`.
387	 */
388	prototype.trigger = function(type, originalEvent) {
389		var event = document.createEvent('CustomEvent');
390		event.initEvent(type, false, true);
391		event.player = this;
392
393		if (originalEvent) {
394			event.playerData = originalEvent.data;
395			event.originalEvent = originalEvent;
396		}
397
398		this._eventer.dispatchEvent(event);
399	};
400
401	/**
402	 * @see #destroy
403	 */
404	prototype._removeAllEventListeners = function() {
405		var allEvents = this._events;
406		for (var type in allEvents) {
407			var events = allEvents[type];
408			for (var i=0, l=events.length; i<l; i++) {
409				var data = events[i];
410				if (data) {
411					this.removeEventListener(type, data.listener);
412					delete data.listener;
413					delete data.binded;
414					events[i] = null;
415				}
416			}
417			delete allEvents[type];
418		}
419	};
420
421	prototype._pushListener = function(type, listener) {
422		var binded = Player.bind(listener, this);
423
424		var events = this._events[type];
425		if (!events) {
426			events = this._events[type] = [];
427		}
428
429		events.push({
430			binded: binded,
431			listener: listener
432		});
433
434		return binded;
435	};
436
437	prototype._popListener = function(type, listener) {
438		var events = this._events[type];
439		if (events) {
440			for (var i=0, l=events.length; i<l; i++) {
441				var data = events[i];
442				if (data && data.listener === listener) {
443					events[i] = null;
444					return data;
445				}
446			}
447		}
448		return undefined;
449	};
450
451	prototype.onApiChange = function(event) {
452		this.trigger('onApiChange', event);
453	};
454
455	/**
456	 * @param {Number} event.playerData The error ID.
457	 * @see https://developers.google.com/youtube/iframe_api_reference#onError
458	 */
459	prototype.onError = function(event) {
460		this.trigger('onError', event);
461		this.trigger('error', event);
462	};
463
464	prototype.onPlaybackQualityChange = function(event) {
465		this.trigger('onPlaybackQualityChange', event);
466	};
467
468	prototype.onPlaybackRateChange = function(event) {
469		this.trigger('onPlaybackRateChange', event);
470	};
471
472	prototype.onReady = function(event) {
473		this.trigger('onReady', event);
474
475		if (this._unsetVideoId) {
476			this.player.cueVideoById(this._unsetVideoId);
477			delete this._unsetVideoId;
478		}
479
480		this._updateMeta();
481		this._observeTimeUpdate();
482		this._observeVolume();
483		this._observePlaybackRate();
484		this._observeDuration();
485		this.trigger('ready', event);
486		this.trigger('canplay', event);
487		this.trigger('canplaythrough');
488	};
489
490	prototype.onStateChange = function(event) {
491		this.trigger('onStateChange', event);
492
493		var state = event.data;
494
495		this.played = this.paused = this.ended = false;
496
497		if (state === Player.PlayerState.UNSTARTED) {
498			this.trigger('emptied', event);
499		}
500		else if (state === Player.PlayerState.ENDED) {
501			this.ended = true;
502			this.trigger('ended', event);
503		}
504		else if (state === Player.PlayerState.PLAYING) {
505			this.played = true;
506			this.trigger('play', event);
507			this.trigger('playing', event);
508		}
509		else if (state === Player.PlayerState.PAUSED) {
510			this.paused = true;
511			this.trigger('pause', event);
512		}
513		else if (state === Player.PlayerState.BUFFERING) {
514			this.trigger('buffer', event);
515		}
516		else if (state === Player.PlayerState.CUED) {
517			this._updateMeta();
518			this.trigger('canplay');
519			this.trigger('canplaythrough');
520		}
521	};
522
523	// ----------------------------------------------------------------
524	// Manip
525
526	/**
527	 * Play the video.
528	 */
529	prototype.play = function() {
530		if (this.player) {
531			this.player.playVideo();
532		}
533	};
534
535	/**
536	 * Stop the video.
537	 */
538	prototype.pause = function() {
539		if (this.player) {
540			this.player.pauseVideo();
541		}
542	};
543  
544	prototype.getIframe = function() {
545		if (this.player) {
546			return this.player.getIframe();
547		}
548	};
549
550	/**
551	 * This function returns the set of playback rates in which the current video is available. The default value is 1, which indicates that the video is playing in normal speed.
552	 *
553	 * The function returns an array of numbers ordered from slowest to fastest playback speed. Even if the player does not support variable playback speeds, the array should always contain at least one value (1).
554	 * @returns {Array}
555	 * @see https://developers.google.com/youtube/iframe_api_reference#getAvailablePlaybackRates
556	 */
557	prototype.getAvailablePlaybackRates = function() {
558		if (this.player) {
559			return this.player.getAvailablePlaybackRates();
560		}
561		else {
562			return undefined;
563		}
564	};
565
566	// ----------------------------------------------------------------
567	// Properties
568
569	prototype._updateMeta = function() {
570		this._src = this.currentSrc = this.player.getVideoUrl();
571	};
572
573	/**
574	 * Start observing timeupdate's change.
575	 */
576	prototype._observeTimeUpdate = function() {
577		this._tmTimeUpdate = setInterval(Player.bind(function() {
578			var time = this.player.getCurrentTime();
579			if (time !== this._currentTime) {
580				this._currentTime = time;
581				this.trigger('timeupdate');
582			}
583		}, this), 100);
584	};
585
586	/**
587	 * Start observing volume's change.
588	 */
589	prototype._observeVolume = function() {
590		this._tmVolume = setInterval(Player.bind(function() {
591			var muted = this.player.isMuted();
592			var volume = this.player.getVolume();
593			if (muted !== this._muted || volume !== this._volume) {
594				this._muted = muted;
595				this._volume = volume;
596				this.trigger('volumechange');
597			}
598		}, this), 100);
599	};
600
601	/**
602	 * Start observing playbackRate's change.
603	 */
604	prototype._observePlaybackRate = function() {
605		this._tmPlaybackRate = setInterval(Player.bind(function() {
606			var playbackRate = this.player.getPlaybackRate();
607			if (playbackRate !== this._playbackRate) {
608				this._playbackRate = playbackRate;
609				this.trigger('ratechange');
610			}
611		}, this), 100);
612	};
613
614	/**
615	 * Start observing duration's change.
616	 */
617	prototype._observeDuration = function() {
618		this._tmDuration = setInterval(Player.bind(function() {
619			var duration = this.player.getDuration() || 0;
620			if (duration !== this.duration) {
621				this.duration = duration;
622				this.trigger('durationchange');
623			}
624		}, this), 100);
625	};
626
627	/**
628	 * @see #destroy
629	 */
630	prototype._stopAllObservings = function() {
631		clearInterval(this._tmTimeUpdate);
632		clearInterval(this._tmVolume);
633		clearInterval(this._tmPlaybackRate);
634		clearInterval(this._tmDuration);
635	};
636
637	prototype._resetProperties = function() {
638		this._currentTime = null;
639		this._volume = null;
640		this._muted = null;
641		this._playbackRate = null;
642		this._src = null;
643		this.duration = null;
644		this.currentSrc = null;
645		this.played = null;
646		this.paused = null;
647		this.ended = null;
648	};
649
650	/**
651	 * Definitions are stored here.
652	 * @type Array
653	 */
654	Player._undefinedProperties = {
655		/**
656		 * Returns the current playback position, in seconds, as a position between zero time and the current duration.
657		 * Can be set, to seek to the given time.
658		 * @type number
659		 */
660		currentTime: {
661			get: function() {
662				return this._currentTime;
663			},
664			set: function(value) {
665				if (this.player) {
666					this.player.seekTo(value, true);
667				}
668			}
669		},
670
671		/**
672		 * Returns the current playback volume multiplier, as a number in the range 0.0 to 1.0, where 0.0 is the quietest and 1.0 the loudest.
673		 * Can be set, to change the volume multiplier.
674		 * @type number
675		 */
676		volume: {
677			get: function() {
678				return this._volume / 100;
679			},
680			set: function(value) {
681				if (this.player) {
682					this.player.setVolume(value * 100);
683				}
684			}
685		},
686
687		/**
688		 * Returns true if all audio is muted (regardless of other attributes either on the controller or on any media elements slaved to this controller), and false otherwise.
689		 * Can be set, to change whether the audio is muted or not.
690		 * @type number
691		 */
692		muted: {
693			get: function() {
694				return this._muted;
695			},
696			set: function(value) {
697				if (this.player) {
698					this.player[value?'mute':'unMute']();
699				}
700			}
701		},
702
703		/**
704		 * Returns the default rate of playback, for when the user is not fast-forwarding or reversing through the media resource.
705		 * Can be set, to change the default rate of playback.
706		 * @type number
707		 */
708		playbackRate: {
709			get: function() {
710				return this._playbackRate;
711			},
712			set: function(value) {
713				if (this.player) {
714					this.player.setPlaybackRate(value);
715				}
716			}
717		},
718
719		/**
720		 * Returns the address of the current media resource.
721		 * Can be set, to change the video URL.
722		 * @type number
723		 */
724		src: {
725			get: function() {
726				return this._src;
727			},
728			set: function(value) {
729				if (this.player) {
730					this.player.cueVideoById(value);
731				}
732				else {
733					this._unsetVideoId = value;
734				}
735			}
736		}
737	};
738})(window, document);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.