Media Provider
Creates the Zustand store, event emitter, and feature setup for a media player instance.
Installation
npx shadcn add @limeplay/media-providerSetup
Use createMediaKit to compose the features you need into a single runtime:
"use client"
import { createMediaKit } from "@/components/limeplay/media-provider"
import { mediaFeature } from "@/hooks/limeplay/use-media"
import { playerFeature } from "@/hooks/limeplay/use-player"
import { playbackFeature } from "@/hooks/limeplay/use-playback"
import { volumeFeature } from "@/hooks/limeplay/use-volume"
import { timelineFeature } from "@/hooks/limeplay/use-timeline"
export const media = createMediaKit({
features: [
mediaFeature(),
playerFeature(),
playbackFeature(),
volumeFeature(),
timelineFeature(),
] as const,
})
export const { MediaProvider, useMediaStore, useMediaApi, useMediaEvents } =
mediaWrap your player with MediaProvider:
import { MediaProvider } from "@/lib/media"
import { Media } from "@/components/limeplay/media"
export function MediaPlayer() {
return (
<MediaProvider>
<Media as="video" />
{/* Controls go here */}
</MediaProvider>
)
}Accessing State
Selectors (reactive)
import { useMediaStore } from "@/lib/media"
// or per-feature hooks:
import { useVolumeStore } from "@/hooks/limeplay/use-volume"
// Option A: unified store (namespaced)
function VolumeDisplayNamespaced() {
const level = useMediaStore((s) => s.volume.level)
return <span>{Math.round(level * 100)}%</span>
}
// Option B: feature-scoped hook (flat)
function VolumeDisplayScoped() {
const level = useVolumeStore((s) => s.level)
return <span>{Math.round(level * 100)}%</span>
}Store API (imperative)
For effects and callbacks where you don't need reactivity:
import { useMediaApi } from "@/lib/media"
function SomeEffect() {
const api = useMediaApi()
React.useEffect(() => {
// Read without subscribing
const { level } = api.getState().volume
// Mutate with Immer draft
api.setState(({ volume }) => {
volume.level = 0.5
})
}, [api])
}Events
Subscribe to typed events from any feature:
import { useMediaEvents } from "@/lib/media"
function Logger() {
const events = useMediaEvents()
React.useEffect(() => {
return events.on("volumechange", ({ volume }) => {
console.log("Volume:", volume)
})
}, [events])
return null
}See Events for the full event reference.
Multi-Instance
Each MediaProvider creates an isolated store. Multiple players on the same page are fully independent:
<MediaProvider>
<PlayerOne />
</MediaProvider>
<MediaProvider>
<PlayerTwo />
</MediaProvider>API Reference
createMediaKit
createMediaKit({ features }) => {
MediaProvider, // React component
useMediaStore, // Reactive selector hook
useMediaApi, // Imperative store API hook
useMediaEvents, // Event emitter hook
features, // Features array reference
}MediaProvider
Wraps player components. Creates the Zustand store, event emitter, and auto-mounts each feature's Setup component.
<MediaProvider>{children}</MediaProvider>