Skip to content

alessiofrittoli/react-media-player

React Media Player 🎥

Handle media players with ease

Latest version Test coverage Socket Security score npm downloads Dependencies Dependencies status

minified minizipped Tree shakable

Fund this package

Table of Contents


Getting started

Run the following command to start using react-media-player in your projects:

npm i @alessiofrittoli/react-media-player

or using pnpm

pnpm i @alessiofrittoli/react-media-player

API Reference

Defining the queue

import { addItemsUUID } from "@alessiofrittoli/react-media-player/utils";
import type { Media, Queue } from "@alessiofrittoli/react-media-player";

interface PlaylistMedia extends Media {
  customProp: boolean;
}

interface Playlist extends Queue<PlaylistMedia> {
  name?: string;
}

const queue: Playlist = {
  name: "Playlist name",
  items: addItemsUUID<PlaylistMedia>([
    {
      src: "/song.mp3",
      type: "audio",
      title: "Song title",
      album: "Album name",
      artist: "Artist name",
      customProp: true,
      fade: { in: 1000, out: 1000 },
      artwork: [
        { src: "/artwork-96.png", sizes: 96, type: "image/png" },
        { src: "/artwork-128.png", sizes: 128, type: "image/png" },
        { src: "/artwork-192.png", sizes: 192, type: "image/png" },
        { src: "/artwork-256.png", sizes: 256, type: "image/png" },
        { src: "/artwork-384.png", sizes: 384, type: "image/png" },
        { src: "/artwork-512.png", sizes: 512, type: "image/png" },
      ],
      videoArtwork: [{ src: "/video-artwork.mp4", type: "video/mp4" }],
    },
    {
      src: "/song-2.mp3",
      type: "audio",
      title: "Song title 2",
      album: "Album name",
      artist: "Artist name",
      customProp: true,
      fade: { in: 1000, out: 1000 },
      artwork: [
        { src: "/artwork-96.png", sizes: 96, type: "image/png" },
        { src: "/artwork-128.png", sizes: 128, type: "image/png" },
        { src: "/artwork-192.png", sizes: 192, type: "image/png" },
        { src: "/artwork-256.png", sizes: 256, type: "image/png" },
        { src: "/artwork-384.png", sizes: 384, type: "image/png" },
        { src: "/artwork-512.png", sizes: 512, type: "image/png" },
      ],
      videoArtwork: [{ src: "/video-artwork.mp4", type: "video/mp4" }],
    },
  ]),
};

React Hooks

useAudioPlayer

Easily handle React audio players.

This hook acts as a wrapper around useMediaPlayer and it automatically creates Audio resource for you.

Please refer to useMediaPlayer doc section for API reference.

Usage
import { useAudioPlayer } from "@alessiofrittoli/react-media-player";
import type {
  MediaChangeHandler,
  PlaybackErrorHandler,
} from "@alessiofrittoli/react-media-player";

useAudioPlayer({
  queue,
  initialMedia: queue.items.at(2),
  normalizeVolume: true,
  playPauseFadeDuration: 500,
  preload: true,
  repeat: true,
  restartThreshold: 6000,
  volume: 1,
  onMediaChange: useCallback<MediaChangeHandler<T>>((media) => {}, []),
  onPlaybackError: useCallback<PlaybackErrorHandler>((error) => {}, []),
});

useAudioPlayerStore

Access useAudioPlayer API exposed by <AudioPlayerProvider /> Component.


useVideoPlayer

Easily handle React video players.

This hook acts as a wrapper around useMediaPlayer and it automatically creates a React.RefObject that needs to be attached to a <video /> JSX node.

Please refer to useMediaPlayer doc section for API reference.

Usage
"use client";

import { useVideoPlayer } from "@alessiofrittoli/react-media-player";
import type {
  MediaChangeHandler,
  PlaybackErrorHandler,
} from "@alessiofrittoli/react-media-player";

