@source/player (3.0.1)

Published 2026-02-13 02:15:35 +00:00 by hibna

Installation

@source:registry=
npm install @source/player@3.0.1
"@source/player": "3.0.1"

About this package

🎬 Modern Video Player

npm version Bundle Size TypeScript License: MIT

A compact, feature-rich React video player with zero runtime dependencies.

A feature-rich, modern video player library built with React, TypeScript, and Vite. Designed for reusability across multiple projects.

🏆 Why Choose This Player?

Feature @source/player video.js react-player plyr
Bundle Size (gzipped) ~18KB JS + ~3.5KB CSS ~500KB ~50KB ⚠️ ~30KB ⚠️
Runtime Dependencies 0 Many Few ⚠️ Few ⚠️
React (Web) Yes Wrapper ⚠️ Yes Wrapper ⚠️
TypeScript Native Yes Types ⚠️ Partial ⚠️ Types ⚠️
HLS Support Yes Yes Yes No
Quality Switching Yes Yes Limited ⚠️ No
Touch Gestures 15+ Limited ⚠️ No Limited ⚠️
Keyboard Shortcuts 15+ ~8 ⚠️ Basic ⚠️ ~10 ⚠️
i18n Support Yes Yes No Yes

Key Advantages

  • 📦 Compact bundle - Core player ships around ~18KB gzipped JS (+ ~3.5KB CSS)
  • Blazing fast - Zero runtime dependencies means faster load times
  • 🎯 React-first - Built specifically for React, not a wrapper
  • 🔧 Full TypeScript - Complete type safety out of the box
  • 🎨 Easy customization - CSS variables for theming
  • 📱 Mobile-ready - Comprehensive touch gesture support
  • 🌍 Internationalized - Built-in i18n with English and Turkish
  • Accessible - ARIA labels and keyboard navigation

Features

🎮 Core Playback

  • ▶️ Play/Pause controls
  • ⏭️ Seek/scrub with progress bar
  • 🔊 Volume control with slider
  • 🎚️ Playback speed control
  • 🔄 Loop support
  • 🖼️ Custom poster/thumbnail

🎨 Modern UI

  • Clean, minimalist design with red theme
  • Smooth animations and transitions
  • Auto-hiding controls
  • Responsive layout (desktop & mobile)
  • Custom SVG icons
  • Loading spinner
  • Center play button

⌨️ Keyboard Shortcuts

  • Space or K - Play/Pause
  • / - Seek 5 seconds
  • J / L - Seek 10 seconds
  • / - Volume up/down
  • M - Mute/Unmute
  • F - Fullscreen toggle
  • P - Picture-in-Picture
  • 0-9 - Jump to percentage (10%-90%)
  • Home / End - Jump to start/end
  • Shortcuts only work for the currently active/focused player instance

📱 Touch Gestures

  • Tap - Play/Pause
  • Double tap left - Rewind 10 seconds
  • Double tap right - Forward 10 seconds
  • Swipe left/right - Seek
  • Swipe up/down - Volume control

🚀 Advanced Features

  • HLS Streaming - Automatic HLS.js integration for .m3u8 files
  • IPTV Support - MPEG-TS (.ts) streams for IPTV services
  • HTTP Range Request - Progressive download for large MP4 files
  • Subtitles - WebVTT and SRT support
  • Multiple Audio Tracks - Switch between different audio streams
  • Picture-in-Picture - Native browser PIP support
  • Fullscreen - Native fullscreen API
  • Buffer Indicator - Visual buffering progress
  • Error Handling - Graceful error states

📦 Installation

This package is distributed through a private registry.

1. Configure .npmrc

Create .npmrc in your app root:

@source:registry=https://gits.hibna.com.tr/api/packages/hibna/npm/
//gits.hibna.com.tr/api/packages/hibna/npm/:_authToken=${GITS_NPM_TOKEN}

2. Set token

Set your token in environment variables (GITS_NPM_TOKEN) and do not commit .npmrc with a hardcoded token.

3. Install package

npm install @source/player
# or
pnpm add @source/player
# or
yarn add @source/player

Note: This package requires react (>=18) and react-dom (>=18) at runtime but does not list them as peerDependencies to avoid install conflicts with private registries. Make sure your project already has React installed.

