Audio and video media player with waveform visualization, region management, and playback controls.
npx @hiyve/cli login
npm install @hiyve/react-media-player
import { MediaPlayer } from '@hiyve/react-media-player';
function App() {
return (
<MediaPlayer
src="https://example.com/audio.mp3"
onError={(err) => console.error(err)}
/>
);
}
import { MediaPlayer } from '@hiyve/react-media-player';
<MediaPlayer
src={audioUrl}
mediaType="audio"
enableRegions
regions={savedRegions}
onRegionChange={(region) => saveRegion(region)}
onRegionDelete={(id) => deleteRegion(id)}
colors={{
waveColor: '#6366f1',
progressColor: '#ec4899',
}}
/>
import { useMediaPlayer } from '@hiyve/react-media-player';
function CustomPlayer({ src }: { src: string }) {
const player = useMediaPlayer({ src });
return (
<div>
<button onClick={player.togglePlayPause}>
{player.isPlaying ? 'Pause' : 'Play'}
</button>
<span>{player.playbackTime}s / {player.playbackLength}s</span>
</div>
);
}
| Prop | Type | Default | Description |
|---|---|---|---|
src |
string |
required | Media URL to play |
mediaType |
'audio' | 'video' |
auto-detected | Force media type instead of auto-detecting from URL |
fileSize |
number |
— | File size in bytes; files >200 MB skip waveform |
enableWaveform |
boolean |
true |
Show waveform visualization |
enableVolumeControl |
boolean |
true |
Show volume/gain control button |
enableRateControl |
boolean |
true |
Show playback rate control button (auto-disabled on Safari) |
enableRegions |
boolean |
false |
Enable region creation, editing, and loop playback |
enableAudioPassthrough |
boolean |
false |
Enable audio passthrough to a Hiyve meeting |
enableKeyboardShortcuts |
boolean |
true |
Enable keyboard shortcuts (space for play/pause) |
enableMute |
boolean |
true |
Show mute/unmute button |
compact |
boolean |
false |
Compact layout mode |
regions |
RegionData[] |
— | Initial named regions to load |
onRegionChange |
(region: RegionData) => void |
— | Called when a named region is created or updated |
onRegionDelete |
(regionId: string) => void |
— | Called when a named region is deleted |
externalAudioSource |
ExternalAudioSource |
— | External audio source for gain visualization in the mixer |
labels |
Partial<MediaPlayerLabels> |
— | Override default labels/tooltips |
colors |
Partial<MediaPlayerColors> |
— | Override default colors |
onPlay |
() => void |
— | Called when playback starts |
onPause |
() => void |
— | Called when playback pauses |
onTimeUpdate |
(time: number) => void |
— | Called on playback time change |
onEnded |
() => void |
— | Called when playback ends |
onError |
(error: Error) => void |
— | Called on errors (fetch, waveform, playback) |
onAudioStreamReady |
(stream: MediaStream) => void |
— | Called when the audio output stream is ready |
These are the building blocks used by MediaPlayer. They are exported for advanced use cases where you need a custom layout.
| Component | Description |
|---|---|
PlaybackControls |
Toolbar with play/pause, rewind, mute, loop, region, passthrough, volume, and rate buttons |
TimeSlider |
Horizontal slider showing current time and duration |
Waveform |
Container element for the WaveSurfer waveform visualization |
VolumeSlider |
Vertical slider with optional click-point snapping |
GainMixer |
Volume and external audio gain controls with visualizer |
GainMixerPopup |
Popup wrapper for GainMixer |
RateMixer |
Playback rate slider with discrete rate steps (0.5x–2.0x) |
RateMixerPopup |
Popup wrapper for RateMixer |
GainAnalyser |
Connects to a gain/analyser node and feeds data to GainVisualizer |
GainVisualizer |
Canvas-based audio level meter with peak indicators |
NamedRegionDialog |
Dialog for naming, saving, or deleting a named region |
useMediaPlayer(options)Core playback hook that manages the media element, Web Audio API, and playback state.
| Option | Type | Required | Description |
|---|---|---|---|
src |
string |
yes | Media URL |
mediaType |
'audio' | 'video' |
no | Force media type |
fileSize |
number |
no | File size in bytes |
onError |
(error: Error) => void |
no | Error callback |
onAudioStreamReady |
(stream: MediaStream) => void |
no | Stream ready callback |
onPlay |
() => void |
no | Play callback |
onPause |
() => void |
no | Pause callback |
onTimeUpdate |
(time: number) => void |
no | Time update callback |
onEnded |
() => void |
no | Ended callback |
Returns (UseMediaPlayerResult):
| Property | Type | Description |
|---|---|---|
mediaRef |
RefObject<HTMLMediaElement> |
Ref to the media element |
audioContextRef |
RefObject<AudioContext> |
Ref to the audio context |
gainNodeRef |
RefObject<GainNode> |
Ref to the gain node |
destinationStreamRef |
RefObject<MediaStreamAudioDestinationNode> |
Ref to the destination stream |
playerId |
string |
Unique player instance ID |
isPlaying |
boolean |
Whether media is playing |
loaded |
boolean |
Whether media is loaded and ready |
playbackTime |
number |
Current playback time in seconds |
playbackLength |
number |
Total duration in seconds |
isMuted |
boolean |
Whether audio is muted |
playbackRate |
number |
Current playback rate |
detectedMediaType |
'audio' | 'video' | null |
Detected media type |
skipWaveform |
boolean |
Whether waveform was skipped (large file) |
disableWebAudio |
boolean |
Whether Web Audio API is disabled (iOS) |
play |
() => void |
Start playback |
pause |
() => void |
Pause playback |
togglePlayPause |
() => void |
Toggle play/pause |
rewind |
() => void |
Rewind to start |
seek |
(time: number) => void |
Seek to time |
setRate |
(rate: number) => void |
Set playback rate |
toggleMute |
() => void |
Toggle mute |
useWaveform(options)Creates a WaveSurfer waveform visualization for a media element.
| Option | Type | Required | Description |
|---|---|---|---|
containerId |
string |
yes | DOM element ID for the waveform container |
mediaElement |
HTMLMediaElement | null |
yes | The media element to visualize |
enabled |
boolean |
yes | Whether to create the waveform |
colors |
MediaPlayerColors |
yes | Color configuration |
onReady |
(duration: number) => void |
no | Called when waveform is ready |
onTimeUpdate |
(time: number) => void |
no | Called on time update |
onError |
(error: Error) => void |
no | Error callback |
Returns (UseWaveformResult):
| Property | Type | Description |
|---|---|---|
wavesurfer |
WaveSurfer | null |
WaveSurfer instance |
regionsPlugin |
RegionsPlugin | null |
Regions plugin instance |
isReady |
boolean |
Whether waveform is ready |
useRegions(options)Manages region editing and loop playback on the waveform. Toggle edit mode to create, rename, move, resize, or delete regions. Outside edit mode, click a region to loop-play it.
| Option | Type | Required | Description |
|---|---|---|---|
regionsPlugin |
RegionsPlugin | null |
yes | Regions plugin from useWaveform |
initialRegions |
RegionData[] |
no | Initial regions to load |
onRegionChange |
(region: RegionData) => void |
no | Called when a region is created or updated |
onRegionDelete |
(regionId: string) => void |
no | Called when a region is deleted |
colors |
MediaPlayerColors |
yes | Color configuration |
setIsPlaying |
(playing: boolean) => void |
yes | Callback to update playing state when a region starts playback |
Returns (UseRegionsResult):
| Property | Type | Description |
|---|---|---|
isEditMode |
boolean |
Whether region edit mode is active |
openRegionDialog |
boolean |
Whether the naming dialog is open |
activeRegionName |
string |
Name of the region being edited |
handleEditToggle |
() => void |
Toggle region edit mode |
handleSaveNamedRegion |
(name: string) => void |
Save region name |
handleDeleteNamedRegion |
() => void |
Delete the active region |
closeRegionDialog |
() => void |
Close the naming dialog |
useAudioPassthrough(options)Manages audio passthrough state for sharing playback audio in a meeting.
When toggled, dispatches a hiyve-media-passthrough CustomEvent on window with { stream, active } in the detail. Listen for this event to wire the stream into your audio pipeline.
| Option | Type | Required | Description |
|---|---|---|---|
destinationStream |
MediaStreamAudioDestinationNode | null |
yes | Destination stream from useMediaPlayer |
enabled |
boolean |
yes | Whether passthrough is enabled |
onError |
(error: Error) => void |
no | Error callback |
Returns (UseAudioPassthroughResult):
| Property | Type | Description |
|---|---|---|
isActive |
boolean |
Whether passthrough is currently active |
toggle |
() => Promise<void> |
Toggle passthrough on/off |
| Type | Description |
|---|---|
MediaPlayerProps |
Props for the MediaPlayer component |
RegionData |
Region data (id, start, end, content, optional channelIdx) |
ExternalAudioSource |
External audio source with optional analyser and gainNode |
MediaPlayerLabels |
All label/tooltip strings (24 properties) |
MediaPlayerColors |
All color values (16 properties) |
PlaybackControlsProps |
Props for PlaybackControls |
TimeSliderProps |
Props for TimeSlider |
WaveformProps |
Props for Waveform |
VolumeSliderProps |
Props for VolumeSlider |
VolumeSliderColors |
Color configuration for VolumeSlider |
GainMixerProps |
Props for GainMixer |
GainMixerPopupProps |
Props for GainMixerPopup |
RateMixerProps |
Props for RateMixer |
RateMixerPopupProps |
Props for RateMixerPopup |
GainAnalyserProps |
Props for GainAnalyser |
GainVisualizerProps |
Props for GainVisualizer |
NamedRegionDialogProps |
Props for NamedRegionDialog |
UseMediaPlayerOptions |
Options for useMediaPlayer |
UseMediaPlayerResult |
Return type of useMediaPlayer |
UseWaveformOptions |
Options for useWaveform |
UseWaveformResult |
Return type of useWaveform |
UseRegionsOptions |
Options for useRegions |
UseRegionsResult |
Return type of useRegions |
UseAudioPassthroughOptions |
Options for useAudioPassthrough |
UseAudioPassthroughResult |
Return type of useAudioPassthrough |
WaveSurferRegion |
WaveSurfer region instance type |
Override default labels and colors by passing partial objects — unspecified keys use defaults.
import { MediaPlayer, defaultMediaPlayerLabels } from '@hiyve/react-media-player';
<MediaPlayer
src={url}
labels={{
play: 'Reproducir',
pause: 'Pausar',
rewind: 'Rebobinar',
mute: 'Silenciar',
unmute: 'Activar sonido',
}}
/>
import { MediaPlayer, defaultMediaPlayerColors } from '@hiyve/react-media-player';
<MediaPlayer
src={url}
colors={{
waveColor: '#6366f1',
progressColor: '#ec4899',
cursorColor: '#f59e0b',
controlBackground: '#1e1e2e',
controlIcon: '#cdd6f4',
}}
/>
Defaults and merge functions:
| Default | Merge Function |
|---|---|
defaultMediaPlayerLabels |
mergeMediaPlayerLabels |
defaultMediaPlayerColors |
mergeMediaPlayerColors |
| Constant | Value | Description |
|---|---|---|
LARGE_FILE_THRESHOLD |
209715200 (200 MB) |
Files above this size skip waveform |
FETCH_TIMEOUT_MS |
60000 |
Media fetch timeout in milliseconds |
DEFAULT_VOLUME_RANGE |
[0, 0.05, ..., 1.0] |
Volume slider range values (5% increments) |
DEFAULT_VOLUME_CLICK_POINTS |
[0, 5, ..., 100] |
Volume slider click points |
MIC_GAIN_RANGE |
[0, 0.25, ..., 5.0] |
Mic gain range (0–500% in 25% increments) |
RATE_RANGE_VALUES |
[0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0] |
Playback rate steps |
RATE_CLICK_POINTS |
[0, 17, 33, 50, 67, 83, 100] |
Rate slider click points |
GAIN_FACTOR |
30 |
Gain visualizer scale factor |
PEAK_DECAY_RATE |
0.01 |
Peak indicator decay rate |
PEAK_THRESHOLD |
10 |
Minimum peak value for indicator |
IS_SAFARI |
boolean |
Safari browser detection |
IS_IOS |
boolean |
iOS device detection (includes iPadOS 13+) |
@mui/material (^5.0.0 || ^6.0.0) and @mui/icons-material@emotion/react (^11.0.0) and @emotion/styled (^11.0.0)react (^18.0.0)@hiyve/react (^2.0.0) — optional; only needed for audio passthrough in a Hiyve meetingMIT
@hiyve/react-media-player - Audio and video media player with waveform visualization
Remarks
This package provides a full-featured media player component with WaveSurfer waveform visualization, region management, playback controls, and optional audio passthrough for Hiyve meetings.
Features:
Example
Basic usage:
Example
With all features:
Example
Using hooks for custom UI: