āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā š shadcn/directory/sadmann7/diceui/components/media-player ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā
<Steps> <Step> **DropdownMenu** ```diff function DropdownMenuContent({ className, + container, sideOffset = 4, ...props -}: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) { +}: React.ComponentProps<typeof DropdownMenuPrimitive.Content> & { + container?: DropdownMenuPrimitive.DropdownMenuPortalProps["container"]; +}) { return ( - <DropdownMenuPrimitive.Portal> + <DropdownMenuPrimitive.Portal container={container}> ``` </Step> <Step> **Tooltip** ```diff function TooltipContent({ className, sideOffset = 0, + container, children, ...props -}: React.ComponentProps<typeof TooltipPrimitive.Content>) { +}: React.ComponentProps<typeof TooltipPrimitive.Content> & { + container?: TooltipPrimitive.TooltipPortalProps["container"]; +}) { return ( - <TooltipPrimitive.Portal> + <TooltipPrimitive.Portal container={container}> ``` </Step> </Steps>Prerequisites: Before installing the media player component, you'll need to update your existing shadcn/ui components to support portal containers.
```package-install
npx shadcn@latest add "https://diceui.com/r/media-player"
```
</Step>
</Steps>
```package-install
@radix-ui/react-slot @radix-ui/react-slider @radix-ui/react-tooltip lucide-react
```
</Step>
<Step>
Copy the refs composition utilities into your `lib/compose-refs.ts` file.
<ComponentSource name="compose-refs" />
</Step>
<Step>
Copy and paste the following code into your project.
<ComponentSource name="media-player" />
</Step>
</Steps>
Import the parts, and compose them together.
import * as MediaPlayer from "@/components/ui/media-player";
<MediaPlayer.Root>
<MediaPlayer.Video>
<source src="..." type="video/mp4" />
</MediaPlayer.Video>
<MediaPlayer.Loading />
<MediaPlayer.Error />
<MediaPlayer.VolumeIndicator />
<MediaPlayer.Controls>
<MediaPlayer.ControlsOverlay />
<MediaPlayer.Play />
<MediaPlayer.SeekBackward />
<MediaPlayer.SeekForward />
<MediaPlayer.Volume />
<MediaPlayer.Seek />
<MediaPlayer.Time />
<MediaPlayer.PlaybackSpeed />
<MediaPlayer.Loop />
<MediaPlayer.Captions />
<MediaPlayer.PiP />
<MediaPlayer.Fullscreen />
<MediaPlayer.Download />
</MediaPlayer.Controls>
</MediaPlayer.Root>
Use the Audio component instead of Video for audio playback.
Media player with a settings menu with playback speed, caption option, and resolution selector.
<ComponentTabs name="media-player-settings-demo" className="block " />Media player with HLS (HTTP Live Streaming) support for adaptive bitrate streaming.
This example demonstrates using the Mux Video React package as the video element to enable HLS playback.
<ComponentTabs name="media-player-hls-demo" className="block" />Media player with custom error handling and retry functionality.
<ComponentTabs name="media-player-error-demo" className="block" />A media player example that includes a playlist, similar to music streaming applications.
<ComponentTabs name="media-player-playlist-demo" fullPreview />The main container component for the media player.
<AutoTypeTable path="./types/docs/media-player.ts" name="RootProps" />
<DataAttributesTable attributes={[ { title: "[data-controls-visible]", value: "Present when the controls are visible.", }, { title: "[data-disabled]", value: "Present when the media player is disabled.", }, { title: "[data-state]", value: ["fullscreen", "windowed"], }, ]} />
The video element, integrated with the player state.
<AutoTypeTable path="./types/docs/media-player.ts" name="VideoProps" />
The audio element, integrated with the player state.
<AutoTypeTable path="./types/docs/media-player.ts" name="AudioProps" />
A container for the media player controls.
<AutoTypeTable path="./types/docs/media-player.ts" name="ControlsProps" />
<DataAttributesTable attributes={[ { title: "[data-disabled]", value: "Present when the controls are disabled.", }, { title: "[data-state]", value: ["fullscreen", "windowed"], }, { title: "[data-visible]", value: "Present when the controls are visible.", }, ]} />
Displays as a subtle backdrop that improves readability for media controls.
<AutoTypeTable path="./types/docs/media-player.ts" name="ControlsOverlayProps" />
<DataAttributesTable attributes={[ { title: "[data-state]", value: ["fullscreen", "windowed"], }, { title: "[data-visible]", value: "Present when the controls are visible.", }, ]} />
A loading indicator that appears when media is loading, similar to YouTube/Netflix style.
<AutoTypeTable path="./types/docs/media-player.ts" name="LoadingProps" />
An error component that displays when media playback encounters an error, with retry and reload options.
<AutoTypeTable path="./types/docs/media-player.ts" name="ErrorProps" />
<DataAttributesTable attributes={[ { title: "[data-state]", value: ["fullscreen", "windowed"], }, ]} />
A volume indicator that appears when the volume is changed with keyboard interactions.
<AutoTypeTable path="./types/docs/media-player.ts" name="VolumeIndicatorProps" />
A button to play or pause the media.
<AutoTypeTable path="./types/docs/media-player.ts" name="PlayProps" />
<DataAttributesTable attributes={[ { title: "[data-disabled]", value: "Present when the button is disabled.", }, { title: "[data-state]", value: ["on", "off"], }, ]} />
A button to seek backward in the media.
<AutoTypeTable path="./types/docs/media-player.ts" name="SeekBackwardProps" />
<DataAttributesTable attributes={[ { title: "[data-disabled]", value: "Present when the button is disabled.", }, ]} />
A button to seek forward in the media.
<AutoTypeTable path="./types/docs/media-player.ts" name="SeekForwardProps" />
<DataAttributesTable attributes={[ { title: "[data-disabled]", value: "Present when the button is disabled.", }, ]} />
A slider component to seek through the media playback.
<AutoTypeTable path="./types/docs/media-player.ts" name="SeekProps" />
<DataAttributesTable attributes={[ { title: "[data-disabled]", value: "Present when the slider is disabled.", }, { title: "[data-hovering]", value: "Present when the seek slider is being actively hovered.", }, { title: "[data-slider='']", value: "Present on the seek slider.", }, { title: "[data-slot='media-player-seek-container']", value: "The container for the seek slider.", }, { title: "[data-slot='media-player-seek']", value: "The root for the seek slider.", }, { title: "[data-slot='media-player-seek-buffered']", value: "The buffered progress indicator within the track.", }, { title: "[data-slot='media-player-seek-hover-range']", value: "The hover preview range indicator.", }, { title: "[data-slot='media-player-seek-chapter-separator']", value: "Chapter separators displayed on the track.", }, { title: "[data-slot='media-player-seek-thumbnail']", value: "The thumbnail preview container in the tooltip.", }, { title: "[data-slot='media-player-seek-chapter-title']", value: "The chapter title in the tooltip.", }, { title: "[data-slot='media-player-seek-time']", value: "The time display in the tooltip.", }, ]} />
<MediaPlayer.Seek
className={
cn(
"[&_[data-slot='media-player-seek-buffered']]:bg-primary/60",
"[&_[data-slot='media-player-seek-hover-range']]:bg-primary/70",
"[&_[data-slot='media-player-seek-chapter-separator']]:w-1 [&_[data-slot='media-player-seek-chapter-separator']]:bg-muted",
"[&_[data-slot='media-player-seek-thumbnail']]:border-2 [&_[data-slot='media-player-seek-thumbnail']]:border-ring"
)
}
/>
A slider component to control the media volume.
<AutoTypeTable path="./types/docs/media-player.ts" name="VolumeProps" />
<DataAttributesTable attributes={[ { title: "[data-disabled]", value: "Present when the volume control is disabled.", }, { title: "[data-slider='']", value: "Present on the volume slider.", }, { title: "[data-slot='media-player-volume-container']", value: "The container for the volume slider.", }, { title: "[data-slot='media-player-volume-trigger']", value: "The trigger for the volume slider.", }, { title: "[data-slot='media-player-volume']", value: "The root for the volume slider.", }, { title: "[data-state]", value: ["on", "off"], }, ]} />
Displays the current time, duration, or remaining time of the media.
<AutoTypeTable path="./types/docs/media-player.ts" name="TimeProps" />
A select dropdown to control the media playback speed.
<AutoTypeTable path="./types/docs/media-player.ts" name="PlaybackSpeedProps" />
<DataAttributesTable attributes={[ { title: "[data-disabled]", value: "Present when the select is disabled.", }, ]} />
A button to toggle loop mode.
<AutoTypeTable path="./types/docs/media-player.ts" name="LoopProps" />
<DataAttributesTable
attributes={[
{
title: "[data-disabled]",
value: "Present when the button is disabled.",
},
{
title: "[data-state]",
value: ["on", "off"],
},
]}
/>
A button to toggle fullscreen mode.
<AutoTypeTable path="./types/docs/media-player.ts" name="FullscreenProps" />
<DataAttributesTable attributes={[ { title: "[data-disabled]", value: "Present when the button is disabled.", }, { title: "[data-state]", value: ["on", "off"], }, ]} />
A button to toggle picture in picture mode (video only).
<AutoTypeTable path="./types/docs/media-player.ts" name="PiPProps" />
<DataAttributesTable attributes={[ { title: "[data-disabled]", value: "Present when the button is disabled.", }, { title: "[data-state]", value: ["on", "off"], }, ]} />
A button to toggle captions or subtitles (video only).
<AutoTypeTable path="./types/docs/media-player.ts" name="CaptionsProps" />
<DataAttributesTable attributes={[ { title: "[data-disabled]", value: "Present when the button is disabled.", }, { title: "[data-state]", value: ["on", "off"], }, ]} />
A button to download the media file.
<AutoTypeTable path="./types/docs/media-player.ts" name="DownloadProps" />
<DataAttributesTable attributes={[ { title: "[data-disabled]", value: "Present when the button is disabled.", }, ]} />
A dropdown menu with playback speed selector, caption selector, and resolution selector.
<AutoTypeTable path="./types/docs/media-player.ts" name="SettingsProps" />
Features:
<MediaPlayer.Settings
speeds={[0.5, 0.75, 1, 1.25, 1.5, 2]}
/>
<DataAttributesTable attributes={[ { title: "[data-disabled]", value: "Present when the button is disabled.", }, ]} />
<KeyboardShortcutsTable shortcuts={[ { keys: ["Space", "K"], description: "Toggles play/pause.", }, { keys: ["ArrowRight"], description: "Seeks forward 5 seconds (video only).", }, { keys: ["ArrowLeft"], description: "Seeks backward 5 seconds (video only).", }, { keys: ["J"], description: "Seeks backward 10 seconds (video only).", }, { keys: ["L"], description: "Seeks forward 10 seconds (video only).", }, { keys: ["Shift + ArrowRight"], description: "Seeks forward 5 seconds (audio only).", }, { keys: ["Shift + ArrowLeft"], description: "Seeks backward 5 seconds (audio only).", }, { keys: ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"], description: "Seeks to 0%-90% of duration.", }, { keys: ["Home"], description: "Seeks to beginning.", }, { keys: ["End"], description: "Seeks to end.", }, { keys: ["ArrowUp"], description: "Increases volume (video only).", }, { keys: ["ArrowDown"], description: "Decreases volume (video only).", }, { keys: ["M"], description: "Toggles mute.", }, { keys: ["R"], description: "Toggles repeat mode.", }, { keys: ["F"], description: "Toggles fullscreen.", }, { keys: ["Escape"], description: "Exits fullscreen when in fullscreen mode.", }, { keys: [">"], description: "Increases playback speed.", }, { keys: ["<"], description: "Decreases playback speed.", }, { keys: ["C"], description: "Toggles captions (video only, if available).", }, { keys: ["P"], description: "Toggles Picture-in-Picture.", }, { keys: ["D"], description: "Downloads the media file (if download button is present).", }, ]} />
ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā