react-voice-visualizer
Advanced tools
Comparing version
/// <reference types="react" /> | ||
import { Controls } from "../types/types.ts"; | ||
interface VoiceVisualiserProps { | ||
interface VoiceVisualizerProps { | ||
controls: Controls; | ||
@@ -36,3 +36,3 @@ height?: string | number; | ||
type Ref = HTMLAudioElement | null; | ||
declare const VoiceVisualiser: import("react").ForwardRefExoticComponent<VoiceVisualiserProps & import("react").RefAttributes<Ref>>; | ||
export default VoiceVisualiser; | ||
declare const VoiceVisualizer: import("react").ForwardRefExoticComponent<VoiceVisualizerProps & import("react").RefAttributes<Ref>>; | ||
export default VoiceVisualizer; |
@@ -198,3 +198,3 @@ (function(){"use strict";(e=>{try{if(typeof window>"u")return;var i=document.createElement("style");i.appendChild(document.createTextNode(e)),document.head.appendChild(i)}catch(o){console.error("vite-plugin-css-injected-by-js",o)}})(".voice-visualizer__buttons-container{display:flex;justify-content:center;align-items:center;column-gap:20px;row-gap:15px;flex-wrap:wrap;margin-bottom:40px}.voice-visualizer__btn-center{box-sizing:border-box;flex-shrink:0;width:60px;height:60px;padding:0;display:flex;justify-content:center;align-items:center;border-radius:50%;background-color:#fff;border:4px solid #c5c5c5;outline:none;cursor:pointer;transition:border-color .3s,background-color .3s}.voice-visualizer__btn-center:hover{background-color:#eaeaea}.voice-visualizer__btn-center>img{width:auto;height:50%;max-height:30px}.voice-visualizer__btn-center.voice-visualizer__btn-center-pause{background-color:#ff3030}.voice-visualizer__btn-center.voice-visualizer__btn-center-pause:hover{background-color:#ff4f4f}.voice-visualizer__btn-center.voice-visualizer__btn-center-pause>img{height:50%;max-height:16px}.voice-visualizer__btn-center:hover{border:4px solid #9f9f9f}.voice-visualizer__btn-left{box-sizing:border-box;flex-shrink:0;width:60px;height:60px;padding:0;display:flex;justify-content:center;align-items:center;border-radius:50%;background-color:#ff3030;border:4px solid #c5c5c5;outline:none;cursor:pointer;transition:border-color .3s,background-color .3s,opacity .3s}.voice-visualizer__btn-left:hover{background-color:#ff4f4f}.voice-visualizer__btn-left:disabled{opacity:.6;background-color:#ff3030}.voice-visualizer__btn-left.voice-visualizer__btn-left-microphone{background-color:#fff}.voice-visualizer__btn-left.voice-visualizer__btn-left-microphone>img{width:auto;height:50%;max-height:30px}.voice-visualizer__btn-left>img{width:auto;height:50%;max-height:16px}.voice-visualizer__btn-left:hover{border:4px solid #9f9f9f}.voice-visualizer__btn{box-sizing:border-box;min-width:100px;min-height:60px;padding:5px 20px;border-radius:40px;font-size:15px;background-color:#f0f0f0;transition:background-color .3s,opacity .3s}.voice-visualizer__btn:disabled{opacity:.8;background-color:#f0f0f0}.voice-visualizer__btn:hover{background-color:#bebebe}.voice-visualizer__canvas-container{position:relative;margin:0 auto;overflow:hidden}.voice-visualizer__canvas-container canvas{display:block}.voice-visualizer__canvas-microphone-btn{position:absolute;top:50%;left:50%;width:auto;max-width:12%;min-width:24px;height:50%;max-height:100px;background-color:transparent;border:none;outline:none;transform:translate(-50%,-50%)}.voice-visualizer__canvas-microphone-icon{width:100%;height:100%;will-change:transform;transition:transform .35s}.voice-visualizer__canvas-microphone-btn:hover .voice-visualizer__canvas-microphone-icon{transform:scale(1.03)}.voice-visualizer__canvas-audio-wave-icon{position:absolute;top:50%;left:50%;width:auto;max-width:40%;height:40%;max-height:100px;transform:translate(-118%,-50%) scale(-1)}.voice-visualizer__canvas-audio-wave-icon2{transform:translate(18%,-50%)}.voice-visualizer__canvas-audio-processing{position:absolute;top:50%;left:50%;margin:0;transform:translate(-50%,-50%)}.voice-visualizer__progress-indicator-hovered{position:absolute;top:0;pointer-events:none;height:100%;width:1px;background-color:#85858599}.voice-visualizer__progress-indicator-hovered-time{position:absolute;top:3%;left:1px;width:fit-content;margin:0;padding:0 7px;font-size:12px;border-radius:0 4px 4px 0;background-color:#575757;opacity:.8}.voice-visualizer__progress-indicator-hovered-time.voice-visualizer__progress-indicator-hovered-time-left{left:unset;right:1px;border-radius:4px 0 0 4px}.voice-visualizer__progress-indicator{position:absolute;top:0;pointer-events:none;height:100%;width:1px;background-color:#efefef}.voice-visualizer__progress-indicator-time{position:absolute;top:3%;left:1px;width:fit-content;box-sizing:border-box;min-width:41px;margin:0;padding:0 7px;font-size:12px;border-radius:0 4px 4px 0;text-align:left;color:#000;font-weight:500;background-color:#efefef}.voice-visualizer__progress-indicator-time.voice-visualizer__progress-indicator-time-left{left:unset;right:1px;border-radius:4px 0 0 4px}.voice-visualizer__audio-info-container{box-sizing:border-box;height:55px;display:flex;align-items:center;justify-content:center;gap:30px}.voice-visualizer__audio-info-time{margin:15px 0;min-width:38px;text-align:left}.voice-visualizer__visually-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:4px solid #c5c5c5;white-space:nowrap;clip-path:inset(100%);clip:rect(0 0 0 0);overflow:hidden}")})(); | ||
return r && r.length >= 2 ? `.${r[1]}` : ""; | ||
}, Ve = (e) => { | ||
}, Je = (e) => { | ||
const r = Math.floor(e / 3600), n = Math.floor(e % 3600 / 60), t = e % 60, i = Math.floor( | ||
@@ -212,3 +212,3 @@ (t - Math.floor(t)) * 1e3 | ||
}; | ||
const Je = ({ | ||
const Qe = ({ | ||
color: e = "#000000", | ||
@@ -252,3 +252,3 @@ stroke: r = 2, | ||
} | ||
), Te = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjMiIGhlaWdodD0iMzMiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgPHBhdGggZD0iTTEuMSAxNi43MmMwIDMgLjk2IDUuOCAzLjYxIDcuOTVhOS45NiA5Ljk2IDAgMCAwIDYuNSAyLjE3bTAgMHY0LjM0aDQuMzQtOC42N200LjM0LTQuMzRjMi4zNSAwIDQuNDItLjQ4IDYuNS0yLjE3YTkuODcgOS44NyAwIDAgMCAzLjYxLTcuOTVNMTEuMjIgMS44MmMtMS40NSAwLTIuNS4zNy0zLjMuOTNhNS42IDUuNiAwIDAgMC0xLjg0IDIuNGMtLjkgMi4wNi0xLjEgNC43Ny0xLjEgNy4yNCAwIDIuNDYuMiA1LjE3IDEuMSA3LjI0YTUuNiA1LjYgMCAwIDAgMS44NCAyLjRjLjguNTUgMS44NS45MiAzLjMuOTIgMS40NCAwIDIuNS0uMzcgMy4yOS0uOTNhNS42IDUuNiAwIDAgMCAxLjg0LTIuNGMuOS0yLjA2IDEuMS00Ljc3IDEuMS03LjIzIDAtMi40Ny0uMi01LjE4LTEuMS03LjI0YTUuNiA1LjYgMCAwIDAtMS44NC0yLjQgNS41MiA1LjUyIDAgMCAwLTMuMy0uOTNaIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPgo8L3N2Zz4K", Qe = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjYiIGhlaWdodD0iMjQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgPHBhdGggZD0iTTE4Ljc1IDYuMTZjNC4zMSAyLjYgNi40NiAzLjkgNi40NiA1Ljg0IDAgMS45NS0yLjE1IDMuMjQtNi40NiA1Ljg0bC00Ljg0IDIuOTJjLTQuMzEgMi42LTYuNDYgMy44OS04LjA4IDIuOTItMS42Mi0uOTgtMS42Mi0zLjU3LTEuNjItOC43NlY5LjA4YzAtNS4xOSAwLTcuNzggMS42Mi04Ljc2IDEuNjItLjk3IDMuNzcuMzMgOC4wOCAyLjkybDQuODQgMi45MloiIGZpbGw9IiNmZmYiLz4KPC9zdmc+Cg==", Ee = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjEiIGhlaWdodD0iMjkiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgPHBhdGggZD0iTTE0IDMuNWEzLjUgMy41IDAgMSAxIDcgMHYyMmEzLjUgMy41IDAgMSAxLTcgMHYtMjJaIiBmaWxsPSIjZmZmIi8+CiAgPHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjkiIHJ4PSIzLjUiIGZpbGw9IiNmZmYiLz4KPC9zdmc+Cg==", We = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjciIGhlaWdodD0iMjUiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgPHJlY3QgeD0iLjIxIiB3aWR0aD0iMjYiIGhlaWdodD0iMjUiIHJ4PSI1IiBmaWxsPSIjZmZmIi8+Cjwvc3ZnPgo=", Ke = Ze( | ||
), Te = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjMiIGhlaWdodD0iMzMiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgPHBhdGggZD0iTTEuMSAxNi43MmMwIDMgLjk2IDUuOCAzLjYxIDcuOTVhOS45NiA5Ljk2IDAgMCAwIDYuNSAyLjE3bTAgMHY0LjM0aDQuMzQtOC42N200LjM0LTQuMzRjMi4zNSAwIDQuNDItLjQ4IDYuNS0yLjE3YTkuODcgOS44NyAwIDAgMCAzLjYxLTcuOTVNMTEuMjIgMS44MmMtMS40NSAwLTIuNS4zNy0zLjMuOTNhNS42IDUuNiAwIDAgMC0xLjg0IDIuNGMtLjkgMi4wNi0xLjEgNC43Ny0xLjEgNy4yNCAwIDIuNDYuMiA1LjE3IDEuMSA3LjI0YTUuNiA1LjYgMCAwIDAgMS44NCAyLjRjLjguNTUgMS44NS45MiAzLjMuOTIgMS40NCAwIDIuNS0uMzcgMy4yOS0uOTNhNS42IDUuNiAwIDAgMCAxLjg0LTIuNGMuOS0yLjA2IDEuMS00Ljc3IDEuMS03LjIzIDAtMi40Ny0uMi01LjE4LTEuMS03LjI0YTUuNiA1LjYgMCAwIDAtMS44NC0yLjQgNS41MiA1LjUyIDAgMCAwLTMuMy0uOTNaIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPgo8L3N2Zz4K", Ve = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjYiIGhlaWdodD0iMjQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgPHBhdGggZD0iTTE4Ljc1IDYuMTZjNC4zMSAyLjYgNi40NiAzLjkgNi40NiA1Ljg0IDAgMS45NS0yLjE1IDMuMjQtNi40NiA1Ljg0bC00Ljg0IDIuOTJjLTQuMzEgMi42LTYuNDYgMy44OS04LjA4IDIuOTItMS42Mi0uOTgtMS42Mi0zLjU3LTEuNjItOC43NlY5LjA4YzAtNS4xOSAwLTcuNzggMS42Mi04Ljc2IDEuNjItLjk3IDMuNzcuMzMgOC4wOCAyLjkybDQuODQgMi45MloiIGZpbGw9IiNmZmYiLz4KPC9zdmc+Cg==", Ee = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjEiIGhlaWdodD0iMjkiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgPHBhdGggZD0iTTE0IDMuNWEzLjUgMy41IDAgMSAxIDcgMHYyMmEzLjUgMy41IDAgMSAxLTcgMHYtMjJaIiBmaWxsPSIjZmZmIi8+CiAgPHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjkiIHJ4PSIzLjUiIGZpbGw9IiNmZmYiLz4KPC9zdmc+Cg==", We = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjciIGhlaWdodD0iMjUiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgPHJlY3QgeD0iLjIxIiB3aWR0aD0iMjYiIGhlaWdodD0iMjUiIHJ4PSI1IiBmaWxsPSIjZmZmIi8+Cjwvc3ZnPgo=", Ke = Ze( | ||
({ | ||
@@ -282,4 +282,4 @@ controls: { | ||
barWidth: ae = 2, | ||
gap: V = 1, | ||
rounded: J = 5, | ||
gap: J = 1, | ||
rounded: Q = 5, | ||
isControlPanelShown: ne = !0, | ||
@@ -291,3 +291,3 @@ isDownloadAudioButtonShown: ie = !1, | ||
isDefaultUIShown: P = !1, | ||
defaultMicrophoneIconColor: Q = b, | ||
defaultMicrophoneIconColor: V = b, | ||
defaultAudioWaveIconColor: x = b, | ||
@@ -307,3 +307,3 @@ canvasContainerClassName: E, | ||
}, H) => { | ||
const [oe, c] = d(0), [y, j] = d([]), [z, K] = d(0), [U, G] = d(0), [F, ee] = d(!1), Me = Math.trunc(Z), Y = Math.trunc(ae), ze = Math.trunc(V), p = D(null), pe = D([]), fe = D(Me), _e = D(Y), be = D(Y), Ce = Y + ze * Y, xe = Oe((_) => { | ||
const [oe, c] = d(0), [y, j] = d([]), [z, K] = d(0), [U, G] = d(0), [F, ee] = d(!1), Me = Math.trunc(Z), Y = Math.trunc(ae), ze = Math.trunc(J), p = D(null), pe = D([]), fe = D(Me), _e = D(Y), be = D(Y), Ce = Y + ze * Y, xe = Oe((_) => { | ||
const k = Math.floor(_.clientWidth / 2) * 2, B = Math.trunc(_.clientHeight); | ||
@@ -340,3 +340,3 @@ K(k), G(B); | ||
barWidth: Y, | ||
rounded: J, | ||
rounded: Q, | ||
animateCurrentPick: O, | ||
@@ -352,3 +352,3 @@ fullscreen: h | ||
C, | ||
J, | ||
Q, | ||
z, | ||
@@ -390,3 +390,3 @@ U, | ||
U, | ||
V, | ||
J, | ||
ae | ||
@@ -408,3 +408,3 @@ ]), $(() => { | ||
currentAudioTime: m, | ||
rounded: J, | ||
rounded: Q, | ||
duration: t | ||
@@ -417,3 +417,3 @@ }); | ||
o, | ||
J, | ||
Q, | ||
N, | ||
@@ -469,5 +469,5 @@ b, | ||
children: /* @__PURE__ */ a( | ||
Je, | ||
Qe, | ||
{ | ||
color: Q, | ||
color: V, | ||
stroke: 0.5, | ||
@@ -531,3 +531,3 @@ className: "voice-visualizer__canvas-microphone-icon" | ||
r && /* @__PURE__ */ a("p", { className: "voice-visualizer__audio-info-time", children: Fe(f) }), | ||
t ? /* @__PURE__ */ a("p", { children: Ve(t) }) : null | ||
t ? /* @__PURE__ */ a("p", { children: Je(t) }) : null | ||
] }), | ||
@@ -558,3 +558,3 @@ /* @__PURE__ */ te("div", { className: "voice-visualizer__buttons-container", children: [ | ||
{ | ||
src: A ? Qe : Ee, | ||
src: A ? Ve : Ee, | ||
alt: A ? "Play" : "Pause" | ||
@@ -614,3 +614,3 @@ } | ||
function et() { | ||
const [e, r] = d(!1), [n, t] = d(!1), [i, m] = d(null), [s, T] = d(new Uint8Array(0)), [v, I] = d(!1), [g, f] = d(null), [A, L] = d(null), [M, o] = d(0), [u, S] = d(0), [re, R] = d(0), [Z, N] = d(""), [b, C] = d(!0), [ae, V] = d(0), [J, ne] = d(!0), [ie, O] = d(null), h = D(null), w = D(null), P = D(null), Q = D(null), x = D(null), E = D(null), W = D(null), l = D(null); | ||
const [e, r] = d(!1), [n, t] = d(!1), [i, m] = d(null), [s, T] = d(new Uint8Array(0)), [v, I] = d(!1), [g, f] = d(null), [A, L] = d(null), [M, o] = d(0), [u, S] = d(0), [re, R] = d(0), [Z, N] = d(""), [b, C] = d(!0), [ae, J] = d(0), [Q, ne] = d(!0), [ie, O] = d(null), h = D(null), w = D(null), P = D(null), V = D(null), x = D(null), E = D(null), W = D(null), l = D(null); | ||
$(() => { | ||
@@ -658,3 +658,3 @@ if (!e || n) | ||
navigator.mediaDevices.getUserMedia({ audio: !0 }).then((c) => { | ||
X(), ne(!1), S(performance.now()), r(!0), m(c), w.current = new window.AudioContext(), P.current = w.current.createAnalyser(), Q.current = new Uint8Array( | ||
X(), ne(!1), S(performance.now()), r(!0), m(c), w.current = new window.AudioContext(), P.current = w.current.createAnalyser(), V.current = new Uint8Array( | ||
P.current.frequencyBinCount | ||
@@ -673,7 +673,7 @@ ), x.current = w.current.createMediaStreamSource(c), x.current.connect(P.current), h.current = new MediaRecorder(c), h.current.addEventListener( | ||
}, ce = () => { | ||
P.current.getByteTimeDomainData(Q.current), T(new Uint8Array(Q.current)), E.current = requestAnimationFrame(ce); | ||
P.current.getByteTimeDomainData(V.current), T(new Uint8Array(V.current)), E.current = requestAnimationFrame(ce); | ||
}, q = (c) => { | ||
h.current && f(c.data); | ||
}, se = () => { | ||
l.current && (V(l.current.currentTime), W.current = requestAnimationFrame(se)); | ||
l.current && (J(l.current.currentTime), W.current = requestAnimationFrame(se)); | ||
}, me = () => { | ||
@@ -690,3 +690,3 @@ e || le(); | ||
q | ||
), h.current.stop(), h.current = null), i == null || i.getTracks().forEach((c) => c.stop()), h.current = null, w.current = null, P.current = null, Q.current = null, x.current = null, E.current = null, W.current = null, m(null), r(!1), I(!1), f(null), L(null), o(0), S(0), R(0), N(""), V(0), C(!0), t(!1), T(new Uint8Array(0)), O(null), ne(!0); | ||
), h.current.stop(), h.current = null), i == null || i.getTracks().forEach((c) => c.stop()), h.current = null, w.current = null, P.current = null, V.current = null, x.current = null, E.current = null, W.current = null, m(null), r(!1), I(!1), f(null), L(null), o(0), S(0), R(0), N(""), J(0), C(!0), t(!1), T(new Uint8Array(0)), O(null), ne(!0); | ||
}, de = (c) => { | ||
@@ -702,3 +702,3 @@ c instanceof Blob && (X(), ne(!1), I(!0), r(!1), o(0), t(!1), f(c)); | ||
}, H = () => { | ||
C(!0), l != null && l.current && (l.current.currentTime = 0, V(0)); | ||
C(!0), l != null && l.current && (l.current.currentTime = 0, J(0)); | ||
}, oe = () => { | ||
@@ -726,3 +726,3 @@ var y; | ||
bufferFromRecordedBlob: A, | ||
isCleared: J, | ||
isCleared: Q, | ||
setPreloadedAudioBlob: de, | ||
@@ -729,0 +729,0 @@ startRecording: me, |
{ | ||
"name": "react-voice-visualizer", | ||
"private": false, | ||
"version": "1.0.8", | ||
"version": "1.0.9", | ||
"type": "module", | ||
@@ -17,2 +17,4 @@ "author": "Yurii Zarytskyi", | ||
"visualization", | ||
"voice visualizer", | ||
"audio visualizer", | ||
"audio wave", | ||
@@ -19,0 +21,0 @@ "audio recorder", |
@@ -44,3 +44,3 @@ # react-voice-visualizer ([Demo App](https://react-voice-visualizer.vercel.app/)) | ||
To start using the VoiceVisualiser component, you will need to import the necessary hook and component from the library. | ||
To start using the VoiceVisualizer component, you will need to import the necessary hook and component from the library. | ||
Here's an example of how to use this library in your `App` component: | ||
@@ -50,3 +50,3 @@ | ||
import { useEffect } from "react"; | ||
import { useVoiceVisualizer, VoiceVisualiser } from "react-voice-visualizer"; | ||
import { useVoiceVisualizer, VoiceVisualizer } from "react-voice-visualizer"; | ||
@@ -78,3 +78,3 @@ const App = () => { | ||
return ( | ||
<VoiceVisualiser controls={recorderControls} ref={audioRef}/> | ||
<VoiceVisualizer controls={recorderControls} ref={audioRef}/> | ||
); | ||
@@ -94,3 +94,3 @@ }; | ||
import { useEffect } from 'react'; | ||
import { useVoiceVisualizer, VoiceVisualiser } from 'react-voice-visualizer'; | ||
import { useVoiceVisualizer, VoiceVisualizer } from 'react-voice-visualizer'; | ||
@@ -122,3 +122,3 @@ const App = () => { | ||
return ( | ||
<VoiceVisualiser controls={recorderControls} ref={audioRef}/> | ||
<VoiceVisualizer controls={recorderControls} ref={audioRef}/> | ||
); | ||
@@ -135,3 +135,3 @@ }; | ||
3. Use the provided state and functions to manage audio recording and playback. | ||
4. Render the `VoiceVisualiser` component to display the real-time audio visualization. | ||
4. Render the `VoiceVisualizer` component to display the real-time audio visualization. | ||
5. Use the provided buttons to start, pause, stop, and save the audio recording. | ||
@@ -188,3 +188,3 @@ | ||
### `VoiceVisualiser` Component | ||
### `VoiceVisualizer` Component | ||
@@ -191,0 +191,0 @@ A component that visualizes the real-time audio audio wave during recording. |
110070
0.05%