npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@tiwz/react-video-player

v2.0.7

Published

A React component for playing video

Downloads

2,254

Readme

@tiwz/react-video-player

A modern, fully-featured, and mobile-friendly React video player component with custom controls, double-tap seek, keyboard shortcuts, fullscreen, Picture-in-Picture (PiP), subtitles, and smooth UX — built for both desktop and mobile.


✨ Features

  • 🎮 Custom video controls (no native controls UI)
  • 📱 Mobile optimized (double-tap to seek ±10s, touch to toggle controls)
  • ⌨️ Keyboard shortcuts support (desktop)
  • 🖥 Fullscreen & Picture-in-Picture (PiP)
  • 🔊 Volume control + mute toggle
  • 🎯 Multi-quality source switching (resumes from same timestamp)
  • ⚡ Playback speed control (0.25x – 4x)
  • 📡 HLS streaming support (built-in, no extra install needed)
  • 🕒 Seek bar with buffered progress indicator
  • 💬 Subtitle / caption support (VTT format)
  • 🚀 Smooth UX with throttled interactions
  • 💡 Auto-hide controls on inactivity
  • 🧭 Landscape lock on fullscreen (mobile)
  • 🔄 Loading indicator on buffering
  • ❌ Error state UI when video fails to load
  • 🧩 Fully typed with TypeScript

📦 Installation

npm install @tiwz/react-video-player

or

bun add @tiwz/react-video-player

or

yarn add @tiwz/react-video-player

🚀 Quick Start

import { VideoPlayer } from '@tiwz/react-video-player'
import '@tiwz/react-video-player/style.css'

export default function App() {
  return (
    <VideoPlayer
      title="Demo Video"
      source="https://www.w3schools.com/html/mov_bbb.mp4"
    />
  )
}

🧩 Props

VideoPlayerProps

| Prop | Type | Required | Description | |------|------|----------|-------------| | source | string \| VideoSourceQuality[] | ✅ | Single URL or array of quality sources | | title | string | ❌ | Video title shown in top bar | | poster | string | ❌ | Thumbnail image shown before playback | | hls | boolean \| Partial<HlsConfig> | ❌ | Enable HLS streaming | | track | VideoTrack | ❌ | Subtitle / caption track (VTT format) |

VideoSourceQuality

type VideoSourceQuality = {
  src: string      // Video URL
  quality: number  // e.g. 1080, 720, 480. Use 0 for Auto
}

VideoTrack

type VideoTrack = {
  src: string    // URL to .vtt subtitle file
  lang: string   // BCP 47 language tag, e.g. 'en', 'th'
}

Example with multiple qualities:

<VideoPlayer
  title="My Video"
  poster="/thumbnail.jpg"
  source={[
    { src: '/video-1080p.mp4', quality: 1080 },
    { src: '/video-720p.mp4',  quality: 720  },
    { src: '/video-480p.mp4',  quality: 480  },
    { src: '/video-auto.mp4',  quality: 0    }, // Auto
  ]}
/>

Quality sources are automatically sorted highest to lowest. Switching quality resumes from the same timestamp.


💬 Subtitles

Subtitle support uses the WebVTT format. Pass a track prop with the URL to your .vtt file and the language code.

<VideoPlayer
  title="My Video"
  source="/video.mp4"
  track={{ src: '/subtitles-en.vtt', lang: 'en' }}
/>

Users can toggle subtitles on/off from the Settings panel in the player. Subtitles are displayed as an overlay above the controls, and will float up when the control bar is visible.

Note: The .vtt file must be served from the same origin or with CORS headers to be loaded correctly by the browser.


📡 HLS Streaming

HLS support is built-in — no extra packages needed.

// Basic HLS
<VideoPlayer
  title="Live Stream"
  source="/stream.m3u8"
  hls
/>

// HLS with custom config
<VideoPlayer
  title="Live Stream"
  source="/stream.m3u8"
  hls={{ maxBufferLength: 30 }}
/>

Safari uses native HLS automatically — hls.js is bypassed on Safari.


🎥 Player Controls

Desktop

| Action | Control | |--------|---------| | Play / Pause | Click center or Space | | Seek backward 10s | Arrow | | Seek forward 10s | Arrow | | Toggle fullscreen | F | | Toggle Picture-in-Picture | P |

Mobile

| Gesture | Action | |---------|--------| | Single tap | Show / hide controls | | Double tap left | Seek backward 10s | | Double tap right | Seek forward 10s | | Consecutive taps | Stacked seek (±20s, ±30s, ...) | | Drag seek bar | Seek with live preview |


⚙️ Settings Panel

The gear icon opens the settings panel with the following options:

| Setting | Description | |---------|-------------| | Video quality | Switch between available quality levels (shown only when multiple sources are provided) | | Playback speed | Adjust speed from 0.25x to 4x | | Subtitle | Toggle subtitles on/off (shown only when a track is provided) |


🖥 Fullscreen

Supports all modern browsers including:

  • Chrome / Edge / Firefox
  • Safari (desktop)
  • Mobile Safari / Chrome Android

Includes automatic orientation lock to landscape for landscape videos on mobile.


📺 Picture-in-Picture (PiP)

Works on:

  • Chrome / Edge
  • Safari (desktop & iPadOS)

Automatically resumes playback when entering PiP if the video is paused.


⚡ Performance

  • Throttled mouse movement (200ms)
  • Optimized re-rendering via useReducer + useRef
  • Stale closure prevention with refs for hot-path callbacks
  • Smart seek stacking with auto-reset
  • Minimal event listeners

🧪 Browser Support

| Browser | Fullscreen | PiP | HLS | Subtitles | Orientation Lock | |---------|-----------|-----|-----|-----------|-----------------| | Chrome | ✅ | ✅ | ✅ | ✅ | ✅ | | Edge | ✅ | ✅ | ✅ | ✅ | ✅ | | Firefox | ✅ | ✅ | ✅ | ✅ | ⚠️ Partial | | Safari (desktop) | ✅ | ✅ | ✅ (native) | ✅ | — | | Mobile Safari | ✅ | ✅ (iPadOS) | ✅ (native) | ✅ | ✅ | | Chrome Android | ✅ | ✅ | ✅ | ✅ | ✅ |


📄 License

MIT © 2026 tiwz