export const VideoPlayer: React.FC = () => {
  const { videoRef } = useVideoPlayer({
    queue,
    initialMedia: queue.items.at(2),
    normalizeVolume: true,
    playPauseFadeDuration: 500,
    preload: true,
    repeat: true,
    restartThreshold: 6000,
    volume: 1,
    onMediaChange: useCallback<MediaChangeHandler<T>>((media) => {}, []),
    onPlaybackError: useCallback<PlaybackErrorHandler>((error) => {}, []),
  });

  return <video ref={videoRef} />;
};

useVideoPlayerStore

Access useVideoPlayer API exposed by <VideoPlayerProvider /> Component.


useMediaPlayer

Easily handle React media players.

Type parameters
Parameter Type Description
T T extends Queue = Queue The type of the queue.

Parameters
Parameter Type Default Description
options UseMediaPlayerOptions<T> - An object defining media player options.
- extends UseVolumeOptions interface.
- extends UseMediaPlayerControllerOptions interface.
options.preload boolean true Indicates whether to preload next media when current media is about to end.

Returns

Type: UseMediaPlayer<T>

An object defining media player state and utilities.

Property Type Description
media HTMLMediaElement The given HTMLMediaElement.

Usage
import { useRef } from "react";
import { useMediaPlayer } from "@alessiofrittoli/react-media-player";
import type {
  MediaChangeHandler,
  PlaybackErrorHandler,
} from "@alessiofrittoli/react-media-player";

const media = useRef(typeof window !== "undefined" ? new Audio() : undefined);

useMediaPlayer({
  media: media.current,
  queue,
  initialMedia: queue.items.at(2),
  normalizeVolume: true,
  playPauseFadeDuration: 500,
  preload: true,
  repeat: true,
  restartThreshold: 6000,
  volume: 1,
  onMediaChange: useCallback<MediaChangeHandler<T>>((media) => {}, []),
  onPlaybackError: useCallback<PlaybackErrorHandler>((error) => {}, []),
});

useVolume

Manage audio volume control.

Please note that this hook doesn't update states to avoid useless overloads. This hook only handles media volume updates and relative normalizations.

UI state updates can be managed using useVolumeStore accessible inside <VolumeProvider /> Component children.

UseVolumeOptions
Parameters
Parameter Type Default Description
options UseVolumeOptions - Configuration options for the volume hook.
options.media HTMLMediaElement - The HTMLMediaElement.
options.volume number 1 The master volume [0-1].
options.normalizeVolume boolean true Normalize master volume.
options.fade number 200 Volume fade in milliseconds applied when toggling mute.

UseVolume interface
Returns

Type: UseVolume

An object providing volume control functionality including volume management, mute toggling, and volume normalization for media players.

Property Type Description
volumeRef React.RefObject<number> A React RefObject that stores the master volume value [0-1].
This value may stores the normalized value if normalizeVolume has been set to true.
initialVolume number The initial master volume [0-1].
normalizeVolume boolean Indicates whether volume normalization is applied.
setVolume ChangeHandler Set volume.
toggleMute ToggleMuteHandler Toggle mute.
Returns 0 if muting, otherwise the volume value before the mute was activated.

Usage
import { useVolume } from "@alessiofrittoli/react-media-player";

const { setVolume, toggleMute, volumeRef } = useVolume({
  media: HTMLAudioElement | HTMLVideoElement,
  volume: 0.8,
  normalizeVolume: true,
  fade: 300,
});

useVolumeStore

Access useVolume API exposed by <VolumeProvider /> Component.


useMediaPlayerController

React media player controller state.

Type parameters
Parameter Type Description
T T extends Queue = Queue The type of the queue.

