@clxrity/react-audio
Advanced tools
@@ -1,2 +0,2 @@ | ||
import { default as AudioLibrary, default as LibraryPlayer, default as LibraryTrackItem } from './lib/AudioLibrary'; | ||
import AudioLibrary from './lib/AudioLibrary/component'; | ||
import AudioPlayer from './lib/AudioPlayer'; | ||
@@ -6,3 +6,3 @@ import JustPlayer from './lib/JustPlayer'; | ||
import type { Track } from './types'; | ||
export { AudioLibrary, AudioPlayer, JustPlayer, LibraryPlayer, LibraryTrackItem, Waveform, }; | ||
export { AudioLibrary, AudioPlayer, JustPlayer, Waveform, }; | ||
export type { Track }; |
@@ -7,3 +7,3 @@ import AudioPlayer from './AudioPlayer'; | ||
AudioLibrary: { | ||
AudioLibrary: typeof import("./AudioLibrary/component").default; | ||
AudioLibrary: typeof import("..").AudioLibrary; | ||
LibraryPlayer: typeof import("./AudioLibrary/elements/Player").default; | ||
@@ -17,3 +17,3 @@ LibraryTrackItem: typeof import("./AudioLibrary/elements/TrackItem").default; | ||
LibraryPlayer: { | ||
AudioLibrary: typeof import("./AudioLibrary/component").default; | ||
AudioLibrary: typeof import("..").AudioLibrary; | ||
LibraryPlayer: typeof import("./AudioLibrary/elements/Player").default; | ||
@@ -25,3 +25,3 @@ LibraryTrackItem: typeof import("./AudioLibrary/elements/TrackItem").default; | ||
LibraryTrackItem: { | ||
AudioLibrary: typeof import("./AudioLibrary/component").default; | ||
AudioLibrary: typeof import("..").AudioLibrary; | ||
LibraryPlayer: typeof import("./AudioLibrary/elements/Player").default; | ||
@@ -28,0 +28,0 @@ LibraryTrackItem: typeof import("./AudioLibrary/elements/TrackItem").default; |
@@ -1,2 +0,2 @@ | ||
import { default as AudioLibrary, default as LibraryPlayer, default as LibraryTrackItem } from './lib/AudioLibrary'; | ||
import AudioLibrary from './lib/AudioLibrary/component'; | ||
import AudioPlayer from './lib/AudioPlayer'; | ||
@@ -6,3 +6,3 @@ import JustPlayer from './lib/JustPlayer'; | ||
import type { Track } from './types'; | ||
export { AudioLibrary, AudioPlayer, JustPlayer, LibraryPlayer, LibraryTrackItem, Waveform, }; | ||
export { AudioLibrary, AudioPlayer, JustPlayer, Waveform, }; | ||
export type { Track }; |
@@ -7,3 +7,3 @@ import AudioPlayer from './AudioPlayer'; | ||
AudioLibrary: { | ||
AudioLibrary: typeof import("./AudioLibrary/component").default; | ||
AudioLibrary: typeof import("..").AudioLibrary; | ||
LibraryPlayer: typeof import("./AudioLibrary/elements/Player").default; | ||
@@ -17,3 +17,3 @@ LibraryTrackItem: typeof import("./AudioLibrary/elements/TrackItem").default; | ||
LibraryPlayer: { | ||
AudioLibrary: typeof import("./AudioLibrary/component").default; | ||
AudioLibrary: typeof import("..").AudioLibrary; | ||
LibraryPlayer: typeof import("./AudioLibrary/elements/Player").default; | ||
@@ -25,3 +25,3 @@ LibraryTrackItem: typeof import("./AudioLibrary/elements/TrackItem").default; | ||
LibraryTrackItem: { | ||
AudioLibrary: typeof import("./AudioLibrary/component").default; | ||
AudioLibrary: typeof import("..").AudioLibrary; | ||
LibraryPlayer: typeof import("./AudioLibrary/elements/Player").default; | ||
@@ -28,0 +28,0 @@ LibraryTrackItem: typeof import("./AudioLibrary/elements/TrackItem").default; |
import * as react_jsx_runtime from 'react/jsx-runtime'; | ||
import React$1, { ComponentPropsWithRef, ReactElement, ComponentPropsWithoutRef, ComponentProps } from 'react'; | ||
import React$1, { ComponentPropsWithRef, ReactElement, ComponentProps } from 'react'; | ||
@@ -24,46 +24,8 @@ /** | ||
interface AudioLibraryProps$1 extends ComponentPropsWithRef<'div'> { | ||
interface AudioLibraryProps extends ComponentPropsWithRef<'div'> { | ||
tracks: Track[]; | ||
styles?: LibraryStyles; | ||
} | ||
declare function AudioLibrary({ tracks, styles, ...props }: AudioLibraryProps$1): react_jsx_runtime.JSX.Element; | ||
declare function AudioLibrary({ tracks, styles, ...props }: AudioLibraryProps): react_jsx_runtime.JSX.Element; | ||
interface AudioLibraryProps extends ComponentPropsWithRef<'div'> { | ||
currentTrack?: Track; | ||
trackIndex: number; | ||
trackCount: number; | ||
onNext: () => void; | ||
onPrevious: () => void; | ||
} | ||
declare function LibraryPlayer({ currentTrack, trackIndex, trackCount, onNext, onPrevious, ...props }: AudioLibraryProps): ReactElement<AudioLibraryProps, 'div'>; | ||
interface ProgressBarProps extends ComponentPropsWithoutRef<'input'> { | ||
duration: number; | ||
currentProgress: number; | ||
buffered: number; | ||
} | ||
declare function ProgressBar({ duration, currentProgress, buffered, ...props }: ProgressBarProps): ReactElement<ProgressBarProps, 'div'>; | ||
interface TrackItemProps extends ComponentPropsWithoutRef<'li'> { | ||
track: Track; | ||
selected: boolean; | ||
trackNumberLabel: string; | ||
color?: string; | ||
} | ||
declare function LibraryTrackItem({ track, selected, trackNumberLabel, color, ...props }: TrackItemProps): ReactElement<TrackItemProps, 'li'>; | ||
interface VolumeInputProps extends ComponentProps<'input'> { | ||
volume: number; | ||
volumeChange: (volume: number) => void; | ||
} | ||
declare function VolumeInput({ volume, volumeChange, ...props }: VolumeInputProps): ReactElement<VolumeInputProps, 'input'>; | ||
declare const _default: { | ||
AudioLibrary: typeof AudioLibrary; | ||
LibraryPlayer: typeof LibraryPlayer; | ||
LibraryTrackItem: typeof LibraryTrackItem; | ||
ProgressBar: typeof ProgressBar; | ||
VolumeInput: typeof VolumeInput; | ||
}; | ||
interface AudioPlayerProps extends ComponentPropsWithRef<'div'> { | ||
@@ -98,2 +60,2 @@ track: Track; | ||
export { _default as AudioLibrary, AudioPlayer, JustPlayer, _default as LibraryPlayer, _default as LibraryTrackItem, type Track, Waveform }; | ||
export { AudioLibrary, AudioPlayer, JustPlayer, type Track, Waveform }; |
{ | ||
"name": "@clxrity/react-audio", | ||
"version": "1.4.0", | ||
"version": "1.5.0", | ||
"description": "A simple audio player for React", | ||
@@ -12,2 +12,5 @@ "main": "dist/cjs/index.js", | ||
], | ||
"bin": { | ||
"setup-waveform-api": "./bin/setup-waveform-api.js" | ||
}, | ||
"repository": { | ||
@@ -39,3 +42,8 @@ "type": "git", | ||
"error", | ||
"next" | ||
"next", | ||
"api", | ||
"waveform", | ||
"waveform-api", | ||
"waveform-data", | ||
"waveform-image" | ||
], | ||
@@ -71,6 +79,9 @@ "author": { | ||
"prettier": "3.3.3", | ||
"react-icons": "^5.3.0", | ||
"rollup": "^4.21.1", | ||
"rollup-plugin-dts": "^6.1.1", | ||
"rollup-plugin-ignore": "^1.0.10", | ||
"rollup-plugin-peer-deps-external": "^2.2.4", | ||
"rollup-plugin-postcss": "^4.0.2", | ||
"shelljs": "^0.8.5", | ||
"styled-components": "^6.1.12", | ||
@@ -80,4 +91,3 @@ "ts-jest": "^29.2.5", | ||
"tslib": "^2.7.0", | ||
"typescript-plugin-css-modules": "^5.1.0", | ||
"react-icons": "^5.3.0" | ||
"typescript-plugin-css-modules": "^5.1.0" | ||
}, | ||
@@ -88,10 +98,15 @@ "peerDependencies": { | ||
}, | ||
"optionalDependencies": { | ||
"fluent-ffmpeg": "^2.1.3", | ||
"shelljs": "^0.8.5" | ||
}, | ||
"scripts": { | ||
"dev": "rollup -c --watch --configPlugin typescript", | ||
"build": "rollup -c --configPlugin typescript", | ||
"dev": "rollup -c --watch", | ||
"build": "rollup -c", | ||
"release": "pnpm build && changeset version && changeset publish", | ||
"test": "jest ./src/test --config=jest.config.ts", | ||
"lint": "prettier -c --write ./src/*", | ||
"start": "cd test && pnpm dev" | ||
"start:test": "cd test && pnpm dev", | ||
"start": "cd web && pnpm dev" | ||
} | ||
} |
@@ -1,3 +0,11 @@ | ||
# `@clxrity/react-audio` <img src="./icon.png" width="32px" height="32px" style="display:inline-block;" /> | ||
# @clxrity/react-audio <img src="./icon.png" width="32px" height="32px" style="display:inline-block;" /> | ||
[](https://www.npmjs.org/package/@clxrity/react-audio) | ||
[](https://www.npmjs.org/package/@clxrity/react-audio) | ||
[](https://github.com/clxrityy/react-audio/network/dependents?dependent_type=REPOSITORY) | ||
[](https://github.com/clxrityy/react-audio/network/dependents?dependent_type=PACKAGE) | ||
[](https://github.com/clxrityy/react-audio/actions/workflows/main.yml) | ||
[](https://github.com/clxrityy/react-audio) | ||
[](https://github.com/clxrityy/react-audio/blob/main/LICENSE) | ||
A react audio player component library. | ||
@@ -21,3 +29,3 @@ | ||
## Components | ||
## Components | ||
@@ -31,2 +39,65 @@ | Component | Controls | Customizable | Display Track Info | | ||
## Waveform Images API (Experimental) | ||
- Install with optional dependencies to use the waveform image generation API. | ||
- [`fluent-ffmpeg`](https://www.npmjs.com/package/fluent-ffmpeg) | ||
- [`shelljs`](https://www.npmjs.com/package/shelljs) | ||
```zsh | ||
npm i @clxrity/react-audio --save-optional | ||
``` | ||
> Works **ONLY** with [Nextjs App Router](https://nextjs.org/docs/app) | ||
You can generate an image of an audio file's waveform by using the `setup-waveform-api` script. | ||
```zsh | ||
npx setup-waveform-api | ||
``` | ||
- This will create a `app/api/generate-waveform/route.ts` file. | ||
```ts | ||
import fluentFfmpeg from 'fluent-ffmpeg'; | ||
import path from 'path'; | ||
import { NextRequest, NextResponse } from 'next/server'; | ||
export async function GET(req: NextRequest) { | ||
const url = new URL(req.url); | ||
const audioUrl = url.searchParams.get('url'); | ||
if (!audioUrl) { | ||
return NextResponse.json({ error: 'Missing URL query parameter' }, { status: 400 }); | ||
} | ||
const waveformPath = path.join(process.cwd(), 'public', 'waveform.png'); | ||
const promise = new Promise((resolve, reject) => { | ||
fluentFfmpeg(audioUrl) | ||
.audioFilters('aformat=channel_layouts=stereo') | ||
.outputOptions('-filter_complex', 'aformat=channel_layouts=stereo,showwavespic=s=600x120') | ||
.output(waveformPath) | ||
.on('end', () => { | ||
resolve(NextResponse.json({ message: `Waveform image at ${waveformPath}` }, { status: 200 })); | ||
}) | ||
.on('error', (err) => { | ||
reject(NextResponse.json({ error: err }, { status: 500 })); | ||
}) | ||
.run(); | ||
}); | ||
return promise; | ||
} | ||
``` | ||
- You can then use this route to generate waveform images. | ||
- **Note**: If you are using `fetch()` to handle the API request, make sure to pass the absolute URL of the audio file. | ||
```tsx | ||
/** | ||
* In this example, the audio file is within the public/ directory. | ||
* `/public/audio.wav` = `http://localhost:3000/audio.wav` | ||
* @see https://nextjs.org/docs/app/building-your-application/optimizing/static-assets | ||
*/ | ||
await fetch('http://localhost:3000/api/generate-waveform?url=http://localhost:3000/audio.wav') | ||
``` | ||
- This will generate a waveform image in the `public/` directory. (e.g. `public/waveform.png`) | ||
--- | ||
@@ -33,0 +104,0 @@ |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
366
24.07%3808452
-1.27%5
66.67%27
8%65
-63.89%4623
-20.58%