diff --git a/public/index.css b/public/index.css index 51707b4..49a1ec7 100644 --- a/public/index.css +++ b/public/index.css @@ -224,6 +224,20 @@ tr:nth-child(even) { .dropdown:hover .dropdown-content { display: block; } +.playing-bar { + display: flex; + flex: 1; + position: relative; +} +.playing-bar span { + z-index: 10; +} +canvas#visualizer { + position: absolute; + display: block; + opacity: 0.4; + z-index: 9; +} @media only screen and (max-width: 600px) { tr td:nth-child(1), th:nth-child(1) { display: none; diff --git a/public/index.html b/public/index.html index 6e2a542..5648b73 100644 --- a/public/index.html +++ b/public/index.html @@ -42,7 +42,10 @@
-
Nothing playing
+
+ Nothing playing + +
@@ -71,5 +74,6 @@
+ diff --git a/public/player.js b/public/player.js index 0d72c46..69937d5 100644 --- a/public/player.js +++ b/public/player.js @@ -44,7 +44,7 @@ } } - if (e.pageX || e.pageY) { + if (e.pageX || e.pageY) { x = e.pageX y = e.pageY } else { @@ -58,7 +58,7 @@ return {x: x, y: y} } - function updateSeeker() { + function updateSeeker () { if (isNaN(audio.duration) || audio.duration === 0) return ts.innerHTML = toHHMMSS(audio.currentTime) + ' / ' + toHHMMSS(audio.duration) @@ -68,7 +68,7 @@ seekBar.style.width = progress + '%' } - function updateVolume() { + function updateVolume () { volBar.style.width = (100 * audio.volume) + '%' if (audio.muted) { @@ -86,7 +86,7 @@ let pos = relMouseCoords.call(this, e) let clickPercent = pos.x / this.offsetWidth - if (max == 1) { + if (max === 1) { audio[prop] = clickPercent return } diff --git a/public/visuals.js b/public/visuals.js new file mode 100644 index 0000000..e271b9d --- /dev/null +++ b/public/visuals.js @@ -0,0 +1,68 @@ +(function () { + var audio = document.querySelector('#player') + var canvas = document.querySelector('#visualizer') + var playbar = document.querySelector('.playing-bar') + + var context = new AudioContext() + var src = context.createMediaElementSource(audio) + var analyser = context.createAnalyser() + + var ctx = canvas.getContext('2d') + + var WIDTH = canvas.width + var HEIGHT = canvas.height + + var barWidth + + function convenientSizer () { + canvas.width = playbar.clientWidth + canvas.height = 40 + + WIDTH = canvas.width + HEIGHT = canvas.height + } + + src.connect(analyser) + analyser.connect(context.destination) + + analyser.fftSize = 256 + + var bufferLength = analyser.frequencyBinCount + + var dataArray = new Uint8Array(bufferLength) + + var barHeight + var x = 0 + + function renderFrame () { + requestAnimationFrame(renderFrame) + barWidth = (WIDTH / bufferLength) * 2.5 + + x = 0 + + analyser.getByteFrequencyData(dataArray) + + ctx.clearRect(0, 0, WIDTH, HEIGHT) + + for (var i = 0; i < bufferLength; i++) { + barHeight = dataArray[i] + + var r = 50 + var g = barHeight + (i / bufferLength) + var b = 250 * (i / bufferLength) + + let realAdjusted = barHeight * (HEIGHT / analyser.fftSize) + + ctx.fillStyle = 'rgb(' + r + ',' + g + ',' + b + ')' + ctx.fillRect(x, HEIGHT - realAdjusted, barWidth, realAdjusted) + + x += barWidth + 1 + } + } + + renderFrame() + + window.addEventListener('resize', convenientSizer) + + convenientSizer() +})()