UseMediaPlayerControllerOptions
Parameters
Parameter Type Default Description
options UseMediaPlayerControllerOptions<T> - An object defining media player controller options.
options.volumeRef React.RefObject<number> - A React RefObject that stores the master volume value [0-1].
- Compatible with volumeRef returned by useVolume hook.
options.repeat boolean true Indicates whether repeatition of the given queue is initially active.
options.media HTMLMediaElement - The HTMLMediaElement.
options.queue T - An object describing the queue. See Defining the queue for more info.
options.initialMedia InitialMedia<QueuedItemType<T>> - Defines the initial queue media to load.
options.restartThreshold number|false 5000 Indicates time in milliseconds after that the media restart to 0
rather than playing the previous one.
This only take effect when previous() method is called.
You can opt-out by this functionality by setting restartThreshold to false or 0.
options.playPauseFadeDuration number 200 Volume fade in milliseconds applied when soundtrack start playing/get paused.
options.onMediaChange MediaChangeHandler<T> - A callback executed when media player is playing and transitioning to another media.
options.onPlaybackError PlaybackErrorHandler - A callback executed when an error occurs when playing a media.

UseMediaPlayerController interface
Returns

Type: UseMediaPlayerController<T>

An object defining media player state and utilities.

  • extends and exposes useQueue APIs. it may be worthy to take a look at undocumented returned properties in the useQueue documentation.
Properties Type Description
state PlayerState Defines the current media player state.
It could be one of the following:
- playing | The media player is currently playing.
- paused | The media player is currently paused.
- stopped | The media player hasn't been started yet or has been stopped.
isPlaying boolean Defines whether the media player is currently playing.
playPause PlayPauseHandler<T> Play/pause/stop the media player or start another media.
- Returns: The queued item being played.
togglePlayPause UtilityPlayPauseHandler<T> Toggle play/pause.
- Returns: The queued item being played/paused.
stop UtilityPlayPauseHandler<T> Stop media player.
- Returns: The queued item that was playing before stopping the media player if any.
previous UtilityPlayPauseHandler<T> Play previous queued media.
- Returns: The queued item being played if any.
next UtilityPlayPauseHandler<T> Play next queued media.
- Returns: The queued item being played if any.

Usage
Toggle play/pause
"use client";

import { useRef } from "react";
import { useMediaPlayerController } from "@alessiofrittoli/react-media-player";

export const MyComponent: React.FC = () => {
  const media = useRef(typeof window !== "undefined" ? new Audio() : undefined);
  const { isPlaying, togglePlayPause } = useMediaPlayerController({
    queue,
    media,
  });

  return (
    <button onClick={togglePlayPause}>{!isPlaying ? "Play" : "Pause"}</button>
  );
};

Play previous media
"use client";

import { useRef } from "react";
import { useMediaPlayerController } from "@alessiofrittoli/react-media-player";

export const MyComponent: React.FC = () => {
  const media = useRef(typeof window !== "undefined" ? new Audio() : undefined);
  const { hasPrevious, previous } = useMediaPlayerController({
    queue,
    media,
    repeat: false,
  });

  return hasPrevious && <button onClick={previous}>Previous song</button>;
};

Play next media
"use client";

import { useRef } from "react";
import { useMediaPlayerController } from "@alessiofrittoli/react-media-player";

export const MyComponent: React.FC = () => {
  const media = useRef(typeof window !== "undefined" ? new Audio() : undefined);
  const { hasNext, next } = useMediaPlayerController({
    queue,
    media,
    repeat: false,
  });

  return hasNext && <button onClick={next}>Next song</button>;
};

Play a queued media matching given UUID
"use client";

import { useRef } from "react";
import { useMediaPlayerController } from "@alessiofrittoli/react-media-player";

export const MyComponent: React.FC = () => {
  const media = useRef(typeof window !== "undefined" ? new Audio() : undefined);
  const { playPause } = useMediaPlayerController({ queue, media });

  return (
    <button
      onClick={() => {
        playPause({ uuid: queue.items.at(1)?.uuid });
      }}
    >
      Play {queue.items.at(1)?.title}
    </button>
  );
};

Update queue and play a queued media matching given UUID
"use client";

import { useRef } from "react";
import { useMediaPlayerController } from "@alessiofrittoli/react-media-player";

export const MyComponent: React.FC = () => {
  const media = useRef(typeof window !== "undefined" ? new Audio() : undefined);
  const { playPause } = useMediaPlayerController({ queue, media });

  return (
    <button
      onClick={() => {
        playPause({ queue: queue2, uuid: queue2.items.at(1)?.uuid });
      }}
    >
      Play {queue2.items.at(1)?.title}
    </button>
  );
};

