Component

HLS Video Player

A headless HLS video player component with native HLS detection and error handling.

import { HLSVideoPlayer } from '@/components/hls-video-player'

function HLSVideoPlayerDemo() {
  return (
    <div className="px-4 py-6">
      <HLSVideoPlayer
        src="https://stream.mux.com/VZtzUzGRv02OhRnZCxcNg49OilvolTqdnFLEqBsTwaxU.m3u8"
        width={1920}
        height={1080}
        muted
        autoPlay
        playsInline
        className="mx-auto w-full max-w-2xl overflow-hidden rounded-lg"
      />
    </div>
  )
}

export default HLSVideoPlayerDemo

Installation

pnpm dlx shadcn@latest add https://r.joyco.studio/hls-video-player.json

Usage

import { HLSVideoPlayer } from '@/components/hls-video-player'
 
<HLSVideoPlayer
  ref={ref}
  src="https://example.com/stream.m3u8"
  width={1920}
  height={1080}
  onReady={onReady}
  onHlsError={onHlsError}
/>

Props

PropTypeDescription
srcstringThe HLS stream URL (.m3u8) or regular video source
widthnumberVideo width (used for aspect ratio)
heightnumberVideo height (used for aspect ratio)
debugbooleanEnable debug logging
onHlsError(error: HLSVideoError) => voidHLS error callback
onVideoErrorReactEventHandler<HTMLVideoElement>Native video error callback
onReady() => voidCalled when video is ready to play
onHlsLoaded() => voidCalled when HLS.js library is loaded
startTimenumberStart playback at specific time (seconds)
maxResolutionnumberCap max resolution (e.g., 720, 1080)
minResolutionnumberSet minimum resolution

With Media Player Controls

Combine with the Media Player component for a full-featured video player UI:

Media playerAudio player with custom controls for playback, volume, seeking, and more. Use space bar to play/pause, Shift + arrow keys (←/→) to seek, and arrow keys (↑/↓) to adjust volume.
0:000:00
'use client'

import {
  MediaPlayer,
  MediaPlayerControls,
  MediaPlayerControlsOverlay,
  MediaPlayerFullscreen,
  MediaPlayerLoading,
  MediaPlayerPiP,
  MediaPlayerPlay,
  MediaPlayerPlaybackSpeed,
  MediaPlayerSeek,
  MediaPlayerSeekBackward,
  MediaPlayerSeekForward,
  MediaPlayerTime,
  MediaPlayerVideo,
  MediaPlayerVolume,
} from '@/components/ui/media-player'
import { HLSVideoPlayer } from '@/components/hls-video-player'

function HLSVideoPlayerWithControlsDemo() {
  return (
    <div className="mx-auto w-full max-w-3xl p-10">
      <MediaPlayer autoHide>
        <MediaPlayerVideo asChild>
          <HLSVideoPlayer
            src="https://stream.mux.com/VZtzUzGRv02OhRnZCxcNg49OilvolTqdnFLEqBsTwaxU.m3u8"
            width={1920}
            height={1080}
          />
        </MediaPlayerVideo>
        <MediaPlayerLoading />
        <MediaPlayerControls className="flex-col items-start gap-2.5">
          <MediaPlayerControlsOverlay />
          <MediaPlayerSeek />
          <div className="flex w-full items-center gap-2">
            <div className="flex flex-1 items-center gap-2">
              <MediaPlayerPlay />
              <MediaPlayerSeekBackward />
              <MediaPlayerSeekForward />
              <MediaPlayerVolume expandable />
              <MediaPlayerTime />
            </div>
            <div className="flex items-center gap-2">
              <MediaPlayerPlaybackSpeed />
              <MediaPlayerPiP />
              <MediaPlayerFullscreen />
            </div>
          </div>
        </MediaPlayerControls>
      </MediaPlayer>
    </div>
  )
}

export default HLSVideoPlayerWithControlsDemo

Error Handling

import { type HLSVideoError } from '@/components/hls-video-player'
 
function App() {
  const handleError = (error: HLSVideoError) => {
    // error.type: 'network' | 'media' | 'fatal' | 'other'
    // error.message: Human readable message
    // error.fatal: Whether playback can continue
    // error.details: Additional error details
 
    if (error.fatal) {
      // Show error UI, offer retry
    }
  }
 
  return (
    <HLSVideoPlayer
      src="..."
      width={1920}
      height={1080}
      onHlsError={handleError}
    />
  )
}
import { type HLSVideoError } from '@/components/hls-video-player'
 
function App() {
  const handleError = (error: HLSVideoError) => {
    // error.type: 'network' | 'media' | 'fatal' | 'other'
    // error.message: Human readable message
    // error.fatal: Whether playback can continue
    // error.details: Additional error details
 
    if (error.fatal) {
      // Show error UI, offer retry
    }
  }
 
  return (
    <HLSVideoPlayer
      src="..."
      width={1920}
      height={1080}
      onHlsError={handleError}
    />
  )
}
Maintainers
Downloads
0Total
0 downloads today