1(function (root, factory) { 2 if (typeof define === 'function' && define.amd) { 3 define([], factory); 4 } else if (typeof module === 'object' && module.exports) { 5 module.exports = factory(); 6 } else { 7 root.webPlayer = factory(); 8 } 9})(this, function () { 10 'use strict'; 11 class webPlayer { 12 constructor(option) { 13 this.option = $.extend({ 14 element:"", 15 }, option); 16 this.audioContext = new (window.AudioContext || window.webkitAudioContext)(); 17 this.sourceNode = null; 18 this.gainNode = this.audioContext.createGain(); 19 this.audioBuffer = null; 20 this.startTime = 0; 21 this.pauseTime = 0; 22 this.isPlaying = false; 23 this._onEnded = this._handleEnded.bind(this); 24 this.playbackRate = 1.0; // é»è®¤æ£å¸¸é度 25 this.volume = 1.0; // é»è®¤é³é 26 this.playlist = []; 27 this.currentIndex = 0; 28 this.onTrackEnd = null; 29 this.onPlaylistEnd = null; 30 this.onTrackError = null; 31 this.AudioElement = this.option.element 32 } 33 async loadAudio(url) { 34 const response = await fetch(url); 35 const arrayBuffer = await response.arrayBuffer(); 36 this.audioBuffer = await this.audioContext.decodeAudioData(arrayBuffer); 37 } 38 _handleEnded() { 39 if (this.isPlaying) { 40 this.isPlaying = false; 41 this.pauseTime = 0; 42 this.sourceNode = null; 43 44 if (this.onTrackEnd) { 45 this.onTrackEnd(this.playlist[this.currentIndex]); 46 } 47 48 this.currentIndex++; 49 if (this.currentIndex < this.playlist.length) { 50 this.loadAndPlay(this.playlist[this.currentIndex]); 51 } else if (this.onPlaylistEnd) { 52 this.hideControl() 53 this.onPlaylistEnd(); 54 } 55 } 56 } 57 async loadAndPlay(url) { 58 try { 59 await this.loadAudio(url); 60 this.play(); 61 } catch (error) { 62 console.error(`å è½½ ${url} 失败:`, error); 63 // å³ä½¿å¤±è´¥ä¹ç»§ç»ææ¾ä¸ä¸ä¸ª 64 this._handleEnded(); 65 } 66 } 67 setPlaylist(tracks, startIndex = 0) { 68 this.playlist = tracks; 69 this.currentIndex = startIndex; 70 } 71 startPlaylist() { 72 if (this.playlist.length > 0) { 73 this.currentIndex = 0; 74 this.loadAndPlay(this.playlist[0]); 75 this.renderControl() 76 } 77 } 78 play() { 79 if (!this.audioBuffer) return; 80 if(this.element){ 81 this.element.addClass('isPlay') 82 } 83 this.stopOtherSourcePlayer() 84 // 妿已æåï¼ä»æåä½ç½®ç»§ç» 85 const offset = this.pauseTime || 0; 86 // å建æ°èç¹ 87 this.sourceNode = this.audioContext.createBufferSource(); 88 this.sourceNode.buffer = this.audioBuffer; 89 // è¿æ¥èç¹ï¼æº â å¢ç â è¾åº 90 this.sourceNode.connect(this.gainNode); 91 this.gainNode.connect(this.audioContext.destination); 92 93 // è®¾ç½®ææ¾é度 94 this.sourceNode.playbackRate.value = this.playbackRate; 95 96 // this.sourceNode.connect(this.audioContext.destination); 97 // è®¾ç½®ç»æåè°ï¼æ³¨æä¸è¦ç¨å¿å彿°ï¼æ¹ä¾¿ç§»é¤ï¼ 98 this.sourceNode.onended = this._onEnded; 99 this.startTime = this.audioContext.currentTime - offset; 100 this.sourceNode.start(0, offset); 101 this.isPlaying = true; 102 this.pauseTime = 0; 103 104 } 105 pause() { 106 if (!this.isPlaying) return; 107 if(this.element){ 108 this.element.removeClass('isPlay') 109 } 110 // 临æ¶ç§»é¤ç»æåè° 111 this.sourceNode.onended = null; 112 // åæ¢ææ¾ 113 this.sourceNode.stop(); 114 this.sourceNode = null; 115 // è®°å½æåä½ç½® 116 this.pauseTime = this.audioContext.currentTime - this.startTime; 117 this.isPlaying = false;
118 console.log('å·²æåï¼ä½ç½®:', this.pauseTime); 119 } 120 stop() { 121 if (this.sourceNode) { 122 // 临æ¶ç§»é¤ç»æåè° 123 this.sourceNode.onended = null; 124 this.sourceNode.stop(); 125 this.sourceNode = null; 126 } 127 this.isPlaying = false; 128 this.pauseTime = 0; 129 } 130 togglePlayPause() { 131 if (this.isPlaying) { 132 this.pause(); 133 } else { 134 this.play(); 135 } 136 } 137 setSpeed(rate) { 138 if(this.element){ 139 let citem = this.element.find('.speedItem[data-value="'+rate+'"]') 140 citem.addClass('active').siblings().removeClass('active') 141 this.element.find('.sppedBtn').text(rate+'x') 142 this.element.find('.speedBar').removeClass('isShow') 143 } 144 this.playbackRate = rate; 145 146 // 妿æ£å¨ææ¾ï¼ç«å³åºç¨æ°é度 147 if (this.sourceNode) { 148 this.sourceNode.playbackRate.value = rate; 149 } 150 } 151 setVolumn(value) { 152 if(this.element){ 153 if(value==0){ 154 this.element.addClass('isMuted') 155 }else{ 156 this.element.removeClass('isMuted') 157 } 158 this.element.find('.volumnBar input').val(value) 159 } 160 this.volume = value; 161 162 // 妿æ£å¨ææ¾ï¼ç«å³åºç¨æ°é度 163 if (this.gainNode) { 164 this.gainNode.gain.value = value; 165 } 166 } 167 // å ¶ä»å®ç¨æ¹æ³ 168 get currentTime() { 169 if (this.isPlaying) { 170 return this.audioContext.currentTime - this.startTime; 171 } 172 return this.pauseTime || 0; 173 } 174 get duration() { 175 return this.audioBuffer ? this.audioBuffer.duration : 0; 176 } 177 // 鿝æ¶éæ¾èµæº 178 dispose() { 179 this.stop(); 180 if (this.audioContext.state !== 'closed') { 181 this.audioContext.close(); 182 } 183 } 184 renderCss(){ 185 if($('#AudioPlayCss').length>0){ 186 return 187 } 188 let css = `.AudioPlay{position:fixed;bottom:20px;left:50%;transform:translateX(-50%);border-radius:6px;box-shadow:0 0 20px rgb(0 0 0 / 10%);background-color:#fff;padding:10px;display:flex;color:#666;font-size:12px;z-index:99;}.AudioPlay .opbtn{display:block;height:32px;line-height:20px;min-width:32px;padding:6px;text-align:center;position:relative;border-radius:4px;transition:all .3s;}.AudioPlay .opbtn svg{display:block;width:20px;height:20px;margin:0;fill:currentColor;}.AudioPlay a:hover{color:#fff;background-color:#409EFF}.AudioPlay .pause,.AudioPlay.isPlay .play,.AudioPlay .volumnClose,.AudioPlay.isMuted .volumnOpen{display:none;}.AudioPlay .play,.AudioPlay.isPlay .pause,.AudioPlay .volumnOpen,.AudioPlay.isMuted .volumnClose{display:block;}.AudioPlay .volumnCon{display:flex;align-items:center;}.AudioPlay .volumnBar{width:90px;height:16px;padding:0 5px;display:flex;align-items:center;}.AudioPlay .volumnBar input{height:4px;width:100%;}.AudioPlay .speedCon{position:relative;}.AudioPlay .speedBar{padding:5px;border-radius:4px;position:absolute;width:80px;background-color:#fff;bottom:50px;right:0;box-shadow:0 0 20px rgb(0 0 0 / 10%);display:none;}.AudioPlay .speedBar.isShow{display:block;}.AudioPlay .speedItem{display:flex;align-items:center;cursor:pointer;padding:5px;border-radius:4px;position:relative;}.AudioPlay .speedItem:before{background:#0000001a;content:"";display:block;flex-shrink:0;height:16px;margin-right:10px;transition:all .3s ease;width:16px;border-radius:50%;}.AudioPlay .speedItem:after{background:#fff;content:"";border:0;height:6px;left:10px;opacity:0;top:50%;transform:translateY(-50%) scale(0);width:6px;position:absolute;border-radius:50%;}.AudioPlay .speedItem.active:before{background:#00b2ff;}.AudioPlay .speedItem.active:after{opacity:1;transform:translateY(-50%) scale(1);}` 189 let style = document.createElement('style'); 190 style.type = 'text/css'; 191 style.id = 'AudioPlayCss' 192 style.innerHTML = css; 193 document.getElementsByTagName('head')[0].appendChild(style); 194 } 195 renderControl(){ 196 this.renderCss(); 197 let dom = `<div class="AudioPlay" id="webPlay_${this.option.cid}_${this.option.eid}"> 198 <div class="playCon"> 199 <a href="javascript:;" class="opbtn play">
199<svg t="1746497108766" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="https://www.w3.org/2000/svg" p-id="7652"><path d="M324.085 95.787l500.422 300.664c82.373 50.453 79.284 136.946-1.030 186.37v0l-506.6 304.784c-41.187 23.683-87.522 37.068-131.798 9.267-36.037-22.653-46.335-58.691-46.335-97.819v-616.774c0-39.127 13.386-75.166 48.395-97.819 45.305-27.801 94.731-14.416 136.946 11.327v0z" p-id="7653"></path></svg></a> 200 <a href="javascript:;" class="opbtn pause"><svg t="1745995311394" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="https://www.w3.org/2000/svg" p-id="14135"><path d="M432 176v672c0 26.5-21.5 48-48 48H224c-26.5 0-48-21.5-48-48V176c0-26.5 21.5-48 48-48h160c26.5 0 48 21.5 48 48zM848 176v672c0 26.5-21.5 48-48 48H640c-26.5 0-48-21.5-48-48V176c0-26.5 21.5-48 48-48h160c26.5 0 48 21.5 48 48z" p-id="14136"></path></svg></a> 201 </div> 202 <div class="volumnCon"> 203 <a href="javascript:;" class="opbtn volumnOpen"><svg t="1745995352893" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="https://www.w3.org/2000/svg" p-id="15288"><path d="M473.088 125.44L256 256H52.224C23.552 256 0 279.552 0 308.224V716.8c0 28.16 23.04 51.2 51.2 51.2h204.8l217.088 130.56c16.896 10.24 38.912-2.048 38.912-22.016V147.456c0-19.968-21.504-32.256-38.912-22.016zM699.904 320.512c-20.992-18.944-53.248-17.408-72.192 3.584-18.944 20.992-17.408 53.248 3.584 72.192 0.512 0.512 58.368 54.784 58.368 121.344 0 37.888-19.456 74.752-58.368 110.08-20.992 18.944-22.528 51.2-3.584 72.192 10.24 11.264 24.064 16.896 37.888 16.896 12.288 0 24.576-4.608 34.304-13.312 61.44-55.296 92.16-117.76 92.16-185.856 0-112.64-88.576-193.536-92.16-197.12z" fill="" p-id="15289"></path><path d="M853.504 166.4c-20.992-18.944-53.248-16.896-72.192 4.096-18.944 20.992-16.896 53.248 4.096 72.192 1.536 1.024 135.68 122.88 135.68 280.576 0 90.624-45.568 177.152-135.68 257.536-20.992 18.944-23.04 51.2-4.096 72.192 10.24 11.264 24.064 16.896 38.4 16.896 12.288 0 24.576-4.096 34.304-12.8 112.64-100.864 169.984-212.992 169.984-333.824-1.024-202.752-163.84-350.208-170.496-356.864z" fill="" p-id="15290"></path></svg></a> 204 <a href="javascript:;" class="opbtn volumnClose"><svg t="1745995429643" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="https://www.w3.org/2000/svg" p-id="16264"><path d="M256 768H51.2c-28.16 0-51.2-23.04-51.2-51.2V308.224C0 279.552 23.552 256 52.224 256H256v512zM512 147.456v728.576c0 19.968-21.504 32.256-38.912 22.016L256 768V256l217.088-130.56c17.408-10.24 38.912 2.048 38.912 22.016zM623.104 656.896c-19.968-19.968-19.968-52.224 0-72.192l217.088-217.088c19.968-19.968 52.224-19.968 72.192 0 19.968 19.968 19.968 52.224 0 72.192l-217.088 217.088c-19.456 19.968-52.224 19.968-72.192 0z" fill="" p-id="16265"></path><path d="M623.104 367.104c19.968-19.968 52.224-19.968 72.192 0l217.088 217.088c19.968 19.968 19.968 52.224 0 72.192-19.968 19.968-52.224 19.968-72.192 0l-217.088-217.088c-19.968-19.456-19.968-52.224 0-72.192z" fill="" p-id="16266"></path></svg></a> 205 <div class="volumnBar"> 206 <input class="volumnInput" type="range" min="0" max="1" step="0.05" value="1" autocomplete="off" role="slider" /> 207 </div> 208 </div> 209 <div class="speedCon"> 210 <a href="javascript:;" class="opbtn sppedBtn">1x</a> 211 <div class="speedBar"> 212 <a href="javascript:;" class="speedItem" data-value="0.5"><span>0.5x</span></a> 213 <a href="javascript:;" class="speedItem" data-value="0.75"><span>0.75x</span></a> 214 <a href="javascript:;" class="speedItem active" data-value="1.0"><span>1.0x</span></a> 215 <a href="javascript:;" class="speedItem" data-value="1.25"><span>1.25x</span></a> 216 <a href="javascript:;" class="speedItem" data-value="1.5"><span>1.5x</span></a> 217 <a href="javascript:;" class="speedItem" data-value="1.75"><span>1.75x</span></a> 218 <a href="javascript:;" class="speedItem" data-value="2.0"><span>2.0x</span></a> 219 </div> 220 </div> 221 </div>` 222 this.playbackRate = 1.0; // é»è®¤æ£å¸¸é度 223 this.volume = 1.0; // é»è®¤é³é 224 this.element = $(dom) 225 this.AudioElement.append(this.element) 226 this.element.addClass('isPlay') 227 this.controlEvent() 228 } 229 controlEvent(){ 230 this.element.on("click",'.play',()=>{ 231 this.play() 232 }).on('click','.pause',()=>{ 233 this.pause() 234 }).on('click','.volumnOpen',()=>{ 235 this.setVolumn(0) 236 }).on('click','.volumnClose',()=>{ 237 this.setVolumn(1) 238 }).on('input','.volumnInput',(e)=>{ 239 let v = $(e.currentTarget).val() 240 this.setVolumn(v) 241 }).on('click','.sppedBtn',()=>{ 242 this.element.find('.speedBar').addClass('isShow') 243 }).on('click','.speedItem',(e)=>{ 244 let v = $(e.currentTarget).attr('data-value') 245 this.setSpeed(v) 246 }) 247 $(document).click((e)=> { 248 var pop = this.element.find(".speedBar,.speedItem,.sppedBtn") 249 if(!pop.is(e.target) && pop.has(e.target).length === 0) { 250 this.element.find('.speedBar').removeClass('isShow') 251 } 252 }); 253 } 254 hideControl(){ 255 this.element.remove() 256 } 257 stopOtherSourcePlayer(){ 258 for (let key in window.sourcePlayer) { 259 if (key != `${this.option.cid}_${this.option.eid}`) { 260 window.sourcePlayer[key].pause(); 261 } 262 } 263 } 264 } 265 return webPlayer; 266});
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.