useMediaPlayerLoading

Handle media loading and error states.

Parameters
Parameter Type Description
options UseMediaPlayerLoadingOptions An object defining media player loading options.
options.media HTMLMediaElement The HTMLMediaElement.

UseMediaPlayerLoading interface
Returns

Type: UseMediaPlayerLoading

An object defining loading and error states.

Parameter Type Description
isLoading boolean Indicates whether the current media is loading.
error MediaError The MediaError interface represents an error which occurred while handling
media in an HTML media element based on HTMLMediaElement,
such as <audio> or <video>.
- see MDN Reference.

Usage
"use client";

import { useEffect, useState } from "react";
import { useMediaPlayerLoading } from "@alessiofrittoli/react-media-player";

export const MyComponent: React.FC = () => {
  const [media, setMedia] = useState<HTMLAudioElement>();

  const { isLoading, error } = useMediaPlayerLoading({ media });

  useEffect(() => {
    setMedia(new Audio("/song.mp3"));
  }, []);

  return (
    <>
      {isLoading && <span>Loading...</span>}
      {!isLoading && !error && <span>Loaded</span>}
      {error?.code === MediaError?.MEDIA_ERR_ABORTED && (
        <span>
          The fetching of the associated resource was aborted by the user's
          request.
        </span>
      )}
      {error?.code === MediaError?.MEDIA_ERR_NETWORK && (
        <span>
          Some kind of network error occurred which prevented the media from
          being successfully fetched, despite having previously been available.
        </span>
      )}
      {error?.code === MediaError?.MEDIA_ERR_DECODE && (
        <span>
          Despite having previously been determined to be usable, an error
          occurred while trying to decode the media resource, resulting in an
          error.
        </span>
      )}
      {error?.code === MediaError?.MEDIA_ERR_SRC_NOT_SUPPORTED && (
        <span>
          The associated resource or media provider object (such as a
          MediaStream) has been found to be unsuitable.
        </span>
      )}
    </>
  );
};

useMediaPreload

Handle media preload.

Type parameters
Parameter Type Description
T T extends Queue = Queue The type of the queue.

Parameters
Parameter Type Default Description
options UseVolumeOptions - Configuration options for the volume hook.
options.controller UseMediaPlayerController<T> - The media player controller.
options.cacheEntries number 3 Defines the maximum cache entries.
options.checkConnection boolean true Defines whether preload is enabled based on user connection quality.

UseMediaPreload interface
Returns

Type: UseMediaPreload

An object containing preload functions.

Property Type Description
preloadMedia PreloadMediaHandler Preload media.
preloadPreviousMedia PreloadPreviousOrNextHandler Preload previous media.
preloadNextMedia PreloadPreviousOrNextHandler Preload next media.

Usage
Basic usage
"use client";

import { useEffect, useState } from "react";
import { addItemsUUID } from "@alessiofrittoli/react-media-player/utils";
import {
  useMediaPlayerController,
  useMediaPreload,
  type Media,
  type Queue,
} from "@alessiofrittoli/react-media-player";

interface Playlist extends Queue<Media> {
  name?: string;
}

const queue: Playlist = {
  name: "Playlist name",
  items: addItemsUUID<Media>([
    {
      src: "/song-1.mp3",
      type: "audio",
    },
    {
      src: "/song-2.mp3",
      type: "audio",
    },
  ]),
};

export const MyComponent: React.FC = () => {
  const [media, setMedia] = useState<HTMLAudioElement>();

  const controller = useMediaPlayerController({ queue, media });
  const { preloadPreviousMedia, preloadNextMedia } = useMediaPreload({
    controller,
  });
  const { isPlaying, hasPrevious, hasNext, previous, next, togglePlayPause } =
    controller;

  useEffect(() => {
    setMedia(new Audio());
  }, []);

  return (
    <>
      <button
        onMouseEnter={() => {
          if (!hasPrevious) return;
          preloadPreviousMedia();
        }}
        onClick={() => {
          if (!hasPrevious) return;
          previous();
        }}
      >
        Previous
      </button>
      <button onClick={togglePlayPause}>{!isPlaying ? "Play" : "Pause"}</button>
      <button
        onMouseEnter={() => {
          if (!hasNext) return;
          preloadNextMedia();
        }}
        onClick={() => {
          if (!hasNext) return;
          next();
        }}
      >
        Next
      </button>
    </>
  );
};

