UNPKG

@clxrity/react-audio

Version:

An interactive audio package for React

691 lines (501 loc) 25.3 kB
# Changelog ## 3.2.0 ### Minor Changes - Add new `AudioLooper` component + `useAudioLooper` hook for multi-track loop recording: - Record multiple synchronized audio loops with configurable duration (1-16 seconds). - Individual track controls: record, play/pause, volume, clear, and remove. - Master controls: volume, play all, stop all, clear all tracks. - Real-time progress visualization for each track during playback. - Automatic loop synchronization across all tracks. - Track limit configuration (default 8, customizable). - Built-in polyfills and error handling for robust operation. Perfect for musicians, beat-making, live performance, and creative audio applications. ### Patch Changes - - Fixed typo in FFTSize type name - Exported all hooks: - useAudioAnalyser - useAudioLooper - useAudioRecorder - - Updated all dependencies to latest versions. ## 3.1.0 ### Minor Changes - Add new `AudioRecorder` component + `useAudioRecorder` hook integration: - Start/stop microphone capture via MediaRecorder. - Live time-domain waveform visualization while recording. - Automatic object URL generation for playback & download. - Download button to save the recording (`recording.webm`). - Graceful fallbacks & test polyfills (AudioContext optional, URL.createObjectURL mocked in tests). Includes internal hook hardening (defensive AudioContext guards, stream track cleanup). ### Patch Changes - Every component now has TypeScript comments for better documentation and type safety. ## 3.0.4 ### Patch Changes - Added missing documentation for remaining components in the library. - `<Spectrogram />`: A component that visualizes the frequency spectrum of an audio signal. - [Documentation | Spectrogram](https://react-audio-docs.vercel.app/docs/components/spectrogram) - `<Oscillator />`: A component that generates an audio oscillator node for sound synthesis. - [Documentation | Oscillator](https://react-audio-docs.vercel.app/docs/components/oscillator) - The **`<Oscillator />`** component has been updated to improve its responsiveness to play/pause changes. - Fixed an issue where the `<Oscillator />` component would not properly respond to play/pause changes. - Improved the internal state management of the `<Oscillator />` component to ensure consistent behavior across different playback scenarios. Added a prop to control `onPlayChange` behavior. ```tsx "use client"; import { Oscillator } from "@clxrity/react-audio"; import { useState } from "react"; export function OscillatorExample() { const [isPlaying, setIsPlaying] = useState(false); const handlePlayChange = (playing: boolean) => { setIsPlaying(playing); }; return <Oscillator onPlayChange={handlePlayChange} isPlaying={isPlaying} />; } ``` - Stabilize seeking via progress slider and improve range input behavior. - Player: Read progress value from `event.target.value` in the seek handler to ensure compatibility with both `change` and `input` events across environments. - Progress: Forward `onInput` to the provided `onChange` handler so range slider updates fire consistently in browsers and jsdom. - Tests: Harden Player interactions seek test by dispatching `loadedmetadata` in `act`, using `input` events, and sanity-checking a writable `currentTime`. Added/used global test stubs for media/canvas APIs to reduce jsdom noise. Result: All tests pass; no breaking API changes. This is a bugfix-level patch improving reliability of seeking and slider interactions. ## 3.0.3 ### Patch Changes - Refactor: better cleanup, typing, and UI polish across components and utils. - Player - Proper ref forwarding with internal fallback; unified media event handling; cleaned effect deps; synced `isPlaying` via play/pause events. - Avoid duplicate type detection on `<source>`; rely on `AudioSource` to infer. - ShufflePlayer - Correct prop typing (`srcs: string[]`), no render-time state updates, robust next/prev index logic, and auto-advance on `ended`. - Waveform / Canvas / draw / animate - `draw()` returns a cleanup function and cancels `requestAnimationFrame` to prevent leaks. - `Canvas` uses the cleanup, memoized resize handler, and initial resize when size not provided. - Avoid re-creating `Uint8Array` per render; memoize based on `frequencyBinCount`. - AudioSource - Derives MIME type from `src` when `type` not provided, defaulting to `audio/*`. - Progress / VolumeSlider - Fix gradient track styling by using `backgroundImage` with correct percentages. - Spectrogram - Tidy class names; no behavior change. - Utils & types - Use type-only exports in barrel; improve docs-`Component` prop typing; minor animate typings. - Constants - Fix `VolumeOff` icon mapping; correct `black` hex. Internal: no public API changes expected; minor visual adjustments and runtime stability improvements (cleanup of RAF). ## 3.0.2 ### Patch Changes - aaa0719: Fixed components and hooks to correctly utilize the audio reference for playback and analysis. - Updated **Player** component to ensure it uses the audio ref properly for playback control. - Updated **useAudioAnalyser** hook to ensure it correctly accesses the audio element for analysis. - Updated **Waveform** component to ensure it uses the audio ref for waveform rendering. - 0fac93a: Fixed the style of the progress input bar - f8eedaa: Added sub components section within documentation for pages for each component - cbe9ae1: Added homepage ## 3.1.0 ### Minor Changes - 836e785: Finished mono-repo move ### Patch Changes - 87f8047: - Updated documentation to include changelog - Created `prebuild` script to copy the changelog to the docs - Updated `README.md` to include changelog link - 1bedd1f: Re-wrote [CONTRIBUTING.md](https://github.com/clxrityy/react-audio/blob/main/CONTRIBUTING.md) to encapsulate the new structure of the repository and the development workflow. ## 3.0.0 ### Major Changes - Switched structure to a [turborepo](https://turbo.build/repo/docs) structure. - The main package is now in the `packages/main` directory. - The documentation is now in the `apps/docs` directory. - The documentation is now built with [Next.js](https://nextjs.org/) & [nextra](https://nextra.site/). - The package is now built with [tsup](https://tsup.dev/) instead of [vite](https://vitejs.dev/). - Refactored the build process to use `tsup` for building the package. - Removed many unnecessary dependencies that were used for the previous build process. - Additional utility packages (pre-included by turbo) are utilized thourghout the codebase: - `@repo/typescript-config` - Shared TypeScript configurations - `@repo/eslint-config` - Shared ESLint configurations ## 2.5.1 ### Patch Changes - 04149cb: fix docs favicon ## 2.5.0 ### Minor Changes - 4ce0d12: Add eslint - 79bad00: Add sitemap - Created `scripts/generate-sitemap.cjs` that runs after building the docs - Utilizes `ladle`'s `meta.json` to get the routes - fc5d270: add SECURITY.md - 8f4fc86: add CODE_OF_CONDUCT.md - fb89952: add vscode extension recommendations - b90bc02: add robots.txt - 75fd845: update node version 23.6.0 -> 23.6.1 - 1ab91ae: add CONTRIBUTING.md - 1574dd6: add code coverage ### Patch Changes - 5ca96a9: changed prettier tab width to 2 - 624ed09: fix all eslint errors - dfadccd: Fix play/pause button for autoplay - 226e7d6: Remove @mui packages - replace with lucide-react for icons - eae2ee1: remove unnecessary props from Spectrogram (realTime & logarithmicScale) ## 2.4.0 ### Minor Changes - 96b7a45: Add `<Oscillator />` component This produces periodic signal with the type of wave specified by the `type` ([`OscillatorType`](https://developer.mozilla.org/en-US/docs/Web/API/OscillatorNode/type)) prop. The component is a wrapper around the Web Audio API's [`OscillatorNode`](https://developer.mozilla.org/en-US/docs/Web/API/OscillatorNode). You must pass the `isPlaying` boolean prop to start and stop the oscillator. ### Parameters | Param | Type | Description | Default | Required | | ----------------- | ----------------------------- | ---------------------------------------- | -------- | -------- | | type | `OscillatorType` | The type of wave to produce | `'sine'` | ❌ | | isPlaying | `boolean` | Whether the oscillator should be playing | `false` | ✅ | | frequency | `number` | The frequency of the oscillator in hertz | `440` | ❌ | | gain | `number` | The gain of the oscillator | `0.5` | ❌ | | onFrequencyChange | `(frequency: number) => void` | Callback when the frequency changes | N/A | ❌ | | onGainChange | `(gain: number) => void` | Callback when the gain changes | N/A | ❌ | #### Example with Next.js ```tsx "use client"; import { Oscillator, type OscillatorProps } from "@clxrity/react-audio"; export default function Home() { const [isPlaying, setIsPlaying] = useState(false); return ( <div> <button onClick={() => setIsPlaying(!isPlaying)}> {isPlaying ? "Stop" : "Start"} </button> <Oscillator type="sine" isPlaying={isPlaying} /> </div> ); } ``` ### Patch Changes - 72089dd: Fix development environment to support the latest version of pnpm ## 2.2.1 ### Patch Changes - 6959472: fix spectrogram ## 2.2.0 ### Minor Changes - 13b68de: Add the `<Spectrogram />` component. #### Parameters | Param | Type | Description | Default | Required | | --------------------- | ----------------- | ---------------------------------------------------------------------------------------------------------- | ---------------------------------------------- | -------- | | track | `Track` | The track to display the spectrogram of. | N/A | ✅ | | fftSize | `FFTSize` | The size of the FFT to use. | `1024` | ❌ | | width | `number`/`string` | The width of the spectrogram. | `100%` | ❌ | | height | `number`/`string` | The height of the spectrogram. | `25%` | ❌ | | minDecibels | `number` | The minimum decibels to display. | `-100` | ❌ | | maxDecibels | `number` | The maximum decibels to display. | `-30` | ❌ | | colorMap | `Array<string>` | The color map to use. | `["#000000", "#ff0000", "#ffff00", "#ffffff"]` | ❌ | | smoothingTimeConstant | `number` | The smoothing time constant to use. | `0.8` | ❌ | | realTime | `boolean` | Whether to display the spectrogram in real time. | `true` | ❌ | | logarithmicScale | `boolean` | Whether to use a logarithmic scale. | `true` | ❌ | | onFrameUpdate | `Function` | A callback to be called when a new frame is available. Accepts a data array (`Uint8Array`) as a parameter. | N/A | ❌ | | loop | `boolean` | Whether to loop the audio. | `false` | ❌ | | fillStyle | `string` | The background fill of the canvas | `#000000` | ❌ | #### Example ```tsx <Spectrogram track={track} fftSize={1024} width={500} height={300} minDecibels={-100} maxDecibels={-30} colorMap={["#000000", "#ff0000", "#ffff00", "#ffffff"]} smoothingTimeConstant={0.8} realTime={true} logarithmicScale={true} onFrameUpdate={() => {}} loop={true} fillStyle="rgba(0, 0, 0, 0.5)" /> ``` - 9540893: Update dependencies ## 2.1.0 ### Minor Changes - 910a28d: Add a **border** prop to ShufflePlayer - ed9308c: Add more stories for `<ShufflePlayer />` - **Dont show tracks** - Example not displaying the track information - **Custom color** - Example of changing the color of the player - **Custom border** - Example of changing the border of the player - c802826: Add some development dependencies to optimize the visibility of the docs, make the default mode dark. **New Dependencies:** - [`baseui`](https://github.com/uber/baseweb#readme) - [`styletron-react`](https://www.npmjs.com/package/styletron-react) - [`styletron-engine-monolithic`](https://www.npmjs.com/package/styletron-engine-monolithic) **Changes:** ```mjs // .ladle/config.mjs /** @type {import('@ladle/react').UserConfig} */ export default { // ... addons: { // ... theme: { enabled: true, defaultState: "dark", }, }, }; ``` ```tsx // .ladle/components.tsx import { Provider as StyletronProvider } from "styletron-react"; import { Client as Styletron } from "styletron-engine-monolithic"; import { LightTheme, DarkTheme, BaseProvider } from "baseui"; import type { GlobalProvider } from "@ladle/react"; const engine = new Styletron(); export const Provider: GlobalProvider = ({ children, globalState }) => ( <StyletronProvider value={engine}> <BaseProvider theme={{ ...(globalState.theme === "dark" ? DarkTheme : LightTheme), direction: globalState.rtl ? "rtl" : "ltr", }} > <div className="docs-container"> <div className="docs-main">{children}</div> </div> </BaseProvider> </StyletronProvider> ); ``` - 1f6297b: Update **ShufflePlayer** props to include showTracks which can optionally hide the display of all the tracks ### Patch Changes - 218df0a: Fix docs output (default story, output directory) - 11ec0e2: Add a script to run after building the documentation to fix the metadata. Before, the `<link />` tags were being generated with the wrong `href` attribute. This script will fix the `href` attribute to point to the correct location. - The `href` attribute was being generated as `/assets/...` instead of `./assets/...` ```json { "scripts": { "build:ladle": "ladle build && node scripts/docs-postbuild.cjs" } } ``` ```cjs const fs = require("fs"); const path = require("path"); const indexPath = path.join(__dirname, "../docs", "index.html"); fs.readFile(indexPath, "utf8", (err, data) => { if (err) { console.error("Error reading index.html", err); process.exit(1); } // Replace absolute asset paths with relative ones (e.g., '/assets' to './assets') let updatedData = data .replace(/href="\/assets/g, 'href="./assets') .replace(/src="\/assets/g, 'src="./assets'); updatedData = updatedData.replace( /<meta name="dscription"[^>]*>/, '<meta name="description" content="A collection of audio components for React applications" />', ); updatedData = updatedData.replace(/<link rel="icon"[^>]*>/, ""); updatedData = updatedData.replace(/<link rel="apple-touch-icon"[^>]*>/, ""); updatedData = updatedData.replace(/<link rel="manifest"[^>]*>/, ""); updatedData = updatedData.replace(/<title>Ladle<\/title>/, ""); fs.writeFile(indexPath, updatedData, "utf-8", (err) => { if (err) { console.error("Error writing index.html", err); process.exit(1); } else { console.log("index.html updated successfully"); } }); }); ``` ## 2.0.2 ### Patch Changes - 4853714: Fix the ability to import the package's css file. Before it was bundling into `dist/src/index.css` which was not being imported correctly. Upon trying to fix it, it would bundle as `react-audio.css` which was not the desired output. - Altered `vite.config.ts` to output the css to `dist/index.css` - Added a custom `rename-css-plugin` to vite plugins: ```ts import { UserConfigExport } from "vite"; import { renameSync } from "fs"; // NEW import path from "path"; import { defineConfig } from "vitest/config"; // ... const app = async (): Promise<UserConfigExport> => { return defineConfig({ plugins: [ //.. prev plugins, { name: "rename-css-plugin", closeBundle() { const oldPath = path.resolve(__dirname, "dist/react-audio.css"); const newPath = path.resolve(__dirname, "dist/index.css"); try { renameSync(oldPath, newPath); // FIX } catch (error) { console.error(error); } }, }, ], }); }; ``` - Also added a way to import within css by updating `css.preprocessorOptions` in `vite.config.ts`: ```ts css: { preprocessorOptions: { scss: { additionalData: `@import "@clxrity/react-audio/index.css";`; } } } ``` You can now import within your css file like so: ```css @import "@clxrity/react-audio/index.css"; ``` And within your js/ts file like so: ```ts import "@clxrity/react-audio/index.css"; ``` ## 2.0.0 ### Major Changes - b82ecec: - Switched from [storybook](https://storybook.js.org/) to [ladle](https://ladle.dev/) - Much more lightweight and faster - A lot more of a simple UI to work with - Text and colors are automatically inherited by the theme. - Dark background = white text - Light background = black text - Components in new working new version so far: - `<Player />` - Replaces `<JustPlayer />` & `<AudioPlayer />` - `<ShufflePlayer />` - Replaces `<LibraryPlayer />` - `<Waveform />` Working structure: ```yaml ~: __tests__/: # Tests with vitest .changeset/: # Changeset version management .github/: # Github workflows .ladle/: # Ladle setup for documenation docs/: # Output from ladle for github pages public/: # Public static directory src/: components/ui/: # Reusable UI components hooks/: # Reusable hooks lib/: # The package exports - ... - index.ts # Main entry point stories/: # Ladle stories util/: # Utility functions - config.ts # Default configurations - index.css # Global CSS ... ``` - 22f001e: - Update all dependencies - Begin restructuring code - Switch to Vite - Switch from styled components to tailwind - Add new logo - Add new landing page - Add new documentation - Add new examples - Add new audio player ### Minor Changes - e8d4166: update all packages to latest version - 149e841: Added the Player component which will replace JustPlayer & AudioPlayer into one component (with props for customization) - e155be4: add functionality to EQ & volume knobs (**AudioInputVisualizer**) - 6f1c415: Added a code coverage workflow that indicates whether all [`vitest`](https://vitest.dev/) tests are passing. - Utilizes [Codecov](https://about.codecov.io/) to provide an interactive UI for test coverage. - Added an environment variable `CODECOV_TOKEN` to the repository's secrets and local `.env` file. - Added a new script `npm run coverage` to generate and upload the coverage report. - 8172042: added the Waveform component, working perfectly. might need some style tweaks and configurations down the road - f1a1c48: Add a new \***\*tests\*\*** directory to contain public tests - f102a1f: Finished the Player component with a progress bar, autoplay feature, ability to disable progress bar and track info display ## 1.7.0 ### Minor Changes - f5abd36: added **AudioUploader** functional with no UI display yet - d89e093: add **resize()** function to **Waveform**'s canvas if no size prop is present - 23839c0: **AudioInputVisualizer** works fully functional - ba70a93: began **AudioInput** component where you can input audio mic/guitar - bb9f2b5: added prop to **Waveform** & **AudioInputVisualizer**: fftsize ### Patch Changes - be63b43: re-added imports for libraryplayer & librarytrackitem ## 1.6.0 ### Minor Changes - 9ba3169: update props setup, all now have specific inherited props - 0422a54: update storybook ### Patch Changes - ad13785: fix imports and props passing on ## 1.5.0 ### Minor Changes - dbc2980: add docs - 7d930b0: add nextjs app to docs - e56a5f9: added a script that generates an api route for creating a waveform image ## 1.4.0 ### Minor Changes - 832989e: added jest, testing ffmpeg features to create waveforms - f7f4d6f: restructure files (exports in src/lib/) ### Patch Changes - c650b27: make all exports default - 610d33d: fixed jest interfering with rollup build - 3a33cf0: ability to change color in waveforms actually works now ## 1.3.0 ### Minor Changes - 48caa05: change styled-components to devDependency - 7560f63: update packages - 0dff7df: add **showTrackInfo** prop to **Waveform** ### Patch Changes - aa2aaa1: remove tailwindcss dependency - 3bd6fe5: fix progress bar on waveform ## 0.14.0 ### Minor Changes - cd32bde: more styling updates to library - 2061b0b: update readme - 596d485: add other components to **Waveform** - e95dde9: updated styles for **AudioPlayer** (removed unused thumbnail) ### Patch Changes - cb432a6: **Waveform** is functional, no errors, need to add other component parts - 8ef7746: waveform now works - ce890a9: fix dom errors ## 0.13.0 ### Minor Changes - 1659bd6: begin **Waveform** component, existing error: "Uncaught DOMException: Failed to execute 'createMediaElementSource' on 'AudioContext': HTMLMediaElement already connected previously to a different MediaElementSourceNode." - fdf559b: style updates to library player ## 0.11.0 ### Minor Changes - 39ed441: add loading states to every component ### Patch Changes - 7a5aca2: fix error "rounded is not defined" prop with **Button** ## 0.10.0 ### Minor Changes - c1c9610: removed **AudioPlayer** for now - 9bb0c8d: added (begun) **`<AudioPlayer />`** ### Patch Changes - 8cd2ac2: fix "Audio is not defined" error in **`<JustPlayer />`** - 4af6757: fix **JustPlayer**: no more useEffect issue - 213a90c: fixed "variant" unknown prop in **`<Button /`>**, will find better ways to update styles and theming ## 0.9.0 ### Minor Changes - 4f368d5: **AudioLibrary** is fully functional and styled nicely for now, updated readme & package.json - 1f5711c: change library component to **AudioLibrary** with states and styles inside ## 0.8.0 ### Minor Changes - 469f488: add / begin `<LibraryPlayer />` component - aec2e66: add styled-components ### Patch Changes - 60d76fd: `<LibraryPlayer />` now works (somewhat) ## 0.7.0 ### Minor Changes - 62c85bf: update packages ### Patch Changes - 443185b: `<JustPlayer />` now works (plays audio) ## 0.6.0 ### Minor Changes - 6e7d46f: updated visuals to `<AudioPlayer />`, began `<JustPlayer />` ## 0.5.0 ### Minor Changes - 3dc1f94: add background color param - df5f580: add license and npmignore ### Patch Changes - fc106f5: it works now - df5f580: make changeset a dev dependency ## 0.4.0 ### Minor Changes - d184bff: made component export & import into applications properly, `<AudioPlayer />` component is now (semi) functional and visible - f5c0d15: structuring `AudioPlayer` component. began exporting compatible types for the (optional) options (styling so far) ## 0.3.0 ### Minor Changes - af6c419: test tailwindcss - 7cacb07: begin functionality of audio component ### Patch Changes - 7cacb07: change name of `Player` to `AudioPlayer` ## 0.2.0 ### Minor Changes - begin testing, add changeset, begin development process