Streaming libraries (optional): HLS, FLV and MPEG-TS streaming libraries are loaded automatically from CDN when needed. If you prefer to bundle them locally, install them separately:

npm install hls.js    # HLS (.m3u8) streams
npm install flv.js    # FLV/RTMP streams
npm install mpegts.js # MPEG-TS (.ts) streams

Local development (optional)

# In this repository
npm run build:lib
npm link

# In your consuming app
npm link @source/player

🚀 Usage

Basic Example

import { VideoPlayer } from '@source/player'
import '@source/player/styles.css'

function App() {
  return (
    <VideoPlayer
      src="https://example.com/video.mp4"
      poster="https://example.com/poster.jpg"
    />
  )
}

Error Boundary (Optional)

import { VideoPlayer, PlayerErrorBoundary } from '@source/player'
import '@source/player/styles.css'

function App() {
  return (
    <PlayerErrorBoundary>
      <VideoPlayer src="https://example.com/video.mp4" />
    </PlayerErrorBoundary>
  )
}

With Subtitles

<VideoPlayer
  src="https://example.com/video.mp4"
  subtitles={[
    { src: '/subtitles/en.vtt', lang: 'en', label: 'English', default: true },
    { src: '/subtitles/tr.srt', lang: 'tr', label: 'Türkçe' },
  ]}
/>

Subtitle Styling (Custom Renderer)

<VideoPlayer
  src="https://example.com/video.mp4"
  subtitles={[{ src: '/subtitles/en.vtt', lang: 'en', label: 'English', default: true }]}
  subtitlePosition="bottom"
  subtitleOffset={72}
  subtitleStyle={{
    fontSize: 24,
    fontFamily: 'Arial, sans-serif',
    color: '#f8fafc',
    backgroundColor: '#111827',
    backgroundOpacity: 0.72,
  }}
/>

HLS Streaming

<VideoPlayer
  src="https://example.com/stream/playlist.m3u8"
  autoplay={false}
/>

Force Protocol (Override Auto Detection)

<VideoPlayer
  src="https://cdn.example.com/video"
  protocol="hls"
/>

IPTV Streaming

// Note: Browser support for direct .ts streams is limited
// For best compatibility, request .m3u8 (HLS) links from your IPTV provider
<VideoPlayer
  src="http://server.com:8080/live/username/password/12345.ts"
  poster="http://example.com/channel-logo.png"
  onError={(error) => {
    console.error('Stream error - try requesting .m3u8 format:', error)
  }}
/>

Custom Theme

<VideoPlayer
  src="https://example.com/video.mp4"
  theme={{
    primaryColor: '#ef4444',
    accentColor: '#dc2626',
    backgroundColor: '#000000',
    textColor: '#ffffff',
  }}
/>

With Volume and Playback Control

<VideoPlayer
  src="https://example.com/video.mp4"
  volume={0.5}              // 50% volume
  playbackRate={1.5}        // 1.5x speed
  currentTime={30}          // Start at 30 seconds
/>

With Event Handlers

<VideoPlayer
  src="https://example.com/video.mp4"
  onPlay={() => console.log('Video started playing')}
  onPause={() => console.log('Video paused')}
  onEnded={() => console.log('Video ended')}
  onTimeUpdate={(time) => console.log('Current time:', time)}
  onVolumeChange={(volume) => console.log('Volume:', volume)}
  onRateChange={(rate) => console.log('Playback rate:', rate)}
  onFullscreenChange={(isFs) => console.log('Fullscreen:', isFs)}
  onError={(error) => console.error('Video error:', error)}
/>

Feature Detection & Polyfills

import { features, initializePolyfills } from '@source/player'

// Initialize polyfills manually (optional - auto-initialized on VideoPlayer mount)
initializePolyfills()

// Check browser capabilities
console.log('Has PIP support:', features.hasPIP())
console.log('Has native HLS:', features.hasNativeHLS())
console.log('Has MSE for HLS.js:', features.hasMSE())
console.log('Is iOS Safari:', features.isIOSSafari())
console.log('Has volume control:', features.hasVolumeControl())

// Hide PIP button on unsupported devices
<VideoPlayer
  src="video.mp4"
  pictureInPicture={features.hasPIP()}
/>

CORS Error Handling

import { validateVideoURL, checkVideoCORS } from '@source/player'

// Validate URL before loading
const validation = validateVideoURL(videoUrl)
if (!validation.valid) {
  console.error(validation.error)
}

// Check CORS support (async)
const corsCheck = await checkVideoCORS(videoUrl)
if (!corsCheck.supported) {
  console.error('CORS issue:', corsCheck.error)
  console.log('Needs proxy:', corsCheck.needsProxy)
}

🛠️ Development

Setup

# Install dependencies
npm install

# Start development server
npm run dev

# Build library
npm run build:lib

# Type check
npx tsc --noEmit

# Format check
npm run format:check

# Full publish validation
npm run validate:publish

Project Structure

video-player/
├── src/
│   ├── components/       # React components
│   │   ├── controls/     # Control UI components
│   │   ├── overlays/     # Overlay components (loading, etc.)
│   │   └── menus/        # Settings menus
│   ├── contexts/         # React Context (PlayerContext)
│   ├── hooks/            # Custom React hooks
│   ├── utils/            # Utility functions
│   ├── types/            # TypeScript type definitions
│   ├── icons/            # Custom SVG icons
│   ├── styles/           # Global styles and CSS variables
│   └── index.ts          # Main export file
├── examples/             # Demo application
├── public/               # Static assets
└── dist/                 # Built library (generated)

📖 API Reference

VideoPlayer Props

Basic Props

Prop Type Default Description
src string required Video source URL (MP4, WebM, HLS, IPTV .ts)
poster string - Poster image URL
protocol 'auto' | 'native' | 'hls' | 'rtmp' | 'dash' | 'mpegts' 'auto' Force playback engine instead of URL auto-detection
autoplay boolean false Auto-play video on load
loop boolean false Loop video playback
muted boolean false Start muted
volume number - Initial volume (0-1)
playbackRate number - Playback speed (0.25, 0.5, 1, 1.5, 2, etc.)
currentTime number - Initial playback position in seconds
crossOrigin '' | 'anonymous' | 'use-credentials' - Sets the video crossOrigin attribute
preload 'none' | 'metadata' | 'auto' 'metadata' Sets the video preload strategy
playsInline boolean true Enables inline playback on mobile browsers
controlsList string - Passes controlsList attribute to the video element
controls boolean true Show player controls
subtitles SubtitleTrack[] [] Subtitle tracks
subtitleStyle SubtitleStyle - Custom subtitle text/background style
subtitlePosition 'top' | 'center' | 'bottom' 'bottom' Subtitle vertical placement
subtitleOffset number | string - Subtitle offset (px if number)
theme PlayerTheme - Custom theme colors
language string 'en' UI language ('en' or 'tr')
keyboardShortcuts boolean true Enable keyboard shortcuts
pictureInPicture boolean true Enable PIP button
className string - Custom CSS class
style CSSProperties - Inline styles

Event Handlers

Prop Type Description
onPlay () => void Fired when playback starts
onPause () => void Fired when playback pauses
onEnded () => void Fired when playback ends
onTimeUpdate (currentTime: number) => void Fired during playback with current time
onVolumeChange (volume: number) => void Fired when volume changes
onError (error: Error) => void Fired on playback error
onLoadedMetadata () => void Fired when video metadata is loaded
onSeeking () => void Fired when seeking starts
onSeeked () => void Fired when seeking completes
onProgress (buffered: number) => void Fired during download progress
onDurationChange (duration: number) => void Fired when duration changes
onRateChange (playbackRate: number) => void Fired when playback rate changes
onFullscreenChange (isFullscreen: boolean) => void Fired when fullscreen state changes
onPictureInPictureChange (isPip: boolean) => void Fired when PIP state changes
onWaiting () => void Fired when buffering starts
onCanPlay () => void Fired when enough data is available to play

PlayerErrorBoundary Props

Prop Type Description
children ReactNode Wrapped player/content tree
fallback ReactNode | (error: Error, retry: () => void) => ReactNode Optional custom fallback UI
onError (error: Error, errorInfo: React.ErrorInfo) => void Called when render errors are captured
onReset () => void Called when retry/reset is triggered
resetKeys readonly unknown[] Resets boundary when any key changes

SubtitleTrack