Override checkConnection option

Returns 'metadata' for slow-2g or 2g connections

import { useMediaPreload } from "@alessiofrittoli/react-media-player";

const { preloadNextMedia } = useMediaPreload({
  controller,
  checkConnection = true, // preload strategy may use `metadata` if connection is `slow-2g` or `2g`
});

preloadNextMedia(false); // preload strategy will be `auto` ignoring previously passed `checkConnection` option

useMediaSession

Hook into MediaSession API for controlling media playback through system controls.

Manages MediaSession state and action handlers for play, pause, stop, seek, previous, and next operations. Synchronizes the native media element's playback state with the MediaSession API and handles user interactions through system media controls (e.g., keyboard shortcuts, media control buttons).

Parameters
Parameter Type Description
options UseMediaSessionOptions An object defining options and callbacks.
options.media HTMLMediaElement The HTMLMediaElement.
options.register boolean Indicates whether to register the action handlers.
⚠️ It is better to set register to true once and only after media.play() has been called.
options.onPlay MediaSessionActionHandler A custom callback executed once user requested to play the media through browser/device controls.
options.onPause MediaSessionActionHandler A custom callback executed once user requested to pause the media through browser/device controls.
options.onStop MediaSessionActionHandler A custom callback executed once user requested to stop the media through browser/device controls.
⚠️ Stop requests always depend on browser support.
options.onPrev MediaSessionActionHandler A custom callback executed once user requested to play the previous media through browser/device controls.
⚠️ Please note that if no onPrev function is given, the MediaSession functionality will not be enabled.
options.onNext MediaSessionActionHandler A custom callback executed once user requested to play the next media through browser/device controls.
⚠️ Please note that if no onNext function is given, the MediaSession functionality will not be enabled.
options.onSeekBackward MediaSessionActionHandler A custom callback executed once user requested to seek backward through browser/device controls.
options.onSeekForward MediaSessionActionHandler A custom callback executed once user requested to seek forward through browser/device controls.
options.onSeekTo MediaSessionActionHandler A custom callback executed once user requested to seek to a specific time through browser/device controls.

Usage
import {
  PlayerState,
  useMediaSession,
  useMediaPlayerController,
} from "@alessiofrittoli/react-media-player";

const { state, hasNext, hasPrevious, togglePlayPause, stop, previous, next } =
  useMediaPlayerController({ queue, media });

useMediaSession({
  media,
  register: state !== PlayerState.STOPPED,
  onPlay: togglePlayPause,
  onPause: togglePlayPause,
  onStop: stop,
  onPrev: hasPrevious ? previous : undefined,
  onNext: hasNext ? next : undefined,
});

useMediaSessionPiP

Hook into MediaSession Picture-in-Picture requests.

Useful resources

Parameters
Parameter Type Description
options UseMediaSessionPiPOptions An object defining options and callbacks.
options.register boolean Indicates whether to register the action handler.
⚠️ Enter PiP requests always depends on browser support.
options.onEnterPiP MediaSessionActionHandler A custom callback executed once the user requested to enter PiP.

Usage
"use client";

import { useCallback, useState, type ReactPortal } from "react";
import {
  PlayerState,
  useMediaSessionPiP,
  useMediaPlayerController,
} from "@alessiofrittoli/react-media-player";
import {
  openDocumentPictureInPicture,
  isDocumentPictureInPictureSupported,
} from "@alessiofrittoli/web-utils";
import { openArtworkPictureInPicture } from "@alessiofrittoli/media-utils/picture-in-picture";

