PageSourceSearch

https://cinefil.tokyo/static/lib/js/jquery-autoplay-onscroll.js?260929023659

js cinefil.tokyo collected 2026-10-02 07:41:58 UTC 22,978 bytes, 834 lines download raw bytes

1/**
2 * 動画をスクロールに応じて自動再生
3 * 最初は無音、ワンクリックで音付き先頭から再生
4 * 自動・手動ともスクロールアウトで停止
5 * usage:
6 *   $.autoplayScrolledIntoView(); 対象となりうる要素すべて
7 *   $.autoplayScrolledIntoView('<selector>');
8 *   
9 * window._disable_autoplay_onscrolledintoview = true にすると動作を停止
10 * .disable-autoplay-onscrolledintoview 内は対象外
11 * data-autoplay-gif 属性にて自動再生不可の端末(iOS/Android)でGIFを表示
12 */
13
14$(function(){
15
16var DEBUG = false;
17	
18// var allow_autoplay = !window.navigator.userAgent.match(/(ios|iphone|ipad|android).*webkit/i);
19var allow_autoplay = true;
20
21if ($.autoplayScrolledIntoView) { return; }
22console.log('jquery-autoplay-onscroll loaded.');
23
24if (!$.registerOnScrolledIntoView) {
25	console.error('need jquery-onscrolledintoview.js before jquery-autoplay-onscroll');
26	return;
27}
28
29var youtube_iframe_api_initialized = false;
30
31// correct iframe protocol to location.protocol
32var protocol = location.protocol;
33// var bad_protocol = 'http'
34var bad_protocol = location.protocol == 'http:' ? 'https:' : 'http:';
35var SELECTOR = [
36	'//www.youtube.com/embed/',
37	'//youtu.be/embed/',
38	'//w.soundcround.com/player/',
39	'//player.vimeo.com/video/'
40].map(function(v){
41	return 'iframe[src^="' + bad_protocol + v + '"],iframe[src^="' + v + '"]';
42}).join(',');
43var RX = new RegExp('^('+bad_protocol+')?//');
44function correctIframeProtocol(){
45	$(SELECTOR).each(function(){
46		var $e = $(this), src = $e.attr('src').replace(RX, location.protocol + '//');
47		if (src != $e.attr('src')) {
48			$e.attr('src', src);
49			console.log('replaced:' + src);
50		}
51	});
52}
53correctIframeProtocol();
54// setInterval(correctIframeProtocol, 1000/10);
55
56
57// correctIframeProtocol() を通したあとなので https でOK
58var YOUTUBE_SELECTOR = [ // チェック前に correctIframeProtocol() を通すべし
59	'iframe[src^="//www.youtube.com/embed/"]',
60	'iframe[src^="//youtu.be/embed/"]',
61	'iframe[src^="http://www.youtube.com/embed/"]',
62	'iframe[src^="http://youtu.be/embed/"]',
63	'iframe[src^="https://www.youtube.com/embed/"]',
64	'iframe[src^="https://youtu.be/embed/"]'
65].join(',');
66var VIMEO_SELECTOR = [ // チェック前に correctIframeProtocol() を通すべし
67	'iframe[src^="//player.vimeo.com/video/"]',
68	'iframe[src^="http://player.vimeo.com/video/"]',
69	'iframe[src^="https://player.vimeo.com/video/"]'
70 ].join(',');
71
72var DEFAULT_TARGET_SELECTOR = [
73	YOUTUBE_SELECTOR,
74	VIMEO_SELECTOR,
75	'video'
76].join(',');
77
78
79function parseQuery(qs) {var r={};(qs||'').split('&').forEach(function(v, i){v=v.split('=');v[0]&&(r[v[0]]=v[1]===undefined?undefined:decodeURIComponent(v[1]))});return r}
80function buildQuery(params){var r=[],k,v;for(k in params){if(params.hasOwnProperty(k)){v=params[k];v=v===undefined?'':'='+encodeURIComponent(v);r.push(k+v)}};return r.join('&')}
81
82var WATCH_INTERVAL = 1000/250;
83
84var WATCHING_SELECTORS = [];
85var $WATCHING_ELEMENTS = $();
86var WATCHING_SELECTOR = '';
87
88$.clearAutoplayScrolledIntoView = function(){
89	$.unregisterOnScrolledIntoView(WATCHING_SELECTOR);
90	$WATCHING_ELEMENTS.each(function(){
91		$.unregisterOnScrolledIntoView(this);
92	});
93	$WATCHING_ELEMENTS = $();
94	WATCHING_SELECTORS = [];
95	WATCHING_SELECTOR = '';
96};
97
98$.autoplayScrolledIntoView = function(target) {
99	
100	if (window._disable_autoplay_onscrolledintoview) { return; }
101	
102	target = (target === undefined ? DEFAULT_TARGET_SELECTOR : target);
103	
104	$.registerOnScrolledIntoView(target);
105	$.registerAutoplayScrolledIntoView(target);
106	
107};
108
109$.registerAutoplayScrolledIntoView = function(target){
110	if (typeof target == 'string') {
111		if ($.inArray(target, WATCHING_SELECTORS) == -1){
112			WATCHING_SELECTORS.push(target);
113			WATCHING_SELECTOR = WATCHING_SELECTORS.join(',');
114		}
115	} else {
116		$WATCHING_ELEMENTS.add($(target));
117		$(target).on('remove DOMNodeRemoved', function(ev){
118			$.unregisterOnScrolledIntoView(ev.target);
119		});
120	}
121	checkAll();
122	$.registerOnScrolledIntoView(target);
123	return $(target);
124};
125
126$.fn.registerAutoplayScrolledIntoView = function(){
127	$.registerAutoplayScrolledIntoView(this);
128	return this;
129};
130
131$.unregisterAutoplayScrolledIntoView = function(target){
132	if (typeof target == 'string') {
133		var idx = $.inArray(target, WATCHING_SELECTORS);
134		if (idx == -1){
135			WATCHING_SELECTORS.splice(idx, 1);
136			WATCHING_SELECTOR = WATCHING_SELECTORS.join(',');
137		}
138	} else {
139		target = $(target);
140		$WATCHING_ELEMENTS = $WATCHING_ELEMENTS.filter(function(){
141			return !target.is(this);
142		});
143	}
144	$.unregisterOnScrolledIntoView(target);
145	checkAll();
146	return $(target);
147};
148
149var stop_autoplay = false;
150
151$.toggleAutoplayScrolledIntoView = function(toggle){
152	stop_autoplay = toggle===undefined?togglek:!stop_autoplay;
153};
154
155$.fn.unregisterAutoplayScrolledIntoView = function(){
156	$.unregisterAutoplayScrolledIntoView(this);
157	return this;
158};
159
160function checkAll(){
161	correctIframeProtocol();
162	var $target = $(WATCHING_SELECTOR).add($WATCHING_ELEMENTS);
163	
164	// .disable-autoplay-onscrolledintoviewかその内部のものは対象外にする
165	$target = $target.filter(function(){
166		return (
167				!$(this).closest('.disable-autoplay-onscrolledintoview')[0]
168				&& !$(this).is('.disable-autoplay-onscrolledintoview')[0]
169			)
170	});
171	youtube_iframe_api_initialized && checkYouTubeIframe($target.filter(YOUTUBE_SELECTOR));
172	checkVimeo($target.filter(VIMEO_SELECTOR));
173	checkVideoElement($target.filter('video'));
174}
175
176function cssPositions($elm) {
177	var ret = {};
178	['position', 'top', 'left', 'width', 'height', 'bottom', 'margin', 'padding', 'z-index', 'opacity', 'zoom', 'max-width', 'max-height', 'transform', '-webkit-transform', 'box-sizing', '-webkit-box-sizing'].forEach(function(v){
179		ret[v] = $elm.css(v);
180	});
181	return ret;
182}
183
184function makeAutoplayGif($elm, onclick) {
185	var gif = $elm.attr('data-autoplay-gif');
186	var $gif = $elm.data('autoplaygif');
187	if (gif && !$gif ) {
188		$gif = $('<img>').attr('src', gif).css('cursor','pointer');
189		var offset = $elm.position();
190		$gif.data('autoplay_target', $elm)
191			.on('click', function(ev){
192				var $gif = $(this), $elm = $gif.data('autoplay_target');
193				onclick($elm);
194				setTimeout(function(){
195					$gif.remove();
196					$elm.show();
197				}, 10);
198			})
199			.css(cssPositions($elm))
200			.insertBefore($elm)
201			;
202			$elm.hide();
203		
204		$elm.data('autplaygif', $gif);
205	}
206}
207
208/**** video tag ****/
209
210if (HTMLMediaElement) {
211	Object.defineProperty(HTMLMediaElement.prototype, 'playing', {
212		get: function(){
213			return !!(this.currentTime > 0 && !this.paused && !this.ended && this.readyState > 2);
214		}
215	});
216
217	HTMLMediaElement.prototype.fadeout = function(opts){
218		var video = this;
219		if (!video.playing) { return; }
220		var org_vol = video.volume;
221		opts = $.extend({
222			startVolume: org_vol,
223			endVolume: 0,
224			duration: 1000,
225			steps: 10,
226			done: function(){},
227		}, opts);
228		var vol = opts.startVolume;
229		var delta_vol = (opts.startVolume - opts.endVolume) / opts.steps;
230		var _t = setInterval(function(){
231			if (vol > 0) {
232				vol = vol - delta_vol;
233				video.volume = vol;
234			} else {
235				clearInterval(_t);
236				video.pause();
237				video.volume = org_vol;
238				opts.done.call(video);
239			}
240		}, opts.duration / opts.steps);
241	}
242	
243}
244
245function checkVideoElement($target){
246	$target.each(function(){
247		var $video = $(this), video = $video[0], autoplay = $video.data('autoplay');
248		
249		if (autoplay) { return; }
250		$video.data('autoplay', {notinitialized:true});
251		
252		function startAutoPlay($video){
253			if (stop_autoplay) { return; }
254			var player = $video[0], autoplay = $video.data('autoplay');
255			if (!autoplay || autoplay.notinitialized ) {
256				autoplay = {
257						muted: player.muted,
258						controls: player.controls,
259						loop: player.loop,
260						canceled: false,
261						cursor: $video.css('cursor')
262					};
263				$video.data('autoplay', autoplay);
264			}
265			if (!autoplay.canceled) {
266				player.muted = true;
267				player.controls = false;
268				$video.css('cursor', 'pointer');
269				$video.data('autoplay', autoplay);
270				
271				if (allow_autoplay) {
272					player.play();
273				} else {
274					makeAutoplayGif($video, function($video){
275						var autoplay = $video.data('autoplay'), video = $video[0];
276						video.currentTime = 0;
277						video.muted = autoplay.muted;
278						video.controls = autoplay.controls;
279						video.play();
280						autoplay.canceled = true;
281						$video.data('autoplay', autoplay);
282					});
283				}
284			}
285		}
286		function stopAutoPlay($video, cue, clear_autoplay){
287			if (stop_autoplay) { return; }
288			var player = $video[0], autoplay = $video.data('autoplay');
289			if (allow_autoplay) {
290				player.pause();
291			}
292			player.muted = autoplay.muted;
293			if (cue) {
294				player.currentTime = 0;
295			}
296			if (clear_autoplay) {
297				player.controls = autoplay.controls;
298				$video.css('cursor', autoplay.cursor);
299				player.loop = autoplay.loop;
300				autoplay.canceled = true;
301				$video.data('autoplay', autoplay);
302			}
303		}
304		
305		$video
306		.on('click.autoplaying', function(ev){
307			var $video = $(this), autoplay = $video.data('autoplay'), video = $video[0];
308			if (autoplay && !autoplay.canceled && $video.isInView()) {
309				stopAutoPlay($video, true, true);
310				video.play();
311			}
312		}).on('ended.autoplaying', function(ev){
313			var $video = $(this), autoplay = $video.data('autoplay'), video = $video[0];
314			if (autoplay.loop && !autoplay.canceled && $video.isInView() ) {
315				video.currentTime = 0;
316				video.play();
317			}
318		}).on('scrolledintoview', function(ev){
319			var $video = $(this), autoplay = $video.data('autoplay'), video = $video[0];
320			if (!autoplay || !autoplay.canceled) {
321				startAutoPlay($video);
322			}
323		}).on('scrolledoutofview', function(ev){
324			var $video = $(this), autoplay = $video.data('autoplay'), video = $video[0];
325			if (video.playing){
326				if (video.muted) {
327					$video[0].pause();
328				} else {
329					$video[0].fadeout({
330						done:function(){}
331					});
332				}
333			}
334		});
335		if ($video.isInView()) {
336			startAutoPlay($video);
337		}
338	});
339	
340}
341
342
343/*** youtube iframe ***/
344
345var YT_ST_REV = {};
346
347function correctYoutubeIframeParams($target){
348	$target.each(function(){
349		var $ifr = $(this), src=$ifr.attr('src'),
350			src = src.split('?'),
351			params = parseQuery(src[1]);
352		params.origin = location.href.match(/^https?:\/\/[^\/]+/)[0];
353		params.playsinline = 1;
354		params.modestbranding = 1;
355		$ifr.attr('src', src[0] + '?' + buildQuery(params));
356	})
357}
358correctYoutubeIframeParams($('iframe[src*="youtube.com/embed"]'))
359
360function checkYouTubeIframe($target){
361	
362	function startAutoPlay($ifr){
363		if (stop_autoplay) { return; }
364		var autoplay = $ifr.data('autoplay');
365		var player = $ifr.data('ytplayer');
366		if (!autoplay) {
367			autoplay = {
368				muted: allow_autoplay && player.isMuted(),
369				canceled: false,
370				qs: $ifr.data('org_qs'),
371				params: $ifr.data('org_params'),
372			};
373			$ifr.data('autoplay', autoplay);
374		}
375		if (!autoplay.canceled) {
376			
377			if (allow_autoplay) {
378				player.mute();
379				player.playVideo();
380			} else {
381				makeAutoplayGif($ifr, function($ifr){
382					var player = $ifr.data('ytplayer');
383					var autoplay = $ifr.data('autoplay');
384					autoplay.canceled = true;
385					$ifr.data('autoplay', autoplay);
386					if (allow_autoplay) {
387						player.seekTo(0);
388						if (!autoplay.muted) {
389							player.unMute();
390						}
391						console.log('YouTube:playVideo()', $ifr);
392						player.playVideo(); /* うまく動かない */
393					}
394				});
395			}
396		}
397	}
398	
399	function stopAutoPlay($ifr, cue, clear_autoplay){
400		if (stop_autoplay) { return; }
401		var autoplay = $ifr.data('autoplay');
402		var player = $ifr.data('ytplayer');
403		if (allow_autoplay) {
404			if (cue) {
405				player.seekTo(0);
406			}
407			player.pauseVideo();
408			if (!autoplay.muted) {
409				player.unMute();
410			}
411		}
412		if (clear_autoplay) {
413			autoplay.canceled = true;
414			$ifr.data('autoplay', autoplay);
415		}
416	}
417	
418	function onReady(player, $ifr) {
419		// console.log('YT.Player:onReady', $ifr[0]);
420		$ifr
421			.data('ytplayer', player)
422			.on('scrolledintoview', function(){
423				var $ifr = $(this), autoplay = $ifr.data('autoplay');
424				var player = $ifr.data('ytplayer');
425				if (!autoplay || !autoplay.canceled) {
426					var s = player.getPlayerState && player.getPlayerState();
427					if (!allow_autoplay
428							|| s === YT.PlayerState.UNSTARTED
429							|| s === YT.PlayerState.BUFFERING
430							|| s === YT.PlayerState.CUED
431							|| s === YT.PlayerState.PAUSED) {
432						startAutoPlay($ifr);
433					}
434				}
435			}).on('scrolledoutofview', function(){
436				var $ifr = $(this), autoplay = $ifr.data('autoplay');
437				var player = $ifr.data('ytplayer');
438				var s = player.getPlayerState && player.getPlayerState();
439				if (s == YT.PlayerState.PLAYING){
440					if (allow_autoplay) {
441						if (player.isMuted()) {
442							player.pauseVideo();
443						} else {
444							ytplayerFadeoutVideo(player);
445						}
446					}
447				}
448			});
449		if ($ifr.isInView()) {
450			startAutoPlay($ifr);
451		}
452	}
453	
454	$target.each(function(){
455		var $ifr = $(this), src=$ifr.attr('src');
456		var player = $ifr.data('ytplayer');
457		
458		if (player) {
459			// console.log('youtube iframe initialized', this);
460		} else {
461			
462			if (src.indexOf(location.protocol) != 0) {
463				console.log('checkYouTubeIframe:bad protocol. waiting:' + src);
464				return;
465			}
466			console.log('checkYouTubeIframe:process:' + src);
467			
468			var m = src.match(/\/embed\/(.+?)(\?(.+?))?$/);
469			var video_id = m[1], qs = m[3] || '', params;
470			
471			params = parseQuery(qs);
472			
473			if (params.loop == '1' && !params.playlist) {
474				params.playlist = video_id;
475			}
476			
477			delete params.autoplay;
478			params.enablejsapi = '1';
479			params.origin = location.href.split('/').splice(0, 3).join('/');
480			params.playsinline = 1;
481			params.modestbranding = 1;
482			
483			var org_params = $.extend({}, params);
484			var org_qs = buildQuery(org_params);
485			
486			$ifr.data('org_qs', org_qs);
487			$ifr.data('org_params', org_params);
488			
489			params.loop = '1';
490			
491			qs = buildQuery(params);
492			
493			src = src
494				.replace(/^https?:/, location.protocol) /* jsapi は同じプロトコルのみ有効 */
495				.replace(/\/embed\/([^\?]+)(\?.*)?$/, '/embed/$1?')
496				+ qs;
497			
498			console.log('checkYouTubeIframe:processed:' + src);
499			
500			if (!allow_autoplay) {
501				console.log('dummy YTPlayer');
502				player = {
503					not_allow_autoplay:true,
504					getIframe:function(){return $ifr;},
505				};
506				setTimeout(function(){
507					onReady(player, $ifr);
508				}, 10);
509			} else {
510				var cnt = 0;
511				player = {
512					initializing:true,
513					getIframe:function(){return $ifr;},
514				};
515				// $ifr.on('load', function(){
516				$ifr
517				.attr('src', src)
518				.on('load', function(){
519					var $ifr = $(this), ifr_id = $ifr.attr('id') || ('ifr-yt-' + cnt);
520					$ifr.attr('id', ifr_id)
521					console.log('youtube iframe', this);
522					player = new YT.Player(ifr_id, {
523						events:{
524							onReady:function(ev){
525								var player = ev.target;
526								var $ifr = $(ev.target.getIframe());
527								console.log('youtube Player onReady', $ifr[0]);
528								return onReady(player, $ifr);
529							},
530							onStateChange:function(ev){
531								// console.log('YT.Player:onStateChange:' + YT_ST_REV[ev.data]||ev.data, ev.target.getIframe());
532								var player = ev.target, s = ev.data, $ifr = $(player.getIframe()), autoplay = $ifr.data('autoplay');
533								if (autoplay && !autoplay.canceled && $ifr.isInView()) {
534									if (s == YT.PlayerState.PAUSED) {
535										stopAutoPlay($ifr, true, true);
536										setTimeout(function(){
537											allow_autoplay && player.playVideo();
538										}, 10);
539									} else if (s == YT.PlayerState.ENDED) {
540										if (autoplay.params.loop != '1') {
541											// 元パラメータがループでないときは手動ループ
542											allow_autoplay && player.seekTo(0);
543										}
544									}
545								}
546							},
547							onError:function(ev){
548								console.error('YoutubeIframe:error:', ev.data);
549							},
550						}
551					});
552					$ifr.data('ytplayer', player);
553				});
554				// }).attr('src', src);
555			}
556			$ifr.data('ytplayer', player);
557			// console.log('YT.Player:Created:', $ifr[0], player);
558			
559		}
560		if (!player) {
561			console.error('cannot get ytplayer', $ifr[0]);
562			return;
563		}
564		
565	});
566	
567
568}
569
570function ytplayerFadeoutVideo(player, opts){
571	if (player.getPlayerState() != YT.PlayerState.PLAYING) { return; }
572	var org_vol = player.getVolume();
573	opts = $.extend({
574		startVolume: org_vol,
575		endVolume: 0,
576		duration: 1000,
577		steps: 10,
578		done: function(){},
579	}, opts);
580	var vol = opts.startVolume;
581	var delta_vol = (opts.startVolume - opts.endVolume) / opts.steps;
582	var _t = setInterval(function(){
583		if (vol > 0) {
584			vol = vol - delta_vol;
585			player.setVolume(vol);
586		} else {
587			clearInterval(_t);
588			player.pauseVideo();
589			player.setVolume(org_vol);
590			opts.done.call(player);
591		}
592	}, opts.duration / opts.steps);
593}
594
595/**** vimeo ****/
596
597function fadeoutVimeo(player, opts){
598	var player = this;
599	if (!player.playing) { return; }
600	player.api('getVolume', function(org_vol){
601		opts = $.extend({
602			startVolume: org_vol,
603			endVolume: 0,
604			duration: 1000,
605			steps: 10,
606			done: function(){},
607		}, opts);
608		var vol = opts.startVolume;
609		var delta_vol = (opts.startVolume - opts.endVolume) / opts.steps;
610		var _t = setInterval(function(){
611			if (vol > 0) {
612				vol = vol - delta_vol;
613				player.api('setVolume', vol);
614			} else {
615				clearInterval(_t);
616				player.api('pause');
617				player.api('setVolume', org_vol);
618				opts.done.call(player);
619			}
620		}, opts.duration / opts.steps);
621	});
622}
623
624// https://f.vimeocdn.com/js/froogaloop2.min.js
625
626var vimeo_cnt = 0;
627$(document).one('scrolledintoview', VIMEO_SELECTOR, function(){
628	if (!window.$f) {
629		$('<'+'script></'+'script>').attr({
630			'id':'script-vimeo-api',
631			'src':'https://f.vimeocdn.com/js/froogaloop2.min.js'
632		}).appendTo('body');
633		console.log('vimeo js api loading');
634	}
635});
636
637var $vimeo_need_replace = $();
638function checkVimeo($target){
639	if (!window.$f) {
640		// http://stackoverflow.com/questions/31691097/uncaught-typeerror-cannot-read-property-ready-of-undefined-vimeo
641		// script 読み込み前のiframeにapiが効かない?
642		$vimeo_need_replace = $vimeo_need_replace.add($target);
643		$target.data('need_replace', true);
644		return;
645	}
646	
647	$target.each(function(){
648		var $ifr = $(this), ifr = $ifr[0], autoplay = $ifr.data('autoplay');
649		
650		var src = $ifr.attr('src').split('?');
651		var q = parseQuery(src[1]);
652		if (!q.api) {
653			var id = $ifr.attr('id') || ('vimeo-' + (++vimeo_cnt));
654			$.extend(q, {
655				api:'1',
656				player_id:id
657			});
658			var $new_ifr = $ifr.clone().attr({
659				id: id,
660				src: src[0] + '?' + buildQuery(q)
661			});
662			$ifr.replaceWith($new_ifr);
663			console.log('vimeo iframe src replaced:'+ $new_ifr.attr('src'));
664			return;
665		}
666		
667		if ($ifr.data('need_replace')) {
668			$ifr.replaceWith($ifr.clone().data('need_replace', false));
669			return;
670		}
671		
672		if (autoplay) { return; }
673		
674		var player = $f($ifr[0]);
675		
676		player.addEvent('ready', function(){
677			console.info('vimeo:ready', player);
678			
679			$ifr.data('autoplay', {
680				notinitialized:true,
681				player: player
682			});
683			
684			function startAutoPlay($ifr){
685				if (stop_autoplay) { return; }
686				var autoplay = $ifr.data('autoplay');
687				if (!autoplay || autoplay.notinitialized ) {
688					var player = autoplay && autoplay.player || $f($ifr[0]);
689					autoplay = {
690							player:player,
691							// muted: player.api('getVolume'),
692							// loop: player.api('getLoop'),
693							canceled: false,
694							cursor: $ifr.css('cursor')
695						};
696					player.api('getVolume', function(vol){
697						autoplay.muted = vol;
698					});
699					player.api('getLoop', function(loop){
700						autoplay.loop = loop;
701					});
702					$ifr.data('autoplay', autoplay);
703				}
704				var player = autoplay.player;
705				if (!autoplay.canceled) {
706					player.api('setVolume', 0);
707					$ifr.css('cursor', 'pointer');
708					$ifr.data('autoplay', autoplay);
709					
710					if (allow_autoplay) {
711						player.api('play');
712					} else {
713						makeAutoplayGif($ifr, function($ifr){
714							var autoplay = $ifr.data('autoplay'), player = autoplay.player;
715							player.api('seekTo', 0);
716							player.api('setVolume', autoplay.muted);
717							player.api('play');
718							autoplay.canceled = true;
719							$ifr.data('autoplay', autoplay);
720						});
721					}
722				}
723			}
724			function stopAutoPlay($ifr, cue, clear_autoplay){
725				if (stop_autoplay) { return; }
726				var autoplay = $ifr.data('autoplay'), player = autoplay.player;
727				if (allow_autoplay) {
728					player.api('pause');
729				}
730				player.api('setVolume', autoplay.muted);
731				if (cue) {
732					player.api('setCurrentTime', 0);
733				}
734				if (clear_autoplay) {
735					$ifr.css('cursor', autoplay.cursor);
736					player.api('setLoop', autoplay.loop);
737					autoplay.canceled = true;
738					$ifr.data('autoplay', autoplay);
739				}
740			}
741			
742			player.addEvent('play', function(){
743				player.playing = true;
744			});
745			player.addEvent('finish', function(){
746				player.playing = false;
747				$ifr.trigger('ended.autoplaying');
748			});
749			player.addEvent('pause', function(){
750				player.playing = false;
751				$ifr.trigger('click.autoplaying')
752			});
753			
754			$ifr
755			.on('click.autoplaying', function(ev){
756				var autoplay = $ifr.data('autoplay'), player = autoplay.player;
757				if (autoplay && !autoplay.canceled && $ifr.isInView()) {
758					stopAutoPlay($ifr, true, true);
759					player.api('play');
760				}
761			}).on('ended.autoplaying', function(ev){
762				var $ifr = $(this), autoplay = $ifr.data('autoplay'), player = autoplay.player;
763				player.api('seekTo', 0);
764				if (!autoplay.canceled || autoplay.loop) {
765					player.api('play');
766				}
767			}).on('scrolledintoview', function(ev){
768				var $ifr = $(this), autoplay = $ifr.data('autoplay'), player = autoplay.player;
769				if (!autoplay || !autoplay.canceled) {
770					startAutoPlay($ifr);
771				}
772			}).on('scrolledoutofview', function(ev){
773				var $ifr = $(this), autoplay = $ifr.data('autoplay'), player = autoplay.player;
774				if (player.playing){
775					if (autoplay.muted) {
776						player.api('pause');
777					} else {
778						fadeoutVimeo(player);
779					}
780				}
781			});
782			if ($ifr.isInView()) {
783				startAutoPlay($ifr);
784			}
785			
786		});
787		
788	});
789	
790}
791
792/******************/
793if (window._disable_autoplay_onscrolledintoview) { return; }
794
795setInterval(function(){
796	checkAll();
797}, WATCH_INTERVAL);
798
799var youtube_initialized = false;
800function youtubeInit(){
801	if (youtube_initialized) { return; }
802	youtube_initialized = true;
803	console.log('youtubeInit()');
804	var _t = setInterval(function(){
805		if (window.YT && window.YT.Player) {
806			console.log('youtubeInit():window.YT.Player enabled');
807			clearInterval(_t);
808			youtube_iframe_api_initialized = true;
809			['ENDED','PLAYING', 'PAUSED', 'BUFFERING', 'CUED'].forEach(function(s){
810				YT_ST_REV[YT.PlayerState[s]] = s;
811			});
812		}
813	}, 100);
814}
815
816var _onYouTubeIframeAPIReady = window.onYouTubeIframeAPIReady;
817if (_onYouTubeIframeAPIReady) {
818	window.onYouTubeIframeAPIReady = function(){
819		_onYouTubeIframeAPIReady();
820		youtubeInit();
821	};
822} else {
823	window.onYouTubeIframeAPIReady = youtubeInit;
824}
825
826$(document).one('scrolledintoview', YOUTUBE_SELECTOR, function(){
827	if (!window.YT) {
828		$('<'+'script></'+'script>').attr('src', 'https://www.youtube.com/iframe_api').appendTo('body');
829	} else {
830		youtubeInit();
831	}
832});
833
834});

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.