interface SubtitleTrack {
  src: string       // Subtitle file URL (.vtt or .srt)
  lang: string      // Language code (e.g., 'en', 'tr')
  label: string     // Display label
  default?: boolean // Set as default subtitle
}

PlayerTheme

interface PlayerTheme {
  primaryColor?: string      // Primary color (default: #ef4444)
  accentColor?: string       // Accent/hover color (default: #dc2626)
  backgroundColor?: string   // Background color (default: #000000)
  textColor?: string         // Text color (default: #ffffff)
}

🎯 Browser Support

  • Chrome/Edge 90+
  • Firefox 88+
  • Safari 14+
  • Mobile Safari 14+
  • Chrome Mobile 90+

📊 Bundle Size

  • Core player JS bundle: ~18KB (gzipped)
  • Core player CSS bundle: ~3.5KB (gzipped)
  • HLS.js (optional, lazy-loaded): ~200KB (only when using HLS streams)
  • MPEGTS.js (optional, lazy-loaded): ~72KB (gzipped, only for .ts streams)
  • Zero runtime dependencies (React is a prerequisite, see installation notes)

🔧 Technical Details

Native Browser APIs Used

  • HTML5 Video API
  • Fullscreen API
  • Picture-in-Picture API
  • Fetch API (Range Requests)
  • TextTrack API (subtitles)
  • Touch Events API
  • Keyboard Events API

Streaming Support

MP4/WebM (Progressive Download)

  • Uses HTTP Range Requests
  • Browser automatically chunks the download
  • No additional library needed
  • Works with any standard web server that supports Range headers

HLS (.m3u8)

  • Automatically detects HLS sources
  • Lazy loads hls.js library when needed
  • Safari has native HLS support (no library needed)
  • Adaptive bitrate streaming

Performance Optimizations

  • Lazy loading of HLS.js with CDN fallback
  • CSS-only animations
  • Debounced control hiding
  • Optimized re-renders with React.memo
  • Tree-shakeable exports
  • Memory leak prevention with proper cleanup
  • Polyfills for older browser support

Error Handling & Reliability

  • CORS Detection: Automatically detects and reports CORS issues with helpful error messages
  • HLS.js Fallback: If npm package fails to load, automatically falls back to CDN
  • Memory Management: Proper cleanup of HLS instances to prevent memory leaks
  • Browser Polyfills: Vendor prefix support for Fullscreen and PIP APIs
  • URL Validation: Validates video URLs before attempting to load
  • Feature Detection: Checks browser capabilities before using advanced features

🚧 TODO / Future Enhancements

  • Multiple audio track UI and switching
  • Quality selector for HLS streams
  • Playback speed menu
  • Settings panel
  • Chapters/markers support
  • Thumbnail preview on hover
  • Playlist support
  • Chromecast support
  • AirPlay support
  • DASH streaming support
  • Accessibility improvements (ARIA labels)
  • Unit tests
  • E2E tests
  • Storybook documentation

📝 License

MIT

👤 Author

Alper


Built with ❤️ using React, TypeScript, and Vite

Dependencies

Development Dependencies

ID Version
@eslint/js ^9.38.0
@testing-library/jest-dom ^6.9.1
@testing-library/react ^16.3.0
@testing-library/user-event ^14.6.1
@types/react ^19.2.2
@types/react-dom ^19.2.2
@typescript-eslint/eslint-plugin ^8.46.2
@typescript-eslint/parser ^8.46.2
@vitejs/plugin-react ^5.1.0
@vitest/ui ^4.0.4
baseline-browser-mapping ^2.9.19
eslint ^9.38.0
eslint-plugin-react-hooks ^7.0.1
eslint-plugin-react-refresh ^0.4.24
globals ^16.4.0
jsdom ^27.0.1
prettier ^3.6.2
react ^19.2.0
react-dom ^19.2.0
terser ^5.44.0
typescript ^5.9.3
vite ^7.1.12
vite-plugin-dts ^4.5.4
vitest ^4.0.4

Keywords

react video player video-player hls rtmp flv mpegts iptv streaming media
Details
npm
2026-02-13 02:15:35 +00:00
1
Alper
MIT
59 KiB
Assets (1)
Versions (8) View all
3.2.0 2026-02-14
3.1.2 2026-02-13
3.1.1 2026-02-13
3.1.0 2026-02-13
3.0.1 2026-02-13