export const MyComponent: React.FC = () => {
  const [portal, setPortal] = useState<ReactPortal>();
  const { state } = useMediaPlayerController({ queue, media });

  const open = useCallback(async () => {
    if (isDocumentPictureInPictureSupported()) {
      const { window } = await openDocumentPictureInPicture();

      const reactNode = (
        <PictureInPictureWindowProvider window={window}>
          <PictureInPictureComponent />
        </PictureInPictureWindowProvider>
      );

      const portal = createPortal(reactNode, window.document.body);

      return;
    }

    await openArtworkPictureInPicture( ... );
  }, []);

  useMediaSessionPiP({
    register: state !== PlayerState.STOPPED,
    onEnterPiP: open,
  });

  return portal;
};

React Components

<AudioPlayer />

Creates a React Audio Player and exposes useAudioPlayer API through React Context with <AudioPlayerProvider /> and <VolumeProvider />.

This allows you to easily mix-up client and server components passed to the Component children.

Component Props
Property Type Description
children ReactNode Any ReactNode which will get access to useAudioPlayer API and volume UI states through useAudioPlayerStore and useVolumeStore respectively.

Usage
Basic usage
import { AudioPlayer } from "@alessiofrittoli/react-media-player";

export const AppAudioPlayer: React.FC = () => (
  <AudioPlayer queue={queue}>
    <AudioPlayerControls />
  </AudioPlayer>
);

Accessing APIs in custom UI controls
import { useCallback } from "react";
import { useUpdateEffect } from "@alessiofrittoli/react-hooks";
import { useAudioPlayerStore } from "@alessiofrittoli/react-media-player";

export const AudioPlayerControls: React.FC = () => {
  const { isPlaying, togglePlayPause } = useAudioPlayerStore();

  return (
    <>
      <button onClick={togglePlayPause}>{!isPlaying ? "Play" : "Pause"}</button>
    </>
  );
};

<VideoPlayer />

Creates a React Video Player and exposes useVideoPlayer API through React Context with <VideoPlayerProvider /> and <VolumeProvider />.

This allows you to easily mix-up client and server components passed to the Component children.

Component Props
Property Type Description
children ReactNode Any ReactNode which will get access to useVideoPlayer API and volume UI states through useVideoPlayerStore and useVolumeStore respectively.
htmlProps React.ComponentProps<'video'> Props passed to the rendered HTMLVideoElement.

Usage
Basic usage
import { VideoPlayer } from "@alessiofrittoli/react-media-player";

export const AppVideoPlayer: React.FC = () => (
  <VideoPlayer queue={queue}>
    <VideoPlayerControls />
  </VideoPlayer>
);

Accessing APIs in custom UI controls
"use client";

import { useCallback } from "react";
import { useUpdateEffect } from "@alessiofrittoli/react-hooks";
import { useVideoPlayerStore } from "@alessiofrittoli/react-media-player";

export const VideoPlayerControls: React.FC = () => {
  const { isPlaying, togglePlayPause } = useVideoPlayerStore();

  return (
    <>
      <button onClick={togglePlayPause}>{!isPlaying ? "Play" : "Pause"}</button>
    </>
  );
};

<AudioPlayerProvider />

Exposes useAudioPlayer API.


<VideoPlayerProvider />

Exposes useVideoPlayer API.


<VolumeProvider />

Exposes UI state updates utilities.

This may come pretty handy when volume is controlled by multiple UI controllers and saves useVolume hook from dispatching state updates whenever a 0.1 volume value has been changed by the user.

This Component is already mounted when using the <AudioPlayer /> or <VideoPlayer /> Component, so no extra action is required by you.

Usage
"use client";

import { useCallback } from "react";
import { useUpdateEffect } from "@alessiofrittoli/react-hooks";
import {
  AudioPlayer,
  useVolumeStore,
  useAudioPlayerStore,
} from "@alessiofrittoli/react-media-player";

export const AppAudioPlayer: React.FC = () => (
  <AudioPlayer queue={queue}>
    <AudioPlayerVolumeControl />
  </AudioPlayer>
);

