|
|
| (не показано 146 промежуточных версий этого же участника) |
| Строка 1: |
Строка 1: |
| $(function () {
| | (function(){ |
| var players = document.getElementsByClassName('audio-player');
| | if(typeof mw==='undefined') return; |
| for (var i = 0; i < players.length; i++) {
| |
| (function (container) {
| |
| var src = container.getAttribute('data-src');
| |
| if (!src) return;
| |
|
| |
|
| var audio = document.createElement('audio');
| | var map={ |
| audio.src = src;
| | "Клише":"#ff4d4d", |
| audio.setAttribute('preload', 'auto');
| | "властью":"#4dff4d", |
| | "ответственность":"#4d4dff", |
| | "Стандартные Рабочие Процедуры":"#ff4dff", |
| | "ядерный":"#ffa500", |
| | "станции":"#4dffff", |
| | "ГСБ":"#b84dff", |
| | "диск":"#4dff88", |
| | "СРП/КЗ":"#ffb6c1", |
| | "банановая кожурка":"#ffff4d" |
| | }; |
|
| |
|
| var wrapper = document.createElement('div');
| | function esc(s){return s.replace(/[.*+?^${}()|[\]\\]/g,'\\$&');} |
| wrapper.className = 'custom-audio-wrapper';
| |
|
| |
|
| var playBtn = document.createElement('button');
| | function walk(node){ |
| playBtn.className = 'custom-audio-play';
| | if(node.nodeType===3){ |
| playBtn.innerHTML = '▶';
| | var t=node.nodeValue, r=t; |
| | for(var k in map){ |
| | r=r.replace(new RegExp(esc(k),'g'),'<span style="color:'+map[k]+'">'+k+'</span>'); |
| | } |
| | if(r!==t){ |
| | var s=document.createElement('span'); |
| | s.innerHTML=r; |
| | node.parentNode.replaceChild(s,node); |
| | } |
| | } |
| | } |
|
| |
|
| var progress = document.createElement('input');
| | var nodes=document.querySelectorAll('.mw-parser-output p, .mw-parser-output li'); |
| progress.setAttribute('type', 'range');
| | for(var i=0;i<nodes.length;i++){ |
| progress.className = 'custom-audio-progress';
| | var cn=nodes[i].childNodes; |
| progress.setAttribute('min', 0);
| | for(var j=0;j<cn.length;j++) walk(cn[j]); |
| progress.value = 0;
| | } |
| progress.step = 0.01;
| | })(); |
| | |
| var time = document.createElement('span');
| |
| time.className = 'custom-audio-time';
| |
| time.innerHTML = '0:00';
| |
| | |
| // Громкость
| |
| var volumeControl = document.createElement('input');
| |
| volumeControl.setAttribute('type', 'range');
| |
| volumeControl.setAttribute('min', 0);
| |
| volumeControl.setAttribute('max', 1);
| |
| volumeControl.setAttribute('step', 0.01);
| |
| volumeControl.setAttribute('value', 1);
| |
| volumeControl.className = 'custom-audio-volume';
| |
| | |
| // Визуализация
| |
| var visualizer = document.createElement('canvas');
| |
| visualizer.className = 'custom-audio-visualizer';
| |
| wrapper.appendChild(visualizer);
| |
| | |
| wrapper.appendChild(playBtn);
| |
| wrapper.appendChild(progress);
| |
| wrapper.appendChild(time);
| |
| wrapper.appendChild(volumeControl);
| |
| | |
| container.appendChild(wrapper);
| |
| | |
| // Инициализация Web Audio API
| |
| var audioContext = new (window.AudioContext || window.webkitAudioContext)();
| |
| var analyser = audioContext.createAnalyser();
| |
| var source = audioContext.createMediaElementSource(audio);
| |
| source.connect(analyser);
| |
| analyser.connect(audioContext.destination);
| |
| | |
| // Настройки анализатора
| |
| analyser.fftSize = 256;
| |
| var bufferLength = analyser.frequencyBinCount;
| |
| var dataArray = new Uint8Array(bufferLength);
| |
| | |
| function draw() {
| |
| requestAnimationFrame(draw);
| |
| | |
| analyser.getByteFrequencyData(dataArray);
| |
| | |
| var canvas = visualizer;
| |
| var canvasContext = canvas.getContext('2d');
| |
| canvasContext.clearRect(0, 0, canvas.width, canvas.height);
| |
| | |
| var barWidth = (canvas.width / bufferLength) * 2.5;
| |
| var barHeight;
| |
| var x = 0;
| |
| | |
| for (var i = 0; i < bufferLength; i++) {
| |
| barHeight = dataArray[i];
| |
| | |
| canvasContext.fillStyle = 'rgb(' + (barHeight + 100) + ',50,50)';
| |
| canvasContext.fillRect(x, canvas.height - barHeight / 2, barWidth, barHeight / 2);
| |
| | |
| x += barWidth + 1;
| |
| }
| |
| }
| |
| | |
| playBtn.onclick = function () {
| |
| if (audio.paused) {
| |
| audio.play();
| |
| playBtn.innerHTML = '⏸';
| |
| } else {
| |
| audio.pause();
| |
| playBtn.innerHTML = '▶';
| |
| }
| |
| };
| |
| | |
| volumeControl.oninput = function () {
| |
| audio.volume = volumeControl.value;
| |
| };
| |
| | |
| audio.addEventListener('loadedmetadata', function () {
| |
| progress.max = audio.duration;
| |
| });
| |
| | |
| audio.addEventListener('timeupdate', function () {
| |
| progress.value = audio.currentTime;
| |
| time.innerHTML = formatTime(audio.currentTime);
| |
| });
| |
| | |
| progress.addEventListener('input', function () {
| |
| audio.currentTime = parseFloat(progress.value);
| |
| });
| |
| | |
| function formatTime(seconds) {
| |
| var mins = Math.floor(seconds / 60);
| |
| var secs = Math.floor(seconds % 60);
| |
| if (secs < 10) secs = '0' + secs;
| |
| return mins + ':' + secs;
| |
| }
| |
| | |
| // Обработка ошибок аудио
| |
| audio.addEventListener('play', function () {
| |
| if (audioContext.state === 'suspended') {
| |
| audioContext.resume().then(function () {
| |
| draw();
| |
| });
| |
| } else {
| |
| draw();
| |
| }
| |
| });
| |
| | |
| })(players[i]);
| |
| }
| |
| });
| |