React Modern Audio Player
DEMO
https://codesandbox.io/s/basic-91y82y?file=/src/App.tsx
Flexible and Customizable UI
This can offer waveform by wavesurfer.js
This can offer various UI and you can also customize each component position
Full View
Position Change
Particular View
Installation
npm install --save react-modern-audio-player
Quick Start
import AudioPlayer from 'react-modern-audio-player';
const playList = [
{
name: 'name',
writer: 'writer',
img: 'image.jpg',
src: 'audio.mp3',
id: 1,
},
]
function Player (){
return (
<AudioPlayer playList={playList} />
)
}
Props
interface AudioPlayerProps {
playList: PlayList;
audioInitialState?: AudioInitialState;
audioRef?: React.MutableRefObject<HTMLAudioElement>;
activeUI?: ActiveUI;
customIcons?: CustomIcons;
coverImgsCss?: CoverImgsCss;
placement?: {
player?: PlayerPlacement;
playList?: PlayListPlacement;
interface?: InterfacePlacement;
volumeSlider?: VolumeSliderPlacement;
};
rootContainerProps?: RootContainerProps
}
PlayList
type PlayList = Array<AudioData>;
type AudioData = {
src: string;
id: number;
name?: string | ReactNode;
writer?: string | ReactNode;
img?: string;
description?: string | ReactNode;
customTrackInfo?: string | ReactNode;
};
AudioInitialState
type AudioInitialState = Omit<
React.AudioHTMLAttributes<HTMLAudioElement>,
"autoPlay"
> & {
isPlaying?: boolean;
repeatType?: RepeatType;
volume?: number;
currentTime?: number;
duration?: number;
curPlayId: number;
};
ActiveUI
type ActiveUI = {
all: boolean;
playButton: boolean;
playList: PlayListUI;
prevNnext: boolean;
volume: boolean;
volumeSlider: boolean;
repeatType: boolean;
trackTime: boolean;
trackInfo: boolean;
artwork: boolean;
progress: ProgressUI;
};
type ProgressUI = "waveform" | "bar" | false;
type PlayListUI = "sortable" | "unSortable" | false;
CustomIcons
type CustomIcons = {
play: ReactNode;
pause: ReactNode;
prev: ReactNode;
next: ReactNode;
repeatOne: ReactNode;
repeatAll: ReactNode;
repeatNone: ReactNode;
repeatShuffle: ReactNode;
volumeFull: ReactNode;
volumeHalf: ReactNode;
volumeMuted: ReactNode;
playList: ReactNode;
};
CoverImgsCss
interface CoverImgsCss {
artwork?: React.CSSProperties;
listThumbnail?: React.CSSProperties;
}
Placement
type PlayerPlacement =
| "bottom"
| "top"
| "bottom-left"
| "bottom-right"
| "top-left"
| "top-right";
type VolumeSliderPlacement = "bottom" | "top" | 'left' | 'right';
type PlayListPlacement = "bottom" | "top";
type InterfacePlacement = {
templateArea?: InterfaceGridTemplateArea;
customComponentsArea?: InterfaceGridCustomComponentsArea<TMaxLength>;
itemCustomArea?: InterfaceGridItemArea;
};
type InterfacePlacementKey =
| Exclude<keyof ActiveUI, "all" | "prevNnext" | "trackTime">
| "trackTimeCurrent"
| "trackTimeDuration";
type InterfacePlacementValue = "row1-1" | "row1-2" | "row1-3" | "row1-4" | ... more ... | "row9-9"
type InterfaceGridTemplateArea = Record<InterfacePlacementKey,InterfacePlacementValue>;
type InterfaceGridCustomComponentsArea = Record<componentId,InterfacePlacementValue>;
type InterfaceGridItemArea = Partial<Record<InterfacePlacementKey, string>>;
Default interface placement
const defaultInterfacePlacement = {
templateArea: {
artwork: "row1-1",
trackInfo: "row1-2",
trackTimeCurrent: "row1-3",
trackTimeDuration: "row1-4",
progress: "row1-5",
repeatType: "row1-6",
volume: "row1-7",
playButton: "row1-8",
playList: "row1-9",
},
};
RootContainerProps
it is same with spectrum provider props
https://react-spectrum.adobe.com/react-spectrum/Provider.html#themes
Override Style
Theme mode ( dark-mode )
it apply dark-mode depending on system-theme
you can customize color-theme by css-variable
of react-spectrum
theme-default
ID & Classnames
root ID
root ClassName
color variables
--rm-audio-player-interface-container:var(--spectrum-global-color-gray-100);
--rm-audio-player-volume-background: #ccc;
--rm-audio-player-volume-panel-background:#f2f2f2;
--rm-audio-player-volume-panel-border:#ccc;
--rm-audio-player-volume-thumb: #d3d3d3;
--rm-audio-player-volume-fill:rgba(0, 0, 0, 0.5);
--rm-audio-player-volume-track:#ababab;
--rm-audio-player-track-current-time:#0072F5;
--rm-audio-player-track-duration:#8c8c8c;
--rm-audio-player-progress-bar:#0072F5;
--rm-audio-player-progress-bar-background:#D1D1D1;
--rm-audio-player-waveform-cursor:var(--spectrum-global-color-gray-800);
--rm-audio-player-waveform-background:var(--rm-audio-player-progress-bar-background);
--rm-audio-player-waveform-bar:var(--rm-audio-player-progress-bar);
--rm-audio-player-sortable-list:var(--spectrum-global-color-gray-200);
--rm-audio-player-sortable-list-button-active:#0072F5;
--rm-audio-player-selected-list-item-background:var(--spectrum-global-color-gray-500);
// ...spectrum theme palette and so on... //
Custom Component
you can apply custom component to AudioPlayer
by CustomComponent
you can also set viewProps
to CustomComponent
(https://react-spectrum.adobe.com/react-spectrum/View.html#props)
const activeUI: ActiveUI = {
all: true,
};
const placement = {
interface: {
customComponentsArea: {
playerCustomComponent: "row1-10",
},
} as InterfacePlacement<11>,
};
const CustomComponent = ({
audioPlayerState,
}: {
audioPlayerState?: AudioPlayerStateContext;
}) => {
const audioEl = audioPlayerState?.elementRefs?.audioEl;
const handOverTime = () => {
if (audioEl) {
audioEl.currentTime += 30;
}
};
return (
<>
<button onClick={handOverTime}>+30</button>
</>
);
};
<AudioPlayer
playList={playList}
placement={placement}
activeUI={activeUI}
>
<AudioPlayer.CustomComponent id="playerCustomComponent">
<CustomComponent />
</AudioPlayer.CustomComponent>
</AudioPlayer>
Example
function App() {
return (
<div>
<AudioPlayer
playList={playList}
audioInitialState={{
muted: true,
volume: 0.2,
curPlayId: 1,
}}
placement={{
interface: {
templateArea: {
trackTimeDuration: "row1-5",
progress: "row1-4",
playButton: "row1-6",
repeatType: "row1-7",
volume: "row1-8",
},
},
player: "bottom-left",
}}
activeUI={{
all: true,
progress: "waveform",
}}
/>
</div>
);
}