| |
| |
| |
| |
|
|
| |
| |
| |
| |
| |
| |
| export function startWaveform(canvas, stream) { |
| const ctx = canvas.getContext('2d'); |
| const dpr = window.devicePixelRatio || 1; |
|
|
| |
| const rect = canvas.getBoundingClientRect(); |
| canvas.width = rect.width * dpr; |
| canvas.height = rect.height * dpr; |
| ctx.scale(dpr, dpr); |
|
|
| const width = rect.width; |
| const height = rect.height; |
|
|
| |
| const audioCtx = new (window.AudioContext || window.webkitAudioContext)(); |
| const source = audioCtx.createMediaStreamSource(stream); |
| const analyser = audioCtx.createAnalyser(); |
| analyser.fftSize = 256; |
| source.connect(analyser); |
|
|
| const bufferLength = analyser.frequencyBinCount; |
| const dataArray = new Uint8Array(bufferLength); |
|
|
| let animFrameId = null; |
|
|
| function draw() { |
| animFrameId = requestAnimationFrame(draw); |
| analyser.getByteTimeDomainData(dataArray); |
|
|
| |
| ctx.fillStyle = '#F0F2F5'; |
| ctx.fillRect(0, 0, width, height); |
|
|
| |
| ctx.lineWidth = 2; |
| ctx.strokeStyle = '#25D366'; |
| ctx.beginPath(); |
|
|
| const sliceWidth = width / bufferLength; |
| let x = 0; |
|
|
| for (let i = 0; i < bufferLength; i++) { |
| const v = dataArray[i] / 128.0; |
| const y = (v * height) / 2; |
|
|
| if (i === 0) { |
| ctx.moveTo(x, y); |
| } else { |
| ctx.lineTo(x, y); |
| } |
| x += sliceWidth; |
| } |
|
|
| ctx.lineTo(width, height / 2); |
| ctx.stroke(); |
| } |
|
|
| draw(); |
|
|
| |
| return function cleanup() { |
| if (animFrameId) cancelAnimationFrame(animFrameId); |
| try { source.disconnect(); } catch (e) { } |
| try { audioCtx.close(); } catch (e) { } |
| }; |
| } |
|
|
|
|
| |
| |
| |
| |
| export function stopWaveform(canvas) { |
| const ctx = canvas.getContext('2d'); |
| const dpr = window.devicePixelRatio || 1; |
| const rect = canvas.getBoundingClientRect(); |
| canvas.width = rect.width * dpr; |
| canvas.height = rect.height * dpr; |
| ctx.scale(dpr, dpr); |
|
|
| const width = rect.width; |
| const height = rect.height; |
|
|
| |
| ctx.fillStyle = '#F0F2F5'; |
| ctx.fillRect(0, 0, width, height); |
|
|
| |
| ctx.strokeStyle = '#D0D5DA'; |
| ctx.lineWidth = 1; |
| ctx.beginPath(); |
| ctx.moveTo(0, height / 2); |
| ctx.lineTo(width, height / 2); |
| ctx.stroke(); |
| } |
|
|