export const AudioPlayerVolumeControl: React.FC = () => {
  const { volume, setVolume: commitVolume } = useVolumeStore();

  const { initialVolume, setVolume, toggleMute } = useAudioPlayerStore();

  const isMute = volume <= 0;

  const updateVolume = useCallback(
    (volume: number) => {
      setVolume(volume / 100);
      commitVolume(volume / 100);
    },
    [setVolume, commitVolume],
  );

  const toggleMuteHandler = useCallback(() => {
    commitVolume(toggleMute());
  }, [toggleMute, commitVolume]);

  useUpdateEffect(() => {
    updateVolume(initialVolume * 100);
  }, [initialVolume, updateVolume]);

  const onChangeHandler = useCallback<React.ChangeEventHandler>(
    (event) => {
      const input = event.target as HTMLInputElement;
      const value = Number(input.value);

      if (isNaN(value)) return;

      const percent = (value * 100) / 100;

      updateVolume(percent);
    },
    [updateVolume],
  );

  return (
    <>
      <button onClick={toggleMuteHandler}>{!isMute ? "Mute" : "Unmute"}</button>
      <input
        type="range"
        value={volume * 100}
        max={100}
        step={1}
        onChange={onChangeHandler}
        aria-valuetext={`${volume * 100}%`}
      />
    </>
  );
};

Utils

Queue Utils

This library exposes queue utility functions exported by @alessiofrittoli/react-hooks and defines others documented below.

Usage
import {
  addItemUUID,
  addItemsUUID,
  maybeAddItemUUID,
  maybeAddItemsUUID,
  findIndexByUUID,
} from "@alessiofrittoli/react-media-player/utils";

...

inheritDataFromQueue

Inherit metadata fields from a queue into a queued item payload.

Please note that the given item fields takes precedence over queue fields.

Inherited properties from the given queue
Property Description
album The album name of the media.
artist The artist of the media.
artwork The media artwork.
videoArtwork The media video artwork.

Type parameters
Parameter Type Description
T T extends Queue = Queue The type of the queue.

Parameters
Parameter Type Default Description
item QueuedItemType<T> - The queued item.
queue T| NewQueue<T> - The queue from which the fields are inherited.

Returns

Type: QueuedItemType<T>

The queued item with intherited fileds from the given queue.


Usage
import { inheritDataFromQueue } from "@alessiofrittoli/react-media-player/utils";

const item = {
  uuid: "random-uuid",
  title: "Track 1",
} as unknown as QueuedItemType<Queue>;

const queue = {
  album: "Album A",
  artist: "Artist A",
  artwork: "artwork-a.jpg",
  videoArtwork: "video-a.jpg",
} as unknown as Queue;

inheritDataFromQueue(item, queue);

/*
Returns:
  {
    album         : 'Album A',
    artist        : 'Artist A',
    artwork       : 'artwork-a.jpg',
    videoArtwork  : 'video-a.jpg',
    uuid          : 'random-uuid',
    title         : 'Track 1',
  }
*/

Development

Install dependencies

npm install

or using pnpm

pnpm i

Build the source code

Run the following command to test and build code for distribution.

pnpm build

Run warnings and errors checks.

pnpm lint

Run all the defined test suites by running the following:

# Run tests and watch file changes.
pnpm test:watch

# Run tests in a CI environment.
pnpm test:ci

Run tests with coverage.

An HTTP server is then started to serve coverage files from ./coverage folder.

⚠️ You may see a blank page the first time you run this command. Simply refresh the browser to see the updates.

pnpm test:coverage:serve

Contributing

Contributions are truly welcome!

Please refer to the Contributing Doc for more information on how to start contributing to this project.

Help keep this project up to date with GitHub Sponsor.

GitHub Sponsor


Security

If you believe you have found a security vulnerability, we encourage you to responsibly disclose this and NOT open a public issue. We will investigate all legitimate reports. Email security@alessiofrittoli.it to disclose any security vulnerabilities.

Made with ☕

avatar
Alessio Frittoli
https://alessiofrittoli.it | info@alessiofrittoli.it