UNPKG

@clxrity/react-audio

Version:

An interactive audio package for React

45 lines (44 loc) 28.6 kB
import{jsx as na}from"react/jsx-runtime";var j=({src:e,type:a,...t})=>{let u=a??(e?`audio/${e.split(".").pop()}`:"audio/*");return na("source",{src:e,type:u,...t})};import{jsx as ca}from"react/jsx-runtime";var F=({children:e,...a})=>ca("button",{...a,type:"button",className:`focus:outline-none focus:shadow-outline disabled:opacity-50 disabled:cursor-not-allowed rounded-md px-4 py-2 transition-all duration-200 active:scale-95 disabled:active:scale-100 disabled:transition-none cursor-pointer `,children:e});import{useEffect as Ra,useMemo as Ta,useRef as qa}from"react";function xe({analyser:e,canvas:a,canvasContext:t,dataArray:u,bufferLength:l,color:d}){if(!t)return;t.clearRect(0,0,a.width,a.height),e.getByteFrequencyData(u),t.fillStyle=d;let o=a.height,s=a.width,m=Math.ceil(s/l)*2.5,n=0;for(let f=0;f<l;f++){let x=u[f]/255*o;t.fillRect(n,o-x,m,x),n+=m+1}}import{forwardRef as La,createElement as Ia}from"react";var He=e=>e.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase(),pa=e=>e.replace(/^([A-Z])|[\s-_]+(\w)/g,(a,t,u)=>u?u.toUpperCase():t.toLowerCase()),he=e=>{let a=pa(e);return a.charAt(0).toUpperCase()+a.slice(1)},ne=(...e)=>e.filter((a,t,u)=>!!a&&a.trim()!==""&&u.indexOf(a)===t).join(" ").trim(),ze=e=>{for(let a in e)if(a.startsWith("aria-")||a==="role"||a==="title")return!0};import{forwardRef as ma,createElement as Ge}from"react";var Ee={xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"};var Ve=ma(({color:e="currentColor",size:a=24,strokeWidth:t=2,absoluteStrokeWidth:u,className:l="",children:d,iconNode:o,...s},m)=>Ge("svg",{ref:m,...Ee,width:a,height:a,stroke:e,strokeWidth:u?Number(t)*24/Number(a):t,className:ne("lucide",l),...!d&&!ze(s)&&{"aria-hidden":"true"},...s},[...o.map(([n,f])=>Ge(n,f)),...Array.isArray(d)?d:[d]]));var p=(e,a)=>{let t=La(({className:u,...l},d)=>Ia(Ve,{ref:d,iconNode:a,className:ne(`lucide-${He(he(e))}`,`lucide-${e}`,u),...l}));return t.displayName=he(e),t};var xa=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["rect",{x:"9",y:"9",width:"6",height:"6",rx:"1",key:"1ssd4o"}]],H=p("circle-stop",xa);var ha=[["path",{d:"M12 15V3",key:"m9g1x1"}],["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}],["path",{d:"m7 10 5 5 5-5",key:"brsn70"}]],$=p("download",ha);var Ca=[["polygon",{points:"13 19 22 12 13 5 13 19",key:"587y9g"}],["polygon",{points:"2 19 11 12 2 5 2 19",key:"3pweh0"}]],Y=p("fast-forward",Ca);var ga=[["path",{d:"M5 22h14",key:"ehvnwv"}],["path",{d:"M5 2h14",key:"pdyrp9"}],["path",{d:"M17 22v-4.172a2 2 0 0 0-.586-1.414L12 12l-4.414 4.414A2 2 0 0 0 7 17.828V22",key:"1d314k"}],["path",{d:"M7 2v4.172a2 2 0 0 0 .586 1.414L12 12l4.414-4.414A2 2 0 0 0 17 6.172V2",key:"1vvvr6"}]],ee=p("hourglass",ga);var Sa=[["path",{d:"M21 12a9 9 0 1 1-6.219-8.56",key:"13zald"}]],z=p("loader-circle",Sa);var wa=[["path",{d:"M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z",key:"131961"}],["path",{d:"M19 10v2a7 7 0 0 1-14 0v-2",key:"1vc78b"}],["line",{x1:"12",x2:"12",y1:"19",y2:"22",key:"x3vr5v"}]],ae=p("mic",wa);var Pa=[["rect",{x:"14",y:"4",width:"4",height:"16",rx:"1",key:"zuxfzm"}],["rect",{x:"6",y:"4",width:"4",height:"16",rx:"1",key:"1okwgv"}]],te=p("pause",Pa);var ka=[["polygon",{points:"6 3 20 12 6 21 6 3",key:"1oa8hb"}]],oe=p("play",ka);var ya=[["polygon",{points:"11 19 2 12 11 5 11 19",key:"14yba5"}],["polygon",{points:"22 19 13 12 22 5 22 19",key:"1pi1cj"}]],ue=p("rewind",ya);var ba=[["polygon",{points:"19 20 9 12 19 4 19 20",key:"o2sva"}],["line",{x1:"5",x2:"5",y1:"19",y2:"5",key:"1ocqjk"}]],re=p("skip-back",ba);var Aa=[["polygon",{points:"5 4 15 12 5 20 5 4",key:"16p6eg"}],["line",{x1:"19",x2:"19",y1:"5",y2:"19",key:"futhcm"}]],le=p("skip-forward",Aa);var Ba=[["rect",{x:"3",y:"3",width:"18",height:"18",rx:"2",key:"h1oib"}],["rect",{x:"8",y:"8",width:"8",height:"8",rx:"1",key:"z9xiuo"}]],de=p("square-square",Ba);var va=[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",key:"afitv7"}]],se=p("square",va);var Fa=[["path",{d:"M11 4.702a.705.705 0 0 0-1.203-.498L6.413 7.587A1.4 1.4 0 0 1 5.416 8H3a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h2.416a1.4 1.4 0 0 1 .997.413l3.383 3.384A.705.705 0 0 0 11 19.298z",key:"uqj9uw"}],["path",{d:"M16 9a5 5 0 0 1 0 6",key:"1q6k2b"}],["path",{d:"M19.364 18.364a9 9 0 0 0 0-12.728",key:"ijwkga"}]],fe=p("volume-2",Fa);var Ma=[["path",{d:"M11 4.702a.705.705 0 0 0-1.203-.498L6.413 7.587A1.4 1.4 0 0 1 5.416 8H3a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h2.416a1.4 1.4 0 0 1 .997.413l3.383 3.384A.705.705 0 0 0 11 19.298z",key:"uqj9uw"}],["path",{d:"M16 9a5 5 0 0 1 0 6",key:"1q6k2b"}]],ie=p("volume-1",Ma);var Da=[["path",{d:"M11 4.702a.705.705 0 0 0-1.203-.498L6.413 7.587A1.4 1.4 0 0 1 5.416 8H3a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h2.416a1.4 1.4 0 0 1 .997.413l3.383 3.384A.705.705 0 0 0 11 19.298z",key:"uqj9uw"}],["line",{x1:"22",x2:"16",y1:"9",y2:"15",key:"1ewh16"}],["line",{x1:"16",x2:"22",y1:"9",y2:"15",key:"5ykzw1"}]],J=p("volume-x",Da);var k={Play:oe,Pause:te,Stop:H,FastForward:Y,Rewind:ue,SkipNext:le,SkipPrevious:re,Loading:ee,VolumeOff:J,VolumeMute:J,VolumeDown:ie,VolumeUp:fe,Selected:se,Unselected:de,Loader:z,Mic:ae,Download:$},A={primary:"rgb(236, 106, 177)",secondary:"rgb(121, 91, 132)",white:"#dddddd",black:"#111111"};function Ce(e){e instanceof HTMLCanvasElement&&(e.width=e.clientWidth*window.devicePixelRatio,e.height=e.clientHeight*window.devicePixelRatio)}function ge(e,a,t,u,l){let d=u.current;if(!d||!e)return()=>{};let o=d.getContext("2d"),s=0,m=()=>{s=requestAnimationFrame(m),o&&xe({analyser:e,canvas:d,canvasContext:o,dataArray:t,bufferLength:a,color:l})};return m(),()=>{s&&cancelAnimationFrame(s)}}import{jsx as Ua}from"react/jsx-runtime";function Se({analyser:e,bufferLength:a,dataArray:t,size:u,color:l,...d}){let o=qa(null),s=Ta(()=>()=>Ce(o.current),[]);return Ra(()=>{let m=ge(e,a,t,o,l||"white");return u||(window.addEventListener("resize",s),s()),()=>{window.removeEventListener("resize",s),m?.()}},[e,a,t,u,l,s]),Ua("canvas",{ref:o,width:u||400,height:u||400,style:{color:l,zIndex:0,...d.style},...d})}import{jsx as vo}from"react/jsx-runtime";import{Fragment as Ha,jsx as ce,jsxs as Oa}from"react/jsx-runtime";var we=({value:e,max:a,buffered:t,color:u,...l})=>{let d=a>0?e/a*100:0,o=a>0?t/a*100:0;return ce(Ha,{children:Oa("div",{className:"relative w-40 h-2 bg-gray-300 rounded overflow-hidden",children:[ce("div",{className:"absolute top-0 left-0 h-full bg-gray-400 transition-all duration-200 rounded w-full",style:{width:`${o}%`,transition:"width 0.2s ease-in-out"}}),ce("div",{className:"absolute top-0 left-0 h-full rounded transition-all duration-200",style:{width:`${d}%`,transition:"width 0.2s ease-in-out",backgroundColor:u||"#3b82f6"}}),ce("input",{type:"range",value:e,max:a,min:0,className:` h-1 w-20 appearance-none rounded-full bg-inherit/50 range-slider:h-2 range-slider:rounded-full ${l.className} `,style:{backgroundImage:`linear-gradient(to right, ${u??"#3b82f6"} ${d}%, transparent 0%)`,border:`1px solid ${u}`},onChange:s=>l.onChange?.(s),onInput:s=>l.onChange?.(s),...l})]})})};import{jsx as za}from"react/jsx-runtime";function Pe({value:e,onVolumeInput:a,color:t,...u}){return za("input",{type:"range",min:0,max:1,step:.01,value:e,onChange:l=>a(parseFloat(l.target.value)),className:` h-1 w-20 appearance-none rounded-full bg-inherit/50 range-slider:h-2 range-slider:rounded-full ${u.className} `,style:{backgroundImage:`linear-gradient(to right, ${t??"#3b82f6"} ${e*100}%, transparent 0%)`,border:`1px solid ${t}`},...u})}import{useEffect as ke,useRef as Ea,useState as _,useCallback as E,forwardRef as Ga}from"react";import{jsx as y,jsxs as pe}from"react/jsx-runtime";var G=Ga(function({src:a,autoplay:t=!1,loop:u=!1,showProgress:l=!0,showVolume:d=!0,onNext:o,onPrev:s,showNextPrevControls:m=!0,size:n=24,color:f=A.primary,...x},S){let L=Ea(null),i=S&&typeof S=="object"?S:L,[b,g]=_(!1),[w,I]=_(!1),[P,h]=_(.25),[c,C]=_(0),[M,W]=_(0),[B,R]=_(0);ke(()=>{let r=i.current;r&&(r.src=a,r.load(),r.volume=P,r.loop=u,r.autoplay=t,t?r.play().then(()=>I(!0)).catch(()=>I(!1)):I(!r.paused))},[a,t,u,P]);let D=E(r=>{r.preventDefault(),r.stopPropagation(),i.current&&i.current.play().then(()=>I(!0)).catch(()=>I(!1))},[i]),T=E(()=>{i.current&&(i.current.pause(),I(!1))},[]),U=E(r=>{h(r.currentTarget.volume)},[]),O=E(()=>{let r=i.current;r&&(r.volume!==0?(r.volume=0,h(0)):(r.volume=.25,h(.25)))},[]),q=E(r=>{let v=r.currentTarget;if(v.duration>0){for(let N=0;N<v.buffered.length;N++)if(v.buffered.start(v.buffered.length-1-N)<v.currentTime){C(v.buffered.end(v.buffered.length-1-N));break}}},[]),Ie=E(r=>{R(r.currentTarget.currentTime),q(r)},[q]),qe=E(r=>{W(r.currentTarget.duration)},[]),fa=E(r=>{W(r.currentTarget.duration),g(!0)},[]),ia=r=>{let v=r.target,Z=parseFloat(v.value);R(Z),i.current&&(i.current.currentTime=Z)};return ke(()=>{t&&b&&i.current&&I(!0)},[t,b]),ke(()=>{let r=i.current;if(!r)return;let v=()=>I(!0),Z=()=>I(!1),N=()=>R(r.currentTime),Ue=()=>{r.buffered.length>0&&C(r.buffered.end(r.buffered.length-1))},Oe=()=>W(r.duration);return r.addEventListener("play",v),r.addEventListener("pause",Z),r.addEventListener("timeupdate",N),r.addEventListener("progress",Ue),r.addEventListener("loadedmetadata",Oe),()=>{r.removeEventListener("play",v),r.removeEventListener("pause",Z),r.removeEventListener("timeupdate",N),r.removeEventListener("progress",Ue),r.removeEventListener("loadedmetadata",Oe)}},[a]),pe("div",{className:"flex flex-col items-center gap-5 relative",children:[y("div",{className:"flex items-center gap-2",children:y("audio",{...x,ref:i,onCanPlay:fa,onTimeUpdate:Ie,onDurationChange:qe,onVolumeChange:U,onPause:T,autoPlay:t,loop:u,preload:"auto",src:a,children:y(j,{src:a})})}),pe("div",{className:"flex flex-col items-center gap-4 z-30",children:[!w&&!t?y(F,{onClick:D,role:"button",name:"play",title:"play",children:y(k.Play,{})}):y(F,{onClick:T,role:"button",name:"pause",title:"pause",children:y(k.Pause,{})}),d&&pe("div",{className:"flex items-center gap-2",children:[y(F,{onClick:O,role:"button",name:"volume",title:"volume",children:P===0?y(k.VolumeOff,{}):P<.5?y(k.VolumeDown,{}):y(k.VolumeUp,{})}),y(Pe,{size:n,color:f,value:P,onVolumeInput:r=>{i.current&&(i.current.volume=r,h(r))}})]})]}),pe("div",{className:"flex items-center gap-2 justify-between relative",children:[m&&s&&y(F,{onClick:s,role:"button",name:"prev",title:"previous",children:y(k.SkipPrevious,{})}),l&&y(we,{color:f,value:B,max:M,buffered:c,onChange:ia}),m&&o&&y(F,{onClick:o,role:"button",name:"next",title:"next",children:y(k.SkipNext,{})})]})]})});import{useEffect as Xe,useRef as be,useCallback as Ae}from"react";import{useState as We,useRef as Q,useCallback as ye,useEffect as Va}from"react";function Ne(){let[e,a]=We(!1),[t,u]=We(null),l=Q(null),d=Q([]),o=Q(null),s=Q(null),m=Q(null),n=Q(null),f=ye(async()=>{let L=await navigator.mediaDevices.getUserMedia({audio:!0});l.current=new MediaRecorder(L),d.current=[],l.current.ondataavailable=i=>{i.data.size>0&&d.current.push(i.data)},l.current.onstop=()=>{let i=new Blob(d.current,{type:"audio/webm"});u(URL.createObjectURL(i))},l.current.start();try{if(typeof AudioContext<"u"){o.current=new AudioContext,s.current=o.current.createAnalyser(),m.current=o.current.createMediaStreamSource(L),m.current.connect(s.current),s.current.fftSize=2048;let i=s.current.fftSize;n.current=new Uint8Array(i)}}catch{}a(!0)},[]),x=ye(()=>{l.current?.stop();try{l.current?.stream?.getTracks?.().forEach(i=>i.stop())}catch{}o.current?.close(),a(!1)},[]),S=ye(()=>!s.current||!n.current?[]:(s.current.getByteTimeDomainData(n.current),[...n.current]),[]);return Va(()=>()=>{o.current&&o.current.close();try{l.current?.stream?.getTracks?.().forEach(i=>i.stop())}catch{}},[]),{recording:e,audioUrl:t,startRecording:f,stopRecording:x,getWaveformData:S}}import{jsx as V,jsxs as Ke}from"react/jsx-runtime";function Ze({className:e,waveColor:a=A.primary,width:t=400,height:u=80,onRecordingComplete:l}){let{recording:d,audioUrl:o,startRecording:s,stopRecording:m,getWaveformData:n}=Ne(),f=be(null),x=be(null),S=be(null);Xe(()=>{o&&fetch(o).then(g=>g.blob()).then(g=>{S.current=g,l?.(g)}).catch(()=>{})},[o,l]);let L=Ae(()=>{if(!d)return;let g=n(),w=x.current;if(w&&g&&g.length){let I=w.getContext("2d");if(I){I.clearRect(0,0,w.width,w.height),I.strokeStyle=a,I.lineWidth=2,I.beginPath();let P=g,h=w.width/P.length,c=0;for(let C=0;C<P.length;C++){let M=P[C];if(M===void 0)continue;let B=M/128*w.height/2;C===0?I.moveTo(c,B):I.lineTo(c,B),c+=h}I.stroke()}}f.current=requestAnimationFrame(L)},[n,d,a]);Xe(()=>(d?f.current=requestAnimationFrame(L):f.current&&(cancelAnimationFrame(f.current),f.current=null),()=>{f.current&&cancelAnimationFrame(f.current)}),[d,L]);let i=Ae(()=>{d?m():s()},[d,s,m]),b=Ae(()=>{if(!o)return;let g=document.createElement("a");g.href=o,g.download="recording.webm",document.body.appendChild(g),g.click(),document.body.removeChild(g)},[o]);return Ke("div",{className:e,style:{display:"flex",flexDirection:"column",alignItems:"center",gap:12},children:[Ke("div",{style:{display:"flex",gap:8},children:[V(F,{onClick:i,title:d?"Stop":"Record",children:d?V(k.Stop,{}):V(k.Mic,{})}),o&&V(F,{onClick:b,title:"Download",children:V(k.Download,{})})]}),V("canvas",{ref:x,width:t,height:u,style:{background:"#111",borderRadius:4,width:t,height:u}}),o&&V("div",{style:{width:t},children:V(G,{src:o,showNextPrevControls:!1,autoplay:!1,loop:!1,color:a})})]})}import{useCallback as Je,useMemo as Wa,useState as Na}from"react";import{jsx as Xa}from"react/jsx-runtime";function _e({srcs:e,autoplay:a=!1,color:t=A.primary,showNextPrevControls:u=!0,showProgress:l=!0,showVolume:d=!0,shuffle:o=!1,onNext:s,onPrev:m,...n}){let[f,x]=Na(0),S=Wa(()=>e[f]??"",[e,f]),L=Je(()=>e.length===0?0:o?Math.floor(Math.random()*e.length):(f+1)%e.length,[f,o,e]),i=Je(()=>e.length===0?0:o?Math.floor(Math.random()*e.length):(f-1+e.length)%e.length,[f,o,e]);return Xa(G,{color:t,autoplay:a,src:S,onNext:()=>{x(L()),s&&s()},onPrev:()=>{x(i()),m&&m()},showNextPrevControls:u,showProgress:l,showVolume:d,onEnded:()=>x(L()),...n})}import{useEffect as ve,useMemo as Ja,useRef as Qe,useState as je}from"react";import{useEffect as Ka,useState as Za}from"react";function Be(e,a,t,u){let[l,d]=Za(null);return Ka(()=>{if(!e||!a||a.state==="closed"){d(null);return}t.current||(t.current=a.createMediaElementSource(e));let o=a.createAnalyser();return o.fftSize=u,t.current.connect(o),o.connect(a.destination),d(o),()=>{o.disconnect();try{t.current?.disconnect()}catch(s){console.warn("Error disconnecting source node:",s)}d(null)}},[e,a,u,t]),l?{analyser:l,getFrequencyData:()=>{let o=l.frequencyBinCount,s=new Uint8Array(o);return l.getByteFrequencyData(s),s}}:null}import{jsx as Fe,jsxs as _a}from"react/jsx-runtime";function $e({src:e,size:a=420,color:t=A.primary,autoplay:u=!1,loop:l=!1,showProgress:d=!0,showVolume:o=!0,fftSize:s=2048,onLoad:m,...n}){let f=Qe(null),[x,S]=je(!1),[L,i]=je(null),b=Qe(null);ve(()=>{let P=requestAnimationFrame(()=>S(!!f.current));return()=>cancelAnimationFrame(P)},[]),ve(()=>{if(x&&(!L||L.state==="closed")){let P=new AudioContext;i(P)}},[x,L]);let g=Be(x?f.current:null,L,b,s),w=g?.analyser.frequencyBinCount,I=Ja(()=>w?new Uint8Array(w):null,[w]);return ve(()=>()=>{L&&L.state!=="closed"&&L.close(),b.current?.disconnect()},[L]),Fe("div",{...n,style:{display:"flex",justifyContent:"center",alignItems:"center",width:"100%",maxWidth:"400px",position:"relative",borderRadius:"8px",backgroundColor:"transparent",gap:"8px",minHeight:"200px",...n.style},children:_a("div",{style:{position:"relative",width:"100%",height:"100px"},children:[g?.analyser&&I&&w&&Fe(Se,{analyser:g.analyser,bufferLength:w,dataArray:I,size:a,color:t,width:a,height:a,style:{position:"absolute",inset:0,width:"100%",height:"100%",opacity:.8,pointerEvents:"none",zIndex:0}}),Fe(G,{src:e,autoplay:u,loop:l,showProgress:d,showVolume:o,color:t,onLoad:m,showNextPrevControls:!1,size:a,ref:f})]})})}import{useEffect as Me,useRef as De,useState as Re}from"react";import{jsx as X,jsxs as K}from"react/jsx-runtime";function Ye({type:e="sine",frequency:a=440,gain:t=.5,isPlaying:u=!1,onPlayChange:l,showControls:d=!0,onFrequencyChange:o,onGainChange:s,...m}){let n=De(null),f=De(null),x=De(null),[S,L]=Re(a),[i,b]=Re(t),[g,w]=Re(!!u),I=typeof u=="boolean"?u:g,P=()=>(n.current||(n.current=new AudioContext),n.current),h=()=>{try{f.current?.stop()}catch{}f.current?.disconnect(),x.current?.disconnect(),f.current=null,x.current=null};return Me(()=>{if(I){let c=P();if(f.current){let C=n.current;f.current.frequency.setValueAtTime(S,C.currentTime),x.current.gain.setValueAtTime(i,C.currentTime)}else{let C=c.createOscillator(),M=c.createGain();C.type=e,C.frequency.setValueAtTime(S,c.currentTime),M.gain.setValueAtTime(i,c.currentTime),C.connect(M),M.connect(c.destination),C.start(),f.current=C,x.current=M}}else h();return()=>{}},[I,e,S,i]),Me(()=>{let c=()=>{n.current&&n.current.state==="suspended"&&n.current.resume()};return window.addEventListener("pointerdown",c,{once:!0}),()=>{window.removeEventListener("pointerdown",c)}},[]),Me(()=>()=>{h(),n.current&&n.current.state!=="closed"&&n.current.close().catch(()=>{}),n.current=null},[]),K("div",{...m,className:`flex flex-col gap-2 items-center ${m.className}`,children:[d&&X("div",{className:"flex items-center gap-2",children:X(F,{title:I?"Pause":"Play","aria-label":I?"Pause oscillator":"Play oscillator",onClick:()=>{typeof u=="boolean"&&l?l(!u):w(c=>!c)},children:I?X(k.Pause,{}):X(k.Play,{})})}),K("div",{className:"flex flex-col gap-2",children:[K("label",{className:"flex items-center gap-2",children:[K("span",{children:["Frequency: ",K("span",{className:"font-mono",children:[S," Hz"]})]}),X("input",{className:"disabled:opacity-50 disabled:cursor-not-allowed",type:"range",min:20,max:2e3,value:S,onChange:c=>{let C=parseFloat(c.target.value);L(C),o?.(C),f.current&&f.current.frequency.setValueAtTime(C,n.current?.currentTime??0)}})]}),K("label",{className:"flex items-center gap-2",children:[K("span",{children:["Gain: ",X("span",{className:"font-mono",children:i})]}),X("input",{type:"range",className:"disabled:opacity-50 disabled:cursor-not-allowed",min:0,max:1,step:.01,value:i,onChange:c=>{let C=parseFloat(c.target.value);b(C),s?.(C),x.current&&x.current.gain.setValueAtTime(C,n.current?.currentTime??0)}})]})]})]})}import{useCallback as Qa,useEffect as ja,useRef as me,useState as ea}from"react";import{jsx as Le,jsxs as $a}from"react/jsx-runtime";function Te({audioRef:e,fftSize:a=1024,width:t="100%",height:u="25%",minDecibels:l=-100,maxDecibels:d=-25,colorMap:o=["#111","#ff0000","#ffff00","#ffffff"],onFrameUpdate:s,fillStyle:m,loop:n=!1,smoothingTimeConstant:f=.8,...x}){let S=me(null),L=me(null),i=me(null),[b,g]=ea(!1),[w,I]=ea(!1),P=Qa(()=>{if(b){e.current.pause(),g(!1);return}if(e.current){if(!L.current){let h=new AudioContext,c=h.createAnalyser();L.current=h,i.current=c,c.fftSize=a,c.minDecibels=l,c.maxDecibels=d,c.smoothingTimeConstant=f,h.createMediaElementSource(e.current).connect(c),c.connect(h.destination)}if(L.current.state==="suspended"&&L.current.resume(),e.current.paused){let h=e.current.play();h!==void 0&&h.then(()=>{g(!0)}).catch(c=>{console.error("Error playing audio:",c)})}n&&(e.current.loop=!0)}},[]);return ja(()=>{if(!S.current||!e.current)return;let h=S.current,c=h.getContext("2d");if(!c)return;h.width=800,h.height=400;let C=(B,R,D)=>`#${B.slice(1).match(/.{2}/g).map((U,O)=>{let q=parseInt(U,16),Ie=parseInt(R.slice(1).match(/.{2}/g)[O],16);return Math.round(q+D*(Ie-q)).toString(16).padStart(2,"0")}).join("")}`,M=B=>{let D=B/255*(o.length-1),T=Math.floor(D),U=D-T,O=o[T],q=o[T+1]||O;return C(O,q,U)},W=()=>{if(!h||!c||!i.current)return;let B=i.current.frequencyBinCount,R=new Uint8Array(B);i.current.getByteFrequencyData(R),c.fillStyle=m||"rgba(0, 0, 0, 0.5)",c.fillRect(0,0,h.width,h.height);for(let D=0;D<B;D++){let T=R[D],U=T/255*h.height,O=h.height-U,q=h.width/B;c.fillStyle=M(T),c.fillRect(D*q,O,q,U)}requestAnimationFrame(W),s?.(R)};b&&W()},[o,m,b,s]),Le("canvas",{...x,onClick:()=>{P(),I(!0)},ref:S,style:{width:t,height:u},className:`border border-zinc-800/65 dark:border-zinc-500/65 rounded-md backdrop:invert-50 cursor-pointer ${w?"":"bg-zinc-700/50 animate-pulse hover:border-2 transition-all hover:bg-zinc-700/75 hover:animate-none"}`})}function aa({src:e,fftSize:a,width:t,height:u,minDecibels:l,maxDecibels:d,colorMap:o,smoothingTimeConstant:s,onFrameUpdate:m,loop:n,fillStyle:f,...x}){let S=me(null);return $a("div",{...x,children:[Le("audio",{ref:S,children:Le(j,{src:e})}),Le(Te,{audioRef:S,fftSize:a,width:t,height:u,minDecibels:l,maxDecibels:d,colorMap:o,smoothingTimeConstant:s,onFrameUpdate:m,fillStyle:f,loop:n})]})}var ta={title:"Player",description:"A simple audio player component.",url:"",props:{src:{value:"string",description:"The source URL of the audio file.",required:!0,default:void 0},size:{value:"number",description:"The size of the player.",required:!1,default:void 0},color:{value:"string",description:"The color of the player.",required:!1,default:A.primary},autoplay:{value:"boolean",description:"Whether the audio should start playing automatically.",required:!1,default:!1},loop:{value:"boolean",description:"Whether the audio should loop.",required:!1,default:!1},showProgress:{value:"boolean",description:"Whether to show the progress bar.",required:!1,default:!0},showVolume:{value:"boolean",description:"Whether to show the volume control.",required:!1,default:!0},showNextPrevControls:{value:"boolean",description:"Whether to show the next and previous controls (used within ShufflePlayer).",required:!1,default:!1},audioRef:{value:"RefObject<HTMLAudioElement | null>",description:"A ref to the audio element.",required:!1,default:void 0},onNext:{value:"() => void",description:"Callback function for the next button. (used within ShufflePlayer)",required:!1,default:void 0},onPrev:{value:"() => void",description:"Callback function for the previous button. (used within ShufflePlayer)",required:!1,default:void 0}}};var oa={title:"ShufflePlayer",description:"A simple audio player component with shuffle functionality.",url:"",props:{srcs:{value:"string[]",description:"An array of source URLs for the audio files.",required:!0,default:void 0},autoplay:{value:"boolean",description:"Whether the audio should start playing automatically.",required:!1,default:!1},color:{value:"string",description:"The color of the player.",required:!1,default:A.primary},showNextPrevControls:{value:"boolean",description:"Whether to show the next and previous controls.",required:!1,default:!0},showProgress:{value:"boolean",description:"Whether to show the progress bar.",required:!1,default:!0},showVolume:{value:"boolean",description:"Whether to show the volume control.",required:!1,default:!0},shuffle:{value:"boolean",description:"Whether to shuffle the audio files. If true, a random file will be played each time.",required:!1,default:!1}}};var ua={title:"Waveform",description:"A waveform component that visualizes audio data in a canvas element.",url:"",props:{src:{value:"string",description:"The source URL of the audio file to visualize. (internal unless CORS settings are configured)",required:!0,default:void 0},size:{value:"number",description:"The size of the canvas element in pixels.",required:!1,default:420},color:{value:"string",description:"The color of the waveform.",required:!1,default:"primary"},autoplay:{value:"boolean",description:"Whether to autoplay the audio when the component is mounted.",required:!1,default:!1},loop:{value:"boolean",description:"Whether to loop the audio playback.",required:!1,default:!1},showProgress:{value:"boolean",description:"Whether to show the progress of the audio playback.",required:!1,default:!1},showVolume:{value:"boolean",description:"Whether to show the volume control.",required:!1,default:!1},fftSize:{value:"number",description:"The size of the FFT (Fast Fourier Transform) used for audio analysis.",required:!1,default:2048},onLoad:{value:"() => void",description:"Callback function to be called when the audio is loaded.",required:!1,default:void 0},audioRef:{value:"RefObject<HTMLAudioElement | null> | null",description:"A reference to the HTML audio element. If not provided, a new ref will be created.",required:!1,default:null}}};var ra={title:"Oscillator",description:"An oscillator component that generates sound waves based on gain and frequency.",url:"",props:{type:{value:"OscillatorType",description:"The type of oscillator wave (e.g., sine, square, sawtooth, triangle).",required:!1,default:"sine"},frequency:{value:"number",description:"The frequency of the oscillator in Hz.",required:!1,default:440},gain:{value:"number",description:"The default gain (volume) of the oscillator.",required:!1,default:.5},onPlayChange:{value:"(playing: boolean) => void",description:"Callback function to handle play/pause changes.",required:!1,default:void 0},isPlaying:{value:"boolean",description:"Whether the oscillator is currently playing sound.",required:!1,default:!1},onFrequencyChange:{value:"(frequency: number) => void",description:"Callback function to handle frequency changes.",required:!1,default:void 0},onGainChange:{value:"(gain: number) => void",description:"Callback function to handle gain changes.",required:!1,default:void 0}}};var la={title:"Spectrogram",description:"A component that visualizes audio data as a spectrogram.",url:"",props:{src:{value:"string",description:"The source URL of the audio file to visualize.",required:!0,default:void 0},fftSize:{value:"number",description:"The size of the FFT (Fast Fourier Transform) used for audio analysis.",required:!1,default:1024},width:{value:"number | string",description:"The width of the spectrogram display.",required:!1,default:"100%"},height:{value:"number | string",description:"The height of the spectrogram display.",required:!1,default:"25%"},minDecibels:{value:"number",description:"The minimum decibel level for the spectrogram display.",required:!1,default:-100},maxDecibels:{value:"number",description:"The maximum decibel level for the spectrogram display.",required:!1,default:-25},colorMap:{value:"string[]",description:"An array of colors to use for the spectrogram visualization.",required:!1,default:["#111","#ff0000","#ffff00","#ffffff"]},smoothingTimeConstant:{value:"number",description:"The smoothing time constant for the analyser node.",required:!1,default:.8},onFrameUpdate:{value:"(data: Uint8Array) => void",description:"Callback function to handle frame updates with audio data.",required:!1,default:void 0},loop:{value:"boolean",description:"Whether to loop the audio playback.",required:!1,default:!1},fillStyle:{value:"string",description:"The fill style for the spectrogram canvas.",required:!1,default:void 0}}};var da={title:"AudioRecorder",description:"Record, preview, and download audio.",url:"",props:{waveColor:{value:"string",default:"rgb(236, 106, 177)",description:"The color of the waveform & preview.",required:!1},width:{value:"number",default:400,description:"The width of the audio recorder.",required:!1},height:{value:"number",default:80,description:"The height of the audio recorder.",required:!1}}};var sa={Player:ta,ShufflePlayer:oa,Waveform:ua,Oscillator:ra,Spectrogram:la,AudioRecorder:da};export{Ze as AudioRecorder,Ye as Oscillator,G as Player,_e as ShufflePlayer,Te as SpectroGramDisplay,aa as Spectrogram,$e as Waveform,sa as components,Be as useAudioAnalyser}; /*! Bundled license information: lucide-react/dist/esm/shared/src/utils.js: lucide-react/dist/esm/defaultAttributes.js: lucide-react/dist/esm/Icon.js: lucide-react/dist/esm/createLucideIcon.js: lucide-react/dist/esm/icons/circle-stop.js: lucide-react/dist/esm/icons/download.js: lucide-react/dist/esm/icons/fast-forward.js: lucide-react/dist/esm/icons/hourglass.js: lucide-react/dist/esm/icons/loader-circle.js: lucide-react/dist/esm/icons/mic.js: lucide-react/dist/esm/icons/pause.js: lucide-react/dist/esm/icons/play.js: lucide-react/dist/esm/icons/rewind.js: lucide-react/dist/esm/icons/skip-back.js: lucide-react/dist/esm/icons/skip-forward.js: lucide-react/dist/esm/icons/square-square.js: lucide-react/dist/esm/icons/square.js: lucide-react/dist/esm/icons/volume-2.js: lucide-react/dist/esm/icons/volume-1.js: lucide-react/dist/esm/icons/volume-x.js: lucide-react/dist/esm/lucide-react.js: (** * @license lucide-react v0.513.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. *) */ //# sourceMappingURL=index.js.map