1IRON = window.IRON || {}; 2(function ($) { 3 /*=============================================================================== 4 ##### This file is available in both MP3 Audio Player Settings and Frontend ##### 5 ===============================================================================*/ 6 7 IRON.peaksCache = {}; // Cache peaks to avoid fetching them multiple times 8 var loadFakeWaveOnly; 9 10 IRON.init_generatePeaks = function (player = false){ 11 if (loadFakeWaveOnly) return; 12 13 if(player && player.stickyPlayer){ 14 return; 15 } 16 17 var peakFile = false; 18 19 if( player && typeof player.currentTrack != 'undefined'){ 20 peakFile = player.list.tracks[player.currentTrack].peakFile; 21 }else{ 22 peakFile = IRON.sonaar.player.list.tracks[IRON.sonaar.player.currentTrack].peakFile; 23 } 24 25 if (!peakFile) { 26 let audioSource = player ? player : IRON.sonaar.player; 27 28 if (audioSource) { 29 let currentTrack = audioSource.list.tracks[audioSource.currentTrack]; 30 if (currentTrack) { 31 if (currentTrack.peak_allow_frontend) { 32 IRON.generatePeaks([{ 33 "file": currentTrack.mp3, 34 "post_id": currentTrack.sourcePostID, 35 "media_id": currentTrack.id, 36 "index": currentTrack.track_pos, 37 "is_preview": currentTrack.isPreview, 38 "peak_file_type": currentTrack.peak_allow_frontend, 39 }]); 40 } 41 } 42 } 43 } 44 } 45 46 IRON.generatePeaks = async function(files) { 47 // Base condition to stop recursion 48 audioContext = new (window.AudioContext || window.webkitAudioContext)(); 49 50 console.log('We are generating the soundwave ...'); 51 52 const file = files[0]; 53 54 try { 55 const MAX_SIZE = 200 * 1024 * 1024; // 10MB in bytes 56 const response = await fetch(file.file); 57 if (!response.ok) { 58 throw new Error(`HTTP error! Status: ${response.status}`); 59 } 60 const contentLength = response.headers.get('Content-Length'); 61 const fileSizeMB = parseInt(contentLength, 10) / (1024 * 1024); 62 63 if (!isFirefox() && contentLength && parseInt(contentLength, 10) > MAX_SIZE) { 64 // This will return false if contentLength is NaN 65 console.log(`File is too large ( > 200MB) to generate waveform in this browser. Use Firefox to generate it for the first time. (${fileSizeMB.toFixed(2)} MB). Skipping: ${file.file}`); 66 return; // Skip this file 67 } 68 69 console.log(`File is ${fileSizeMB.toFixed(2)} MB. Analyzing waveform of: ${file.file}`); 70 const arrayBuffer = await response.arrayBuffer(); 71 try { 72 73 var audioBuffer = await audioContext.decodeAudioData(arrayBuffer); 74 let peaks = IRON.extractPeaks(audioBuffer); 75 IRON.updatePeaksOnServer(file.post_id, file.media_id, file.index, peaks, file.file, file.is_temp, file.is_preview, file.peak_file_type); 76 // Attempt to release the audioBuffer memory 77 audioBuffer = null; 78 79 } catch (decodeError) { 80 console.error('Error decoding file:', file.file, decodeError); 81 } 82 } catch (fetchError) { 83 console.error('Error fetching file:', file.file, fetchError); 84 } 85 86 function isFirefox() { 87 return navigator.userAgent.toLowerCase().indexOf('firefox') > -1; 88 } 89 90 } 91 92 IRON.extractPeaks = function(audioBuffer, peakLength = 1920) { 93 const channels = audioBuffer.numberOfChannels; 94 const sampleSize = audioBuffer.length / peakLength; 95 const sampleStep = ~~(sampleSize / 10) || 1; 96 const peaks = []; 97 98 for (let c = 0; c < channels; c++) { 99 const chan = audioBuffer.getChannelData(c); 100 101 for (let i = 0; i < peakLength; i++) { 102 let start = ~~(i * sampleSize); 103 let end = ~~(start + sampleSize); 104 let min = chan[0]; 105 let max = chan[0]; 106 107 for (let j = start; j < end; j += sampleStep) { 108 const value = chan[j]; 109 if (value > max) max = value; 110 if (value < min) min = value; 111 } 112 113 if (c === 0 || max > peaks[2 * i]) { 114 peaks[2 * i] = Math.abs(max.toFixed(2)); 115 } 116 if (c === 0 || min < peaks[2 * i + 1]) { 117 peaks[2 * i + 1] = Math.abs(min.toFixed(2)); 118 } 119 } 120 } 121 return peaks; 122 } 123 124 IRON.updatePeaksOnServer = function(postId, media_id, index, peaks, file = null, is_temp = null, is_preview = null, peak_file_type = null) { 125 peaks = peaks.join(',').replace(/0\./gi,'.') 126 $.ajax({ 127 url: sonaar_music.ajax.ajax_url, 128 type: 'POST', 129 dataType: 'json', 130 data: { 131 action: 'update_audio_peaks', 132 nonce: sonaar_music.ajax.ajax_nonce_peaks, 133 post_id: postId, 134 media_id: media_id, 135 index: index, 136 file: file, 137 peaks: peaks, 138 is_temp: is_temp, 139 is_preview: is_preview, 140 peak_file_type: peak_file_type, 141 }, 142 success: function(response) { 143 console.log('Peaks updated for media_id:', media_id, ' post_id:', postId, 'index:', index, response); 144 }, 145 error: function(jqXHR, textStatus, errorThrown) { 146 console.error("Error updating peaks: ", textStatus, errorThrown); 147 } 148 }); 149 } 150 IRON.addDownloadSVGButton = function() { 151 IRON.addDownloadSVGButton.saveSVG = true; 152 153 var btn = document.createElement("button"); 154 btn.innerHTML = "Download SVG"; 155 btn.style.position = "absolute"; 156 btn.style.top = "50px"; 157 btn.style.left = "50px"; 158 btn.style.zIndex = "9999"; 159 160 btn.onclick = function() { 161 downloadSVG(IRON.addDownloadSVGButton.svgString); 162 }; 163 document.body.prepend(btn); 164 165 function downloadSVG(svgData) { 166 var blob = new Blob([svgData], { type: 'image/svg+xml' }); 167 var url = URL.createObjectURL(blob); 168 var a = document.createElement('a'); 169 a.href = url; 170 a.download = 'soundwave.svg'; 171 document.body.appendChild(a); 172 a.click(); 173 setTimeout(function() { 174 document.body.removeChild(a); 175 window.URL.revokeObjectURL(url); 176 }, 0); 177 } 178 179 }
180 createFakeWave = function (audioPlayer = true, imSticky = false, singleTrack = false) { 181 if(!imSticky && !singleTrack && audioPlayer.remove_wave) return; 182 183 if(sonaar_music.option.music_player_load_fakewave_only == 'on') loadFakeWaveOnly = true; 184 185 if (imSticky && sonaar_music.option.sticky_spectro_container == 'inside' && sonaar_music.option.sticky_spectro_style != 'none') { 186 return; // Early return if specific conditions are met 187 } 188 189 var waveId; 190 if(singleTrack && singleTrack.index() < 20){ // for better performance, only manage the first 20 tracks. 191 waveId = getWaveIdentifier(audioPlayer, imSticky, singleTrack); 192 }else if(imSticky || audioPlayer && !singleTrack){ 193 waveId = getWaveIdentifier(audioPlayer, imSticky, singleTrack); 194 } 195 196 if (!waveResizeHandlers.has(waveId)){ 197 // Debounced resize handler for this specific wave 198 // Store the initial width 199 let windowWidth = window.innerWidth; 200 201 const debouncedResizeHandler = debounce(() => { 202 // Check if the width has changed 203 if (window.innerWidth !== windowWidth) { 204 createFakeWave(audioPlayer, imSticky, singleTrack); 205 // Update the stored width 206 windowWidth = window.innerWidth; 207 } 208 }, 250); 209 210 // Add the resize listener and store the handler in the map 211 window.addEventListener('resize', debouncedResizeHandler); 212 waveResizeHandlers.set(waveId, debouncedResizeHandler); 213 } 214 215 216 var peaks = []; 217 var barGap; 218 var barWidth; 219 var lineCap; 220 var fadeDuration; 221 var totalBarWidth; 222 var waveBaseDiv; 223 var waveBaseWidth; 224 var canvasWidth; 225 var canvasHeight; 226 var desiredNumBars; 227 var downsamplingFactor; 228 var numBars; 229 230 var peakFile = singleTrack && singleTrack.attr('data-peakFile') != '' ? singleTrack.attr('data-peakFile') : 231 // If 'singleTrack' condition was false, check if 'imSticky' is truthy 232 imSticky ? IRON.sonaar.player.list.tracks[IRON.sonaar.player.currentTrack].peakFile : 233 // If 'imSticky' condition was false, check if 'audioPlayer' exists, 'audioPlayer.currentTrack' is defined, and the current track has a non-empty 'data-peakFile' attribute 234 !singleTrack && audioPlayer && typeof audioPlayer.currentTrack != 'undefined' && audioPlayer.find('sr-playlist-item').eq(audioPlayer.currentTrack).attr('data-peakFile') != '' ? audioPlayer.find('.sr-playlist-item').eq(audioPlayer.currentTrack).attr('data-peakFile') : 235 // If none of the above conditions were met, set 'peakFile' to false 236 false; 237 238 var defaultPeaks = "000010101110101110101011111010111011111111111011111111211111111111112121112121111121212121211121112232111121313121112222122221512132213121313121214242313222312132322131423131413132313122223132323222212221214222@=IGHJJ<C?==9=:5:96455568357;5543;62;5377058974285788228628436714217747328825538633625626746736578643454635555460353434678442662533491561562745573344453444575335442434553:7@HCLB9=C;<9<95455774235666473782354464453372546671634354443673>G:NCCBA=;843352463453386757465563784252443563533372332551223354F;DE?89?=:A;:<@=98554475367:66636575444573D=CMDA@C:9;<==;8<97762345353444553333432453241655463644443533222433334446452323443223344565775523345425232333233312232223332122222324123233222232322322222311222111131129B:?CCLN@F9;;:668334222223334526255445322232523153338232324323329AA?G@7EB><;:645235142524956:27:56434343324332335192514224234322;>F<@HC?>=87833432323260596659445456542332BGN<IDIBGABCA>C65@?<<<<7743445455476534333415663834744544432323222323334326644222232478595<7@<;=><>?;><54;:6575241322232222222213131434433222122212121113122222311211121C2NLFQHA:G@DE>=>C@??;;:82873346643354535233253433341354333422222J2=>FMC@BE=9<:44332231:6:<9>;???>><??6<@>;>;:8563383343333363222E5=@AG?>?:<=?8=<=><96832553545554334445442J2GALPD<:KBJBG?A=C=:7><867744434556432233443254444735254444454244422423434435543322432;988@<=<>?>:=A??<9;;;638524233322132232233423252333434224232224232232333322121222332?HK9BBGQC?B?=EBB;K==>C;;74336865763532534334547354435442245443:3?HF<>A?A85:;;?646453<4;889C;?@:??>@>9>@77;@89:;24164736442534289FIC=A@<>?<:97856846756489:9:86663567579544E??GFBNGA?<8E<HA??9AB8=99878753854<48:9269:69496>:5348766355505416857769645655764537@::?@CFHF<A?HA?@ABA;;=57742574766584553662713593551573432573452582646472336574546354AKJRPGIJHDG?BCIA:@A5<<?7875464657:673572546681555472542374356463ILI>FL=9;;663474525596?=8=EB?A@@G:AA@@@<9>:4988295<3554454455363>A>?FI?B?;?:>9>=:874549373:872568634648662IJDBH<FEH;>OFF?F=CAB?=5884955586567444959345767469859665647874557564635375636264856377>?::E?F<?HB@?;6@@8<A@;8:34537362567364335686665543545353586444535682345552745443847?BOQHEIDCFH@7?CC<D66>;55:7553544788765766;355587473559675467677O;
238O:EJBA?CA;8676737464::@::=@NA?JD=BB@AC<>>98;928665839656;47585;C;CMC<B=A=;84;776946566436927464465453543WJNVMCXQTJLF8GB8;9>7<<@5@DH?BEI9BC=;6;8;:8>989;:CC@CE>?B<A@<<CC6>;?>EB:>>9=B;A=?9??9;BSCENQ?HCIFRG=465;998==D<E?FB>F@=ADA;:76:<8;=B@HEIKM;DBCG?=EBD@BD@?>>BBC9>AAD<D@=?<9?IIHHPO_QNGWCDC=:=D=77=D7?DJ55HF94?@39;95>:9<C?E:C@?@@@=?@<>>=:9IB2SJFJEMCBG@<=FJMA?@JIFMHCBKMBZI9D=59:B3<;=66CE>F@A<<@F:;886;9:>IIM>NLNDDLH>EDID@FABD<@DB>A>?A@=>>@9;>:B>??SXKXVPSGKUFE?DH87><<8A<CDDI@ACA;<;8962695;@=>A<?D?5@<FG<;BAG@7C?;IDD;>@E=;<<AG<@C>:MBE=@KTLMHM?IA9<86:07:E44;I85HE97EB:6=<6:8<;D=?<8IEEB;=BED<@9;BB@<;<GC=B:=D<?@<=D=ANY?KOVPRTWRS@?A<@B@@<<@>1>?F5CGG<9E<168:597>4@8;79:;=G==995C>?::5KCMFJAEGEQ>E?IA7<3:C?NE<QEKKPMIGPBE97D8673;9A;EFIGG@A;8;>35:95:8L@GQE@@BFCKFJ==4@AHB;5?6GA>8<;@=<:@AD89;<MbQO[PKPRKGI?FC9=;@?9C=>77BH99CJ<5A<936;9965=99<?C:ED>?;BL;B>CF;=A>MF?=C@>@;>>4:?><>=?PWBOTJWNAOC9?67:7:88<E54GJB;GB9:DF=6;;9@9?I8DD8B?EJ@CFG@>;:D?=?GIA??9?9C=@@?:@9BD;AA<QHMAZJWMONQLI<G8@;:;7<B:D<C@J@NE?@<9=:C9C@J>CJRIC7FDDCC?D=D<6D>C@EMHFANFDFFCG@H8>DXEQK??F?EGNEUIB;=6<?=47;=>8?JC<@@57EC=7:=2:7LHHDADPABKJQQ?E@CADFC:EA?EJ@NFB>@>EB?97A<<CPHQQPPLRJNQW<98=?F87CH8<@ED3BN9<HD<ED@=;=B@IF=DC===B:::F6<@8:>=@9>B?8D>BA@A>?>>?<=7JKOPTZGGGGN>MJIBKB=5F>CB=HOJ?I?@AHB;ECB=H<=DNCOMNBEFE@=7C9<<<;7:;9?6@<@;:9=7=54586:75@SOLKYSFFCFUPEBOB=KNF;CD6<JRD<IC=IGOE=?=85;CA?<=A?<:;8<D<>5@;A49:8;=;I?8@<4<=9:<67784946:8:;274839667:77487967657638367938756748445735635:36474645496845346824556533446747546513331254673444233325443432341221252533342323331232232313243323221222231313332113221222121222112212211212111212111111111111111112111111111111111101111111110111110111111101000100000000000000000000000000000000000000000000000000000000000000000"; 239 240 async function getPeaksFromJSON(peakFile) { 241 if (IRON.peaksCache[peakFile]) { 242 //console.log('get file from cache : ', peakFile); 243 return IRON.peaksCache[peakFile]; 244 } else if (IRON.peaksCache[peakFile] === undefined) { 245 // Store a promise in the cache for the ongoing fetch 246 //console.log('load the peak! : ', peakFile); 247 IRON.peaksCache[peakFile] = fetch(peakFile) 248 .then(response => response.text()) 249 .then(peaksData => { 250 const peaks = peaksData.split('').map(c => (c.charCodeAt() - 48) / 100); 251 return peaks; 252 }); 253 254 return IRON.peaksCache[peakFile]; 255 } else { 256 // Wait for the ongoing fetch to complete 257 return await IRON.peaksCache[peakFile]; 258 } 259 } 260 261 262 function shuffleArray(array) { 263 for (let i = array.length - 1; i > 0; i--) { 264 const j = Math.floor(Math.random() * (i + 1)); 265 [array[i], array[j]] = [array[j], array[i]]; // Swap elements 266 } 267 } 268 269 (async () => { 270 271 if (loadFakeWaveOnly || !peakFile) { //If we force fakewave from plugin option or peakfile does not exist 272 peaks = defaultPeaks.split('').map(c => (c.charCodeAt() - 48) / 100); 273 shuffleArray(peaks); 274 } else { 275 peaks = await getPeaksFromJSON(peakFile); 276 } 277 const progressType = ( singleTrack && typeof audioPlayer.data('tracklist-soundwave-style') !== 'undefined' ) ? audioPlayer.data('tracklist-soundwave-style') : audioPlayer.progressType; 278 279 function initCreateWaves(){ 280 if (!imSticky && progressType == "simplebar" || imSticky && sonaar_music.option.waveformType == "simplebar") return; 281 282 const container = sr_canvas_container; 283 const $waveParent = $(container).parents('.sonaar_fake_wave'); 284 const $waveCut = $waveParent.find('.sonaar_wave_cut'); 285 286 $waveCut.css('display', 'none'); 287 if( !$waveCut.attr('style').includes('width:') ){ 288 $waveCut.css('width', '0px'); 289 } 290 waveBaseDiv = container.closest(".sonaar_fake_wave"); 291 if(typeof $waveParent.data('width') === 'undefined'){ 292 waveBaseWidth = waveBaseDiv.clientWidth; 293 $waveParent.data('width', waveBaseWidth); 294 }else{ 295 waveBaseWidth = $waveParent.data('width'); 296 } 297 298 canvasWidth = (waveBaseWidth != 0) ? waveBaseWidth : 1000; //Set the width to 1000 when `waveBaseWidth` is 0 to prevent players from tabs, accordions, and other hidden elements from having a canvas width of 0. 299 canvasHeight = container.height; 300 301 barWidth = parseInt($(container).parents('[data-wave-bar-width]').attr('data-wave-bar-width'),10) || parseInt(sonaar_music.option.music_player_barwidth, 10) || 2; // Adjust as needed 302 lineCap = $(container).parents('[data-wave-line-cap]').attr('data-wave-line-cap') || sonaar_music.option.music_player_linecap || 'square'; // Can be 'butt', 'round', or 'square' 303 304 if($(container).parents('[data-wave-bar-gap]').length){//if shortcode parameters is set 305 barGap = parseInt($(container).parents('[data-wave-bar-gap]').attr('data-wave-bar-gap'),10); 306 }else if(typeof sonaar_music.option.music_player_bargap !== 'undefined'){ // plugin option 307 barGap = parseInt(sonaar_music.option.music_player_bargap, 10); 308 }else{ 309 barGap = 0; 310 } 311 312 if($(container).parents('[data-wave-fadein]').length){ //if shortcode parameters is set 313 fadeDuration = ($(container).parents('[data-wave-fadein]').attr('data-wave-fadein')==='false')? 1 : 350; 314 }else if(typeof sonaar_music.option.music_player_wave_disable_fadein !== 'undefined'){ // plugin option 315 fadeDuration = ( sonaar_music.option.music_player_wave_disable_fadein !== 'on')? 350 : 1; 316 }else{ 317 fadeDuration = 350; // Duration in milliseconds for each bar to fully appear 318 } 319 if(singleTrack){ 320 fadeDuration = 1; 321 } 322 323 totalBarWidth = barWidth + barGap; 324 desiredNumBars = canvasWidth / totalBarWidth; 325 downsamplingFactor = peaks.length / desiredNumBars; // Calculate the downsampling factor dynamically based on desired number of bars
326 numBars = Math.ceil(peaks.length / downsamplingFactor); 327 if(typeof waveColor === 'undefined'){ 328 waveColor = (imSticky) ? '#606060' : '#000000'; 329 330 }; 331 if(typeof waveProgressColor === 'undefined'){ 332 waveProgressColor = (imSticky) ? '#FFF' : '#202020'; 333 }; 334 335 createWaves(sr_canvas_container, waveColor, lineCap); 336 createWaves(sr_canvas_progress, waveProgressColor, lineCap); 337 338 } 339 340 function createWaves(container, waveColor, lineCap) { 341 const canvas = container; 342 const ctx = canvas.getContext("2d"); 343 canvas.height = canvasHeight; 344 ctx.lineCap = lineCap; 345 ctx.lineWidth = Math.floor(barWidth); // Ensure integer value 346 var imProgressBar = false; 347 if($(container).parents('.sonaar_wave_cut').length){ 348 imProgressBar = true; 349 } 350 //canvas.width = waveBaseWidth; 351 /*console.log('------------------'); 352 console.log(audioPlayer[0]); 353 console.log("Peaks Length Total: ", peaks.length); 354 console.log("Canvas Width:", canvasWidth); 355 console.log("totalBarWidth:", totalBarWidth); 356 console.log("desiredNumBars:", desiredNumBars); 357 console.log("downsamplingFactor:", downsamplingFactor); 358 console.log("numBars:", numBars);*/ 359 var barColor; 360 if (waveColor.substring(0, 3) === "rgb") { 361 barColor = reformatRgb(waveColor); 362 }else{ 363 barColor = hexToRgb(waveColor); 364 } 365 366 const startTime = Date.now(); // Start time of the animation 367 368 369 370 function drawBars() { 371 if(!imSticky && !singleTrack && IRON.addDownloadSVGButton.saveSVG){ 372 IRON.addDownloadSVGButton.svgElements = []; 373 } 374 ctx.clearRect(0, 0, canvasWidth, canvasHeight); // Clear the canvas 375 376 const currentTime = Date.now(); 377 let anyBarNotFullyOpaque = false; 378 const modifHeight = (lineCap === 'butt') ? 0 : barWidth; 379 const maxHeight = Math.floor((canvasHeight - modifHeight) * 2); 380 const maxPeak = Math.max(...peaks); 381 const scalingFactor = maxHeight / (maxPeak * 2); 382 383 for (let i = 0; i < numBars; i++) { 384 const index = Math.floor(i * downsamplingFactor); 385 let barHeight = peaks[index] * scalingFactor; 386 if(imProgressBar){ 387 barHeight = barHeight + 2.5; 388 } 389 barHeight = Math.floor(barHeight); 390 barHeight = barHeight === 1 ? 2 : barHeight; 391 const x = Math.floor(i * (barWidth + barGap)); 392 const y = Math.round((canvasHeight - barHeight)/2); 393 const timeElapsed = currentTime - startTime; 394 let opacity = (timeElapsed - i * (fadeDuration / numBars)) / fadeDuration; 395 opacity = Math.min(Math.max(opacity, 0), barColor.a); // Ensure opacity doesn't exceed initial alpha value 396 ctx.strokeStyle = `rgba(${barColor.r}, ${barColor.g}, ${barColor.b}, ${opacity})`; 397 398 ctx.beginPath(); 399 ctx.moveTo(x + barWidth / 2, y); 400 ctx.lineTo(x + barWidth / 2, y + barHeight); 401 ctx.stroke(); 402 403 if(!imSticky && !singleTrack && IRON.addDownloadSVGButton.saveSVG){ 404 IRON.addDownloadSVGButton.svgElements.push(`<rect x="${x}" y="${y}" width="${barWidth}" height="${barHeight+1}" fill="#000000" rx="roundingValue" ry="roundingValue"/>`); 405 406 //square IRON.addDownloadSVGButton.svgElements.push(`<rect x="${x}" y="${y}" width="${barWidth}" height="${barHeight+1}" fill="#000000"/>`); 407 } 408 409 if (opacity < barColor.a) { 410 anyBarNotFullyOpaque = true; 411 } 412 413 } 414 415 if(!imSticky && !singleTrack && IRON.addDownloadSVGButton.saveSVG){ 416 IRON.addDownloadSVGButton.svgString = `<svg width="${canvasWidth}" height="${canvasHeight}" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${canvasWidth} ${canvasHeight}">${IRON.addDownloadSVGButton.svgElements.join('')}</svg>`; 417 } 418 if (anyBarNotFullyOpaque) { 419 requestAnimationFrame(drawBars); 420 } 421 } 422 423 drawBars(); // Start the animation 424 $(container).parents('.sonaar_fake_wave').find('.sonaar_wave_cut').css('display', 'inherit'); 425 426 427 }; 428 429 function hexToRgb(hex) { 430 let r = 0, g = 0, b = 0, a = 1; 431 432 // Remove the hash at the start if it's there 433 hex = hex.replace(/^#/, ''); 434 435 if (hex.length === 3) { // Convert #RGB to #RRGGBB 436 hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2]; 437 } 438 439 if (hex.length === 6) { // Process it as #RRGGBB 440 r = parseInt(hex.slice(0, 2), 16); 441 g = parseInt(hex.slice(2, 4), 16); 442 b = parseInt(hex.slice(4, 6), 16); 443 } else if (hex.length === 8) { // Process it as #RRGGBBAA 444 r = parseInt(hex.slice(0, 2), 16); 445 g = parseInt(hex.slice(2, 4), 16); 446 b = parseInt(hex.slice(4, 6), 16);
447 a = parseInt(hex.slice(6, 8), 16) / 255; 448 } 449 return { r, g, b, a }; 450 } 451 452 function reformatRgb(color) { 453 const colorValues = color.match(/(\d+(\.\d+)?)%?/g).map(Number); 454 const isRGBA = color.includes("rgba"); 455 const alpha = isRGBA ? colorValues[3] : 1; 456 return { 457 r: colorValues[0], 458 g: colorValues[1], 459 b: colorValues[2], 460 a: alpha 461 }; 462 } 463 464 var waveColor = $(audioPlayer).attr('data-wave-color') || audioPlayer.soundwaveColorBG || sonaar_music.option.music_player_timeline_color; 465 var waveProgressColor = $(audioPlayer).attr('data-wave-progress-color') || audioPlayer.soundwaveProgressColor || sonaar_music.option.music_player_progress_color; 466 467 if(singleTrack){ 468 if(typeof audioPlayer.data('tracklist-wave-color') != 'undedined') { 469 waveColor = audioPlayer.data('tracklist-wave-color') || sonaar_music.option.music_player_timeline_color; 470 } 471 if(typeof audioPlayer.data('tracklist-wave-progress-color') != 'undedined') { 472 waveProgressColor = audioPlayer.data('tracklist-wave-progress-color') || sonaar_music.option.music_player_progress_color; 473 } 474 } 475 476 477 /*if (IRON.isSonaarTheme && srp_pluginEnable) { 478 IRON.audioPlayer.stickyEnable = true; 479 }*/ 480 481 if (imSticky && sonaar_music.option.waveformType == "simplebar" ) { 482 // set the heights of the bars 483 let barHeight = (typeof sonaar_music.option.sr_soundwave_height_simplebar !== 'undefined') ? sonaar_music.option.sr_soundwave_height_simplebar + "px" : ""; 484 let cssCode = '.sonaar_fake_wave .sonaar_wave_base, .sonaar_fake_wave .sonaar_wave_cut, div#sonaar-player .srp_extendedPlayer_container .sr_progressbar_sticky .wave{ height: ' + barHeight +' !important;}'; 485 let $inlineStyle = $("#sonaar-music-inline-css"); 486 487 if ($inlineStyle.length === 0 || !$inlineStyle.text().includes(cssCode)) { 488 $inlineStyle.append(cssCode); 489 } 490 491 } 492 493 // RETURN IF SIMPLE BAR IS USED - NO NEED TO CREATE FAKEWAVES. This is 100% sur that sticky and player are simplebar. 494 if (sonaar_music.option.waveformType == "simplebar" && progressType !== "mediaElement") { 495 return; 496 } 497 498 if( progressType == "simplebar" ){ 499 audioPlayer = false; // set audio player to false because we wont use it anymore 500 } 501 502 503 if(singleTrack){ 504 505 var soundwaveWrapper = $(singleTrack).find('.srp_soundwave_wrapper'); 506 //soundwaveWrapper.css('width', '100%'); 507 soundwaveWrapper.find('.sonaar_fake_wave').css('height', '40px').css('margin-top', '0px').css('margin-bottom', '0px'); 508 509 var sr_canvas_container = $(singleTrack).find('.sonaar_wave_base canvas')[0]; 510 var sr_canvas_progress = $(singleTrack).find('.sonaar_wave_cut canvas')[0]; 511 containerHeight = $(singleTrack).find(".sonaar_fake_wave").css("height"); 512 sr_canvas_container.height = parseInt(containerHeight, 10); 513 sr_canvas_progress.height = parseInt(containerHeight, 10); 514 515 }else if ( audioPlayer ) { 516 517 var sr_canvas_container = $(audioPlayer).find('.album-player .sonaar_wave_base canvas')[0]; 518 var sr_canvas_progress = $(audioPlayer).find('.album-player .sonaar_wave_cut canvas')[0]; 519 520 if( $(audioPlayer).find(".album-player .sonaar_fake_wave").css("height") === "0px" ){ 521 $(audioPlayer).find(".album-player .sonaar_fake_wave").css("height", "70px"); 522 }; 523 524 containerHeight = $(audioPlayer).find(".album-player .sonaar_fake_wave").css("height"); 525 526 527 sr_canvas_container.height = parseInt(containerHeight, 10); 528 sr_canvas_progress.height = parseInt(containerHeight, 10); 529 530 531 if(!imSticky){ 532 audioPlayer.find('.album-player .sonaar_wave_base').css('background-color', 'unset'); 533 audioPlayer.find('.album-player .sonaar_wave_cut').css('background-color', 'unset'); 534 } 535 536 } 537 //CREATE THE RANDOM PEAK BARS with conditions to prevent to many if. numBars is pretty high 538 if( !imSticky && typeof sr_canvas_container !== 'undefined' && sr_canvas_container !== null ){ 539 // PLAYER 540 initCreateWaves(); 541 return; 542 } 543 544 545 if(imSticky ){ 546 // STICKY PLAYER 547 var sr_canvas_container = document.getElementById('splayer
547-wave-container'); 548 var sr_canvas_progress = document.getElementById('splayer-wave-progress'); 549 550 //set soundwave colors 551 if (typeof IRON.audioPlayer.activePlayer !== 'undefined' && IRON.audioPlayer.activePlayer.adaptiveColors && sonaar_music.option.sticky_player_disable_adaptive_colors != 'true'){ 552 waveColor = (typeof IRON.audioPlayer !== 'undefined' && typeof IRON.audioPlayer.activePlayer.adaptiveColors !== 'undefined') ? IRON.audioPlayer.activePlayer.paletteColorsHex[2] : sonaar_music.option.sticky_player_soundwave_bars; 553 waveProgressColor = (typeof IRON.audioPlayer !== 'undefined' && typeof IRON.audioPlayer.activePlayer.adaptiveColors !== 'undefined') ? IRON.audioPlayer.activePlayer.paletteColorsHex[1] : sonaar_music.option.sticky_player_soundwave_progress_bars; 554 }else{ 555 waveColor = sonaar_music.option.sticky_player_soundwave_bars; 556 waveProgressColor = sonaar_music.option.sticky_player_soundwave_progress_bars; 557 } 558 559 initCreateWaves(); 560 return; 561 } 562 })(); 563 }; 564 565 // Debounce function 566 function debounce(func, wait) { 567 let timeout; 568 return function(...args) { 569 const context = this; 570 clearTimeout(timeout); 571 timeout = setTimeout(() => func.apply(context, args), wait); 572 }; 573 } 574 575 // Function to generate a unique identifier for each wave 576 function getWaveIdentifier(audioPlayer, imSticky, singleTrack) { 577 let identifier = ''; 578 579 if (audioPlayer) { 580 if(!singleTrack){ 581 identifier += 'player_' + audioPlayer.id; 582 } 583 } 584 585 if (imSticky) { 586 identifier += 'sticky'; 587 } 588 589 if (singleTrack && singleTrack.length > 0) { 590 const trackIndex = singleTrack.index(); 591 identifier += 'player_' + audioPlayer.id + '_trackIndex_' + trackIndex; 592 } 593 594 return identifier || 'default'; 595 } 596 597 removePlayerResizeListeners = function(playerId) { 598 waveResizeHandlers.forEach((handler, waveId) => { 599 if (waveId && waveId.includes("trackIndex_")) { 600 if(waveId.includes(playerId)){ 601 window.removeEventListener('resize', handler); 602 waveResizeHandlers.delete(waveId); // Remove the item from the map 603 } 604 } 605 }); 606 } 607 608 const waveResizeHandlers = new Map(); 609 // Assign the function to the IRON object 610 IRON.createFakeWave = createFakeWave; // IRON.createFakeWave introduced in v5, but MP3 Audio Player Pro v4 supports only createFakeWave(). So we need to keep both for backward compatibility 611 IRON.removePlayerResizeListeners = removePlayerResizeListeners; 612 613 614 //Replace CTA button by ellipsis on small device 615 sr_playerCTAresponsive = function () { 616 $('.iron-audioplayer:not(.srp_has_customfields):not(.srp_tracklist_grid)').each(function () { 617 const selector = $(this).parents('[class*="sr_track_inline_cta_bt"]:not(.srp_track_cta_fixed)'); 618 if( selector.length ){ 619 let sr_ctaEnable = true; 620 $(this).find('.sr-playlist-item:not([data-relatedtrack="1"])').each(function () { 621 const min_breakpoint = ($(this).find('.audio-track').width() < 200 )? 200: $(this).find('.audio-track').width(); 622 if( min_breakpoint + $(this).find('.song-store-list-container').width() >= $(this).width()){ 623 sr_ctaEnable = false; 624 } 625 }) 626 if (sr_ctaEnable ) { 627 selector.removeClass('sr_track_inline_cta_bt__no') 628 selector.addClass('sr_track_inline_cta_bt__yes') 629 } else { 630 selector.removeClass('sr_track_inline_cta_bt__yes') 631 selector.addClass('sr_track_inline_cta_bt__no') 632 } 633 } 634 }) 635 } 636 637 //Close And Open Player widget Store List container 638 $(document).on('click', function () { 639 closeStoreListContainer('.srp_cta_opened'); 640 }); 641 642 $('.store-list').on('click', function () { 643 if (!$(this).find('.srp_cta_opened').length) { 644 openStoreListContainer($(this).find('.song-store-list-menu')[0]); 645 } 646 }); 647 648 openStoreListContainer = function (el) { 649 if ($(el).parents('.sr_track_inline_cta_bt__yes').length) { 650 return; 651 } 652 closeStoreListContainer('.srp_cta_opened'); 653 var theyShouldBeClosed = setInterval(function () { // Wait until all other store list container is closed 654 if ($('.srp_cta_opened').length == 0) { 655 $(el).find('.song-store-list-container').show(0, function () { 656 }).animate({ opacity: 1 }, 150, function () { 657 $(el).find('.song-store-list-container').addClass('srp_cta_opened'); 658 }); 659 $(el).find('.song-store-list-container').addClass('srp_cta_ready'); 660 clearInterval(theyShouldBeClosed); 661 } 662 }, 100); 663 } 664 665 closeStoreListContainer = function (el) { 666 if ($(el).parents('.sr_track_inline_cta_bt__yes').length) { 667 return; 668 } 669 $(el).animate({ opacity: 0 }, 150, 'swing', function () { 670 $(el).hide(0); 671 }); 672 $(el).removeClass('srp_cta_opened'); 673 } 674 675 //Call Function on window Resize 676 let resizeTimer; 677 $(window).resize(function () { 678 if (resizeTimer != null) window.clearTimeout(resizeTimer); 679 resizeTimer = window.setTimeout(function () { 680 681 //Call function here... 682 sr_playerCTAresponsive(); 683 684 }, 200); 685 }); 686 687 //Take "01:05:25" and return "3925" sec. 688 convertTime = function (time) { 689 time = time.toString().split(':').reverse(); 690 let newTime = 0; 691 $(time).each(function (index) { 692 newTime = newTime + parseInt(this) * (60 ** (index)); 693 }) 694 return (newTime); 695 } 696 697})(jQuery); 698 699//Check if the we are int the guttenberg editor
700function isGutenbergActive() { 701 return document.body.classList.contains('block-editor-page'); 702}
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.