-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex_early.html
More file actions
128 lines (94 loc) · 2.69 KB
/
Copy pathindex_early.html
File metadata and controls
128 lines (94 loc) · 2.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
<!DOCTYPE html>
<html>
<head>
<style>
body {
background-color: coral;
margin: 0;
}
.visualiser-container {
position: relative;
margin-top: 100px;
width: 100%;
height: 200px;
}
canvas {
position: absolute;
top: 0;
left: 0;
}
#playhead {
position: absolute;
top: 0;
width: 2px;
height: 200px;
background: white;
z-index: 2;
}
</style>
</head>
<body>
<audio id="audio" src="audio_test.mp3" controls style="position:absolute; z-index:3;"></audio>
<div class="visualiser-container">
<canvas id="spectrogram"></canvas>
<div id="playhead"></div>
</div>
<script>
(function() {
const audio = document.getElementById("audio");
const canvas = document.getElementById("spectrogram");
const ctx = canvas.getContext("2d");
const playhead = document.getElementById("playhead");
canvas.width = window.innerWidth;
canvas.height = 200;
const audioCtx = new AudioContext();
const source = audioCtx.createMediaElementSource(audio);
const analyser = audioCtx.createAnalyser();
analyser.fftSize = 1024;
analyser.smoothingTimeConstant = 0;
source.connect(analyser);
source.connect(audioCtx.destination);
const freqData = new Uint8Array(analyser.frequencyBinCount);
let x = 0;
function drawSpectrogram() {
requestAnimationFrame(drawSpectrogram);
if (audio.paused) return;
analyser.getByteFrequencyData(freqData);
// shift canvas left
const imageData = ctx.getImageData(1, 0, canvas.width - 1, canvas.height);
ctx.putImageData(imageData, 0, 0);
// draw new slice on right
for (let i = 0; i < freqData.length; i++) {
const value = freqData[i];
const percent = value / 255;
// log scale (important)
const logIndex = Math.log10(1 + 9 * (i / freqData.length));
const y = canvas.height - logIndex * canvas.height;
const hue = 240 - percent * 240;
ctx.fillStyle = `hsl(${hue}, 100%, ${percent * 50}%)`;
ctx.fillRect(
canvas.width - 1,
y,
1,
canvas.height / freqData.length
);
}
}
function animatePlayhead() {
function frame() {
if (!audio.duration) return;
const percent = audio.currentTime / audio.duration;
playhead.style.left = (percent * canvas.width) + "px";
if (!audio.paused) requestAnimationFrame(frame);
}
frame();
}
audio.addEventListener("play", () => {
audioCtx.resume();
drawSpectrogram();
animatePlayhead();
});
})();
</script>
</body>
</html>