1class gtutYoutubeBannerPlayer { 2 constructor(selector, videoIframe, config) { 3 4 this.videoIframe = videoIframe 5 this.videoId = document.querySelector(`${selector} #${videoIframe}`).getAttribute('data-video-id'); 6 this.overlay = document.querySelector(`${selector} .gtut_yt_overlay`); 7 this.player = null; // å¨é¡å¥ä¸å®ç¾©ææ¾å¨æå¡è®é 8 this.youtubeSettings = { 9 videoId: this.transformVideoId(this.videoId), 10 height: '1440', 11 width: '2560', 12 useCoverImg: true, 13 autoPlay: true, 14 loop: true, 15 bleed: false, 16 playerVars: { 17 controls: 0, 18 fs: 0, 19 iv_load_policy: 3, 20 rel: 0, 21 modestbranding: 1, 22 playsinline: 1, 23 }, 24 events: { 25 onReady: this.onPlayerReady, 26 onStateChange: this.onPlayerStateChange, 27 }, 28 }; 29 this.firstRePlayVideo = true; 30 this.firstInThisSite = sessionStorage.getItem("inThisSite"); 31 if (this.firstInThisSite) { 32 this.firstRePlayVideo = false; 33 } else { 34 sessionStorage.setItem("inThisSite", true); 35 } 36 this.extendConfig = this.extendConfig.bind(this); 37 this.addCoverImg = this.addCoverImg.bind(this); 38 this.removerCoverImg = this.removerCoverImg.bind(this); 39 this.checkLoopShowControls = this.checkLoopShowControls.bind(this); 40 // Call initialization function 41 this.playerInitialized = false; 42 this.apiLoaded = false; 43 this.init(config); 44 } 45 init(config) { 46 this.youtubeSettings = this.extendConfig(this.youtubeSettings, config); 47 if (!this.youtubeSettings.loop) { 48 this.youtubeSettings.playerVars.controls = 1; 49 } 50 if (!this.apiLoaded) { 51 // å è¼ YT API 52 let existingScript = document.querySelector('script[src="' + 'https://www.youtube.com/iframe_api' + '"]'); 53 if (!existingScript) { 54 const tag = document.createElement('script'); 55 tag.src = 'https://www.youtube.com/iframe_api'; 56 const firstScriptTag = document.getElementsByTagName('script')[0]; 57 firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); 58 } 59 60 // æ è®° API å·²å è½½ 61 this.apiLoaded = true; 62 } 63 64 // console.log('çå¾ '); 65 // çå¾ YT API å è¼å®æ 66 if (window.onYouTubeIframeAPIReady) { 67 const oldCallback = window.onYouTubeIframeAPIReady; 68 window.onYouTubeIframeAPIReady = () => { 69 oldCallback(); 70 this.initPlayer(); 71 } 72 this.initPlayer(); 73 // console.log('yt api ready'); 74 } else { 75 76 window.onYouTubeIframeAPIReady = () => { 77 this.initPlayer(); 78 } 79 80 // console.log(' else'); 81 } 82 // console.log('init'); 83 84 } 85 86 initPlayer() { 87 // console.log('initPlayer'); 88 if (!this.playerInitialized) { 89 const hiddenProperty = 'hidden' in document 90 ? 'hidden' 91 : 'webkitHidden' in document 92 ? 'webkitHidden' 93 : 'mozHidden' in document 94 ? 'mozHidden' 95 : null; 96 const visibilityChangeEvent = hiddenProperty.replace(/hidden/i, 'visibilitychange'); 97 let leaveTime; 98 let backTime; 99 const onVisibilityChange = () => { 100 if (!document[hiddenProperty]) { 101 backTime = Date.now(); 102 if (leaveTime == undefined || backTime > leaveTime + 600000) { 103 location.reload(); 104 } 105 } else { 106 leaveTime = Date.now(); 107 } 108 }; 109 document.addEventListener(visibilityChangeEvent, onVisibilityChange); 110 const that = this 111 function checkYTPlayer() { 112 if (typeof YT !== 'undefined') { 113 // YT exists, create the player 114 that.player = new YT.Player(`${that.videoIframe}`, that.youtubeSettings); 115 } else { 116 // YT does not exist yet, check again after 200 milliseconds 117 setTimeout(checkYTPlayer, 300); 118 } 119 } 120 121 // éå§æª¢æ¥ YT Player 122 checkYTPlayer(); 123 if (this.youtubeSettings.useCoverImg) { 124 this.addCoverImg(this.youtubeSettings.useCoverImg); 125 } 126 if (this.youtubeSettings.bleed && this.youtubeSettings.autoPlay && this.youtubeSettings.loop) { 127 document.querySelector(`#${this.videoIframe}`).classList.add('big_size'); 128 } 129 this.playerInitialized = true; 130 // console.log('playerInitialized'); 131 } 132 } 133 134 transformVideoId(id) { 135 const youtubeVideoIdLength = 11; 136 let newId = ''; 137 if (id.length <= youtubeVideoIdLength) { 138 return id; 139 } 140 if (id.indexOf('watch?v=') > 0) { 141 newId = id.substr(id.indexOf('watch?v=') + 8, youtubeVideoIdLength); 142 } else if (id.indexOf('youtu.be/') > 0) { 143 newId = id.substr(id.indexOf('youtu.be/') + 9, youtubeVideoIdLength); 144 } else if (id.indexOf('/embed/') > 0) { 145 newId = id.substr(id.indexOf('/embed/') + 7, youtubeVideoIdLength); 146 } else { 147 newId = id.substr(id.lastIndexOf('/') + 1, id.length); 148 if (newId.length > youtubeVideoIdLength) { 149 newId = newId.substr(0, youtubeVideoIdLength); 150 } 151 } 152 return newId; 153 } 154 155 addCoverImg(src) { 156 let imgUrl; 157 if (src === true) { 158 imgUrl = `https://img.youtube.com/vi/${this.youtubeSettings.videoId}/maxresdefault.jpg`; 159 const customCoverImg = this.overlay.getAttribute('data-coverimg'); 160 if (customCoverImg) { 161 imgUrl = customCoverImg; 162 } 163 } else { 164 imgUrl = src; 165 } 166 167 this.overlay.style.backgroundImage = `url(${imgUrl})`; 168 } 169 170 removerCoverImg() { 171 this.overlay.style.opacity = 0; 172 } 173 174 extendConfig(a, b) { 175 for (const key in b) if (b.hasOwnProperty(key)) a[key] = b[key]; 176 return a; 177 } 178 179 checkLoopShowControls= () => { 180 if (!this.youtubeSettings.loop) { 181 this.overlay.style.pointerEvents = 'none'; 182 } 183 } 184 185 186 onPlayerReady = (e) => { 187 // console.log('onPlayerReady'); 188 if (this.youtubeSettings.useCoverImg) { 189 this.removerCoverImg(); 190 } 191 if (this.youtubeSettings.autoPlay) { 192 e.target.mute().playVideo(); 193 } else { 194 this.overlay.style.cursor = 'pointer'; 195 this.overlay.addEventListener('click', () => { 196 e.target.playVideo(); 197 this.checkLoopShowControls(); 198 }); 199 } 200 } 201 202 onPlayerStateChange = (event) => { 203 if (event.data === 0 && this.youtubeSettings.loop) { 204 if (this.firstRePlayVideo) { 205 this.player.loadVideoById(this.transformVideoId(this.videoId)); 206 this.firstRePlayVideo = false;
207 } else { 208 event.target.playVideo(); 209 } 210 } 211 if (event.data === 0 && !this.youtubeSettings.loop) { 212 this.checkLoopShowControls(); 213 } 214 } 215} 216
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.