1const $ = jQuery ; 2 3 4var strip = function (s) { 5 return s.replace(/^\s+|\s+$/g,''); 6}; 7var parsTime = function (str) { 8 var a = str.split(':'); 9 var seconds = (parseInt(a[0])) * 60 * 60 + parseInt(a[1]) * 60 + parseFloat(a[2]); 10 return seconds; 11} 12 13function formatTime(time){ 14 time = Math.floor(time); 15 let min = Math.floor(time/60); 16 let sec = time % 60; 17 if (sec < 10) sec = '0'+sec; 18 return min+':'+sec; 19} 20 21function getCurrentSubtitle(time, subtitles){ 22 var current = null; 23 subtitles.forEach(function(el){ 24 if (el.startTime <= time && el.endTime > time && el.type=="subtitle"){ 25 current = el; 26 } 27 }); 28 return current; 29} 30 31function loadSubtitles(url, callback){ 32 var subtitles = []; 33 $.get(url, function(srt) { 34 35 srt = srt.replace(/\r\n|\r|\n/g, '\n'); 36 srt = strip(srt); 37 var srt_ = srt.split('\n\n'); 38 39 for(var s=0; s<srt_.length; s++) { 40 var st = srt_[s].split('\n'); 41 if(st[0] === ''){ 42 st.shift(); 43 } 44 if(st.length >=2) { 45 var n = st[0], 46 i = strip(st[1].split(' --> ')[0]), 47 o = strip(st[1].split(' --> ')[1]), 48 t = st[2]; 49 if(st.length > 2) { 50 for(var j=3; j<st.length;j++){ 51 if($(window).width() < 480) { 52 t += ' '; 53 } else { 54 t += '<br/>'; 55 } 56 t += st[j]; 57 } 58 } 59 subtitles.push({ 60 start:i, 61 startTime: parsTime(i), 62 end:o, 63 endTime: parsTime(o), 64 type:"subtitle", 65 data: t 66 }); 67 } 68 } 69 callback(subtitles); 70 }); 71} 72 73 74function icon(iconName){ 75 return '<a class="player-icon icon-'+iconName+'"><svg viewBox="0 0 23 23"><use fill="#FFF" xlink:href="'+pluginUrl+'img/player-icons.svg#'+iconName+'"></use></svg></a>'; 76} 77 78 79$.fn.audioplayer = function(){ 80 let subtitleUrl = $(this).find('track').attr('src') 81 let subtitlesData = []; 82 let duration = 0; 83 audioUrl = $(this).find('audio source').attr('src'); 84 let $audio = $(this).find('audio'); 85 if (subtitleUrl){ 86 $(this).find('audio').before('<div class="subtitle-container"><div class="subtitle-holder"></div></div>'); 87 88 loadSubtitles(subtitleUrl, data=>subtitlesData = data) 89 } 90 $(this).find('img').height($(this).find('img').width()); 91 $(this).find('.inkylab-player-wrapper').height($(this).find('img').width()); 92 let playerHTML = '<div class="inkylab-audio-player d-flex">'+icon('prev')+icon('play')+icon('next')+'<div class="progress-status"><div class="justify-content-between d-flex player-times"><span class="player-current-time">0:00</span><span class="player-duration"></span></div><div class="progress-bar player-progress-bar"><div class="progress" style="width:0%"></div></div></div>'+icon('sound')+icon('subtitle')+icon('download')+'</div>'; 93 $audio.after(playerHTML); 94 $(this).find('.icon-download').attr('href', audioUrl).attr('download', true); 95 let $subContainer = $(this).find('.subtitle-holder'); 96 let $timeHolder = $(this).find('.player-current-time'); 97 let $durationHolder = $(this).find('.player-duration'); 98 let $progress = $(this).find('.progress'); 99 let $playPauseIcon = $(this).find('.icon-play'); 100 let $subtitleIcon = $(this).find('.icon-subtitle'); 101 let $soundIcon = $(this).find('.icon-sound'); 102 let $prevIcon = $(this).find('.icon-prev'); 103 let $nextIcon = $(this).find('.icon-next'); 104 //event listener handlers 105 $audio.on('loadedmetadata', function(){ 106 duration = this.duration; 107 $durationHolder.html(formatTime(duration)); 108 109 $playPauseIcon.click(function(){ 110 if ($audio[0].paused){ 111 $audio[0].play(); 112 $playPauseIcon.find('use').attr('xlink:href', pluginUrl+'/img/player-icons.svg#pause') 113 114 } 115 else{ 116 $audio[0].pause(); 117 $playPauseIcon.find('use').attr('xlink:href', pluginUrl+'/img/player-icons.svg#play') 118 119 } 120 }) 121 $audio.on('ended', function(){ 122 $playPauseIcon.find('use').attr('xlink:href', pluginUrl+'/img/player-icons.svg#play') 123 124 }) 125 $progress.parent().click(function(e){ 126 let cx = e.clientX; 127 let px = $(this).offset().left; 128 let width = $(this).width(); 129 let p = (cx-px)/width; 130 $audio[0].currentTime = p*duration; 131 132 133 }) 134 $subtitleIcon.click(function(){ 135 $(this).toggleClass('active'); 136 $subContainer.toggleClass('d-none'); 137 }) 138 $prevIcon.click(function(){ 139 $audio[0].currentTime = $audio[0].currentTime - 5; 140 }) 141 $nextIcon.click(function(){ 142 $audio[0].currentTime = $audio[0].currentTime + 5; 143 }) 144 145 $soundIcon.click(function(){ 146 if ($audio[0].muted){ 147 $audio[0].muted = false;
148 $(this).find('use').attr('xlink:href',pluginUrl+'img/player-icons.svg#sound') 149 }else{ 150 $audio[0].muted = true; 151 $(this).find('use').attr('xlink:href',pluginUrl+'img/player-icons.svg#no-sound') 152 153 } 154 }) 155 }); 156 $audio.on('timeupdate', function(e){ 157 let currentTime = this.currentTime; 158 $timeHolder.html(formatTime(currentTime)); 159 let currentSubtitle = getCurrentSubtitle(currentTime, subtitlesData); 160 if (duration) { 161 $progress.css('width', (100*currentTime/duration)+'%') 162 } 163 $subContainer.html(currentSubtitle ? currentSubtitle.data:''); 164 }) 165 166 167 168 169} 170 171 172$(document).ready(function () { 173 $('.wp-block-inkylab-audio-player').each(function(){ 174 $(this).audioplayer(); 175}) 176 177}) 178
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.