react-modern-audio-player
TypeScript icon, indicating that this package has built-in type declarations

1.4.0-rc.2 • Public • Published

rm-audio-player

React Modern Audio Player

License Version Download BundleSize

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?: InitialStates;
  audioRef?: React.MutableRefObject<HTMLAudioElement>;
  activeUI?: ActiveUI;
  customIcons?: CustomIcons;
  coverImgsCss?: CoverImgsCss;
  placement?: {
    player?: PlayerPlacement;
    playList?: PlayListPlacement;
    interface?: InterfacePlacement;
    volumeSlider?: VolumeSliderPlacement;
  };
  rootContainerProps?: RootContainerProps
}
Prop Type Default
playList PlayList [ ]
audioInitialState InitialStates isPlaying: false repeatType: "ALL" volume: 1
activeUI ActiveUI playButton : true
customIcons CustomIcons undefined
coverImgsCss CoverImgsCss undefined
placement Placement playListPlacement : "bottom" interfacePlacement :DefaultInterfacePlacement
rootContainerProps RootContainerProps theme: spectrum-theme-default
width: 100%
position: 'static'
UNSAFE_className: rm-audio-player-provider

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;
};

InitialStates

type InitialStates = 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"
/** if you apply custom components, values must be "row1-1" ~ any more */

type InterfaceGridTemplateArea = Record<InterfacePlacementKey,InterfacePlacementValue>;

type InterfaceGridCustomComponentsArea = Record<componentId,InterfacePlacementValue>;

type InterfaceGridItemArea = Partial<Record<InterfacePlacementKey, string>>;
	/** example
	* progress : 2-4
	* repeatBtn : row1-4 / 2 / row1-4 / 10
	*
	* check MDN - grid area
	* https://developer.mozilla.org/ko/docs/Web/CSS/grid-area
	*/

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

  • rm-audio-player

root ClassName

  • rm-audio-player-provider

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>,
  /**
   * you should set generic value of `InterfacePlacement` as interfaces max length for auto-complete aria type such as "row-1-10"
   * generic value must plus 1 than interfaces length because of 0 index
  */
};

/** you can get audioPlayerState by props */
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>
  );
}

Package Sidebar

Install

npm i react-modern-audio-player

Weekly Downloads

464

Version

1.4.0-rc.2

License

MIT

Unpacked Size

462 kB

Total Files

85

Last publish

Collaborators

  • slash9494