
Research
/Security News
Critical Vulnerability in NestJS Devtools: Localhost RCE via Sandbox Escape
A flawed sandbox in @nestjs/devtools-integration lets attackers run code on your machine via CSRF, leading to full Remote Code Execution (RCE).
react-udux-player
Advanced tools
Here's the complete README.md file in one view for easy copying:
# React Udux Player
A customizable music player for React applications with HLS streaming support, track preloading, style isolation, and a rich set of features.
## Features
- 🎵 HLS streaming support
- 🔄 Track preloading for smooth transitions
- 🎨 Fully customizable theming
- 🧩 Pluggable UI components
- 📱 Responsive design
- 🔊 Volume control with mute toggle
- 🔀 Shuffle and repeat modes
- ⏱️ Progress bar with seeking
- 🎧 Event callbacks for player state changes
- 🔒 Style isolation to prevent conflicts with your app's styles
## Installation
```bash
npm install react-udux-player
# or
yarn add react-udux-player
# or
pnpm add react-udux-player
import { UduxPlayerProvider, UduxPlayer, useUduxPlayer } from 'react-Udux-player';
// Define your tracks
const tracks = [
{
id: "1",
title: "Song Title",
artist: "Artist Name",
duration: 180,
streamUrl: "https://example.com/song.m3u8",
coverUrl: "/images/cover.jpg"
},
// More tracks...
];
// In your component
function App() {
return (
<UduxPlayerProvider>
{/* Your app content */}
<MusicLibrary />
<UduxPlayer />
</UduxPlayerProvider>
);
}
// Use the player in any component
function MusicLibrary() {
const { setQueue, togglePlay, currentTrack } = useUduxPlayer();
return (
<div>
<h1>My Music</h1>
<button onClick={() => {
setQueue(tracks);
togglePlay();
}}>
Play All
</button>
{/* Display current track */}
{currentTrack && (
<div>
Now playing: {currentTrack.title} by {currentTrack.artist}
</div>
)}
</div>
);
}
The player uses a scoped CSS approach to prevent style conflicts with your application. All player styles are:
udux-player-*
)This ensures that the player's styles won't affect your application's styles and vice versa.
You can customize the player's appearance by providing a theme object:
import { UduxPlayerProvider, UduxPlayer } from 'react-Udux-player';
const myTheme = {
colors: {
primary: '#1DB954', // Main accent color
background: '#121212', // Player background
text: '#FFFFFF', // Primary text color
textSecondary: '#B3B3B3', // Secondary text color
progressBar: '#535353', // Progress bar background
progressBarFilled: '#1DB954', // Filled part of progress bar
controlBackground: '#282828', // Background for controls
playerBorder: '#282828', // Border color
},
sizes: {
playerHeight: '90px', // Height of the player
progressBarHeight: '4px', // Height of progress bar
controlButtonSize: '32px', // Size of control buttons
volumeSliderWidth: '100px', // Width of volume slider
coverArtSize: '56px', // Size of cover art
},
borderRadius: '4px', // Border radius for elements
fontFamily: 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif', // Font family
};
function App() {
return (
<UduxPlayerProvider theme={myTheme}>
<UduxPlayer />
</UduxPlayerProvider>
);
}
You can replace any part of the player UI with your own components:
import { UduxPlayerProvider, UduxPlayer } from 'react-Udux-player';
import MyCustomPlayButton from './MyCustomPlayButton';
import MyCustomVolumeControl from './MyCustomVolumeControl';
function App() {
return (
<UduxPlayerProvider
components={{
PlayButton: MyCustomPlayButton,
VolumeControl: MyCustomVolumeControl,
}}
>
<UduxPlayer />
</UduxPlayerProvider>
);
}
Example of a custom play button component:
// MyCustomPlayButton.jsx
import React from 'react';
const MyCustomPlayButton = ({ isPlaying, onClick, isBuffering }) => {
return (
<button
onClick={onClick}
style={{
backgroundColor: '#1DB954',
color: 'white',
border: 'none',
borderRadius: '50%',
width: '40px',
height: '40px',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
cursor: 'pointer',
}}
>
{isBuffering ? (
<span>⋯</span>
) : isPlaying ? (
<span>❚❚</span>
) : (
<span>▶</span>
)}
</button>
);
};
export default MyCustomPlayButton;
The player comes with a set of custom icons and styling out of the box:
The player automatically extracts dominant colors from the album artwork and applies them as a gradient background:
Listen to player events:
import { UduxPlayerProvider, UduxPlayer } from 'react-Udux-player';
function App() {
return (
<UduxPlayerProvider
onTrackChange={(track) => console.log('Now playing:', track?.title)}
onPlaybackStateChange={(isPlaying) => console.log('Playback:', isPlaying ? 'playing' : 'paused')}
onError={(error) => console.error('Player error:', error)}
onTimeUpdate={(time) => console.log('Current time:', time)}
onQueueChange={(queue) => console.log('Queue updated:', queue.length, 'tracks')}
onVolumeChange={(volume, isMuted) => console.log('Volume:', volume, isMuted ? '(muted)' : '')}
onShuffleChange={(shuffleEnabled) => console.log('Shuffle:', shuffleEnabled ? 'on' : 'off')}
onRepeatChange={(repeatMode) => console.log('Repeat mode:', repeatMode)}
onSeek={(time) => console.log('Seeked to:', time)}
onEnded={() => console.log('Track ended')}
onLike={(track, isLiked) => console.log(`Track ${track?.title} ${isLiked ? 'liked' : 'unliked'}`)}
onAddToPlaylist={(track) => console.log(`Add ${track?.title} to playlist`)}
onFullscreenChange={(isFullscreen) => console.log(`Fullscreen: ${isFullscreen}`)}
onViewChange={(isNowPlayingView) => console.log(`Now playing view: ${isNowPlayingView}`)}
onMinimize={() => console.log('Player minimized')}
>
<UduxPlayer />
</UduxPlayerProvider>
);
}
You can create your own player UI while still using the player context:
import React from 'react';
import { UduxPlayerProvider, useUduxPlayer } from 'react-Udux-player';
// Custom player component
function CustomPlayer() {
const {
currentTrack,
isPlaying,
togglePlay,
nextTrack,
previousTrack,
currentTime,
duration,
seek,
} = useUduxPlayer();
// Format time as MM:SS
const formatTime = (time) => {
if (!time) return '0:00';
const minutes = Math.floor(time / 60);
const seconds = Math.floor(time % 60);
return `${minutes}:${seconds.toString().padStart(2, '0')}`;
};
if (!currentTrack) {
return <div>No track selected</div>;
}
return (
<div className="my-custom-player">
<div className="track-info">
<img
src={currentTrack.coverUrl || '/default-cover.jpg'}
alt={currentTrack.title}
className="cover-art"
/>
<div>
<h3>{currentTrack.title}</h3>
<p>{currentTrack.artist}</p>
</div>
</div>
<div className="controls">
<button onClick={previousTrack}>Previous</button>
<button onClick={togglePlay}>
{isPlaying ? 'Pause' : 'Play'}
</button>
<button onClick={nextTrack}>Next</button>
</div>
<div className="progress">
<span>{formatTime(currentTime)}</span>
<input
type="range"
min={0}
max={duration || 100}
value={currentTime || 0}
onChange={(e) => seek(Number(e.target.value))}
/>
<span>{formatTime(duration)}</span>
</div>
</div>
);
}
// Main app
function App() {
return (
<UduxPlayerProvider>
<div>
{/* Your app content */}
<CustomPlayer />
</div>
</UduxPlayerProvider>
);
}
Prop | Type | Description |
---|---|---|
children | ReactNode | Child components |
theme | Theme | Theme customization object |
components | CustomComponents | Custom UI components |
initialVolume | number | Initial volume level (0-100) |
initialShuffle | boolean | Initial shuffle state |
initialRepeat | "off" | "all" |
onTrackChange | (track: Track | null) => void |
onPlaybackStateChange | (isPlaying: boolean) => void | Called when playback starts or stops |
onError | (error: Error) => void | Called when an error occurs |
onTimeUpdate | (time: number) => void | Called when playback time updates |
onQueueChange | (queue: Track[]) => void | Called when the queue changes |
onVolumeChange | (volume: number, isMuted: boolean) => void | Called when volume changes |
onShuffleChange | (shuffleEnabled: boolean) => void | Called when shuffle mode changes |
onRepeatChange | (repeatMode: RepeatMode) => void | Called when repeat mode changes |
onSeek | (time: number) => void | Called when seeking to a position |
onEnded | () => void | Called when a track ends |
onLike | (track: Track | null, isLiked: boolean) => void |
onAddToPlaylist | (track: Track | null) => void |
onFullscreenChange | (isFullscreen: boolean) => void | Called when you trigger fullscreen mode |
onViewChange | (isNowPlayingView: boolean) => void | Called when you toggle now playing |
onMinimize | () => void | Called when you toggle minimize player |
The useUduxPlayer
hook provides access to the player state and controls:
Property/Method | Type | Description |
---|---|---|
currentTrack | Track | null |
queue | Track[] | Current queue of tracks |
isPlaying | boolean | Whether playback is active |
volume | number | Current volume (0-100) |
isMuted | boolean | Whether audio is muted |
currentTime | number | Current playback position in seconds |
duration | number | Duration of current track in seconds |
shuffle | boolean | Whether shuffle mode is active |
repeat | "off" | "all" |
isBuffering | boolean | Whether the player is buffering |
togglePlay | () => void | Toggle play/pause |
nextTrack | () => void | Skip to next track |
previousTrack | () => void | Go to previous track |
seek | (time: number) => void | Seek to position in seconds |
setVolume | (volume: number) => void | Set volume (0-100) |
toggleMute | () => void | Toggle mute |
toggleShuffle | () => void | Toggle shuffle mode |
toggleRepeat | () => void | Cycle repeat modes |
setQueue | (tracks: Track[]) => void | Set the queue of tracks |
theme | Theme | Current theme object |
tracksToPreload | number[] | Indices of tracks being preloaded |
interface Track {
id: string;
title: string;
artist: string;
album?: string;
duration: number;
coverUrl?: string;
streamUrl: string;
}
interface Theme {
colors: {
primary: string;
background: string;
text: string;
textSecondary: string;
progressBar: string;
progressBarFilled: string;
controlBackground?: string;
playerBorder?: string;
};
sizes: {
playerHeight: string;
progressBarHeight: string;
controlButtonSize: string;
volumeSliderWidth?: string;
coverArtSize?: string;
};
borderRadius: string;
fontFamily?: string;
}
interface CustomComponents {
PlayButton?: React.ComponentType<{ isPlaying: boolean; onClick: () => void; isBuffering: boolean }>;
NextButton?: React.ComponentType<{ onClick: () => void; disabled: boolean }>;
PreviousButton?: React.ComponentType<{ onClick: () => void; disabled: boolean }>;
ShuffleButton?: React.ComponentType<{ active: boolean; onClick: () => void; disabled: boolean }>;
RepeatButton?: React.ComponentType<{ mode: RepeatMode; onClick: () => void; disabled: boolean }>;
VolumeControl?: React.ComponentType<{
volume: number;
isMuted: boolean;
onVolumeChange: (volume: number) => void;
onMuteToggle: () => void;
}>;
ProgressBar?: React.ComponentType<{
currentTime: number;
duration: number;
onSeek: (time: number) => void;
isBuffering: boolean;
}>;
TrackInfo?: React.ComponentType<{ track: Track | null }>;
PlayerContainer?: React.ComponentType<{ children: React.ReactNode }>;
}
If the player controls are not responding:
setQueue
useUduxPlayer
hook within a component that's a child of UduxPlayerProvider
If you're experiencing style conflicts:
udux-player-*
) to prevent conflictsuseUduxPlayer
hookIf audio doesn't play:
https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8
The player works in all modern browsers that support HTML5 audio and video. For HLS streaming support, it uses the react-hls-player
package which provides cross-browser compatibility.
FAQs
A customizable music player for React applications
The npm package react-udux-player receives a total of 185 weekly downloads. As such, react-udux-player popularity was classified as not popular.
We found that react-udux-player demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
/Security News
A flawed sandbox in @nestjs/devtools-integration lets attackers run code on your machine via CSRF, leading to full Remote Code Execution (RCE).
Product
Customize license detection with Socket’s new license overlays: gain control, reduce noise, and handle edge cases with precision.
Product
Socket now supports Rust and Cargo, offering package search for all users and experimental SBOM generation for enterprise projects.