visualizer
This commit is contained in:
parent
790516e385
commit
c25bfc59fd
@ -224,6 +224,20 @@ tr:nth-child(even) {
|
|||||||
.dropdown:hover .dropdown-content {
|
.dropdown:hover .dropdown-content {
|
||||||
display: block;
|
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) {
|
@media only screen and (max-width: 600px) {
|
||||||
tr td:nth-child(1), th:nth-child(1) {
|
tr td:nth-child(1), th:nth-child(1) {
|
||||||
display: none;
|
display: none;
|
||||||
|
@ -42,7 +42,10 @@
|
|||||||
<div class="player flex-row">
|
<div class="player flex-row">
|
||||||
<div class="inline-flex">
|
<div class="inline-flex">
|
||||||
<div id="queue" class="queue-tag" style="display: none;">Queue</div>
|
<div id="queue" class="queue-tag" style="display: none;">Queue</div>
|
||||||
<div id="playing">Nothing playing</div>
|
<div class="playing-bar">
|
||||||
|
<span id="playing">Nothing playing</span>
|
||||||
|
<canvas id="visualizer" height="40"></canvas>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<audio id="player"></audio>
|
<audio id="player"></audio>
|
||||||
<div class="player-controls">
|
<div class="player-controls">
|
||||||
@ -71,5 +74,6 @@
|
|||||||
</div>
|
</div>
|
||||||
<script type="text/javascript" src="index.js"></script>
|
<script type="text/javascript" src="index.js"></script>
|
||||||
<script type="text/javascript" src="player.js"></script>
|
<script type="text/javascript" src="player.js"></script>
|
||||||
|
<script type="text/javascript" src="visuals.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -44,7 +44,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.pageX || e.pageY) {
|
if (e.pageX || e.pageY) {
|
||||||
x = e.pageX
|
x = e.pageX
|
||||||
y = e.pageY
|
y = e.pageY
|
||||||
} else {
|
} else {
|
||||||
@ -58,7 +58,7 @@
|
|||||||
return {x: x, y: y}
|
return {x: x, y: y}
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateSeeker() {
|
function updateSeeker () {
|
||||||
if (isNaN(audio.duration) || audio.duration === 0) return
|
if (isNaN(audio.duration) || audio.duration === 0) return
|
||||||
|
|
||||||
ts.innerHTML = toHHMMSS(audio.currentTime) + ' / ' + toHHMMSS(audio.duration)
|
ts.innerHTML = toHHMMSS(audio.currentTime) + ' / ' + toHHMMSS(audio.duration)
|
||||||
@ -68,7 +68,7 @@
|
|||||||
seekBar.style.width = progress + '%'
|
seekBar.style.width = progress + '%'
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateVolume() {
|
function updateVolume () {
|
||||||
volBar.style.width = (100 * audio.volume) + '%'
|
volBar.style.width = (100 * audio.volume) + '%'
|
||||||
|
|
||||||
if (audio.muted) {
|
if (audio.muted) {
|
||||||
@ -86,7 +86,7 @@
|
|||||||
let pos = relMouseCoords.call(this, e)
|
let pos = relMouseCoords.call(this, e)
|
||||||
let clickPercent = pos.x / this.offsetWidth
|
let clickPercent = pos.x / this.offsetWidth
|
||||||
|
|
||||||
if (max == 1) {
|
if (max === 1) {
|
||||||
audio[prop] = clickPercent
|
audio[prop] = clickPercent
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
68
public/visuals.js
Normal file
68
public/visuals.js
Normal file
@ -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()
|
||||||
|
})()
|
Loading…
Reference in New Issue
Block a user