Skip to content

Madraka/nextjs-videoplayer

Repository files navigation

🎬 NextJS Video Player

NPM Version License TypeScript Demo

Modern, customizable video player for Next.js applications with adaptive streaming, mobile optimization, and advanced features.

✨ Features

  • 🎯 Next.js 15+ App Router Ready
  • πŸ“± Mobile-First Design with VK Player-inspired controls
  • 🎬 Adaptive Streaming (HLS.js & Dash.js support)
  • πŸ–ΌοΈ Thumbnail Previews with sprite sheet support
  • 🎨 Highly Customizable with TypeScript configuration
  • πŸ‘† Touch Gestures optimized for mobile
  • ⚑ Performance Optimized with lazy loading
  • πŸŽͺ Single Official Preset (default) with per-instance overrides
  • πŸ“Š Built-in Analytics tracking
  • β™Ώ Accessibility compliant

πŸš€ Quick Start

Installation

# Using npm
npm install @madraka/nextjs-videoplayer

# Using pnpm  
pnpm add @madraka/nextjs-videoplayer

# Using yarn
yarn add @madraka/nextjs-videoplayer

# Install directly from GitHub
npm install github:Madraka/nextjs-videoplayer
pnpm add github:Madraka/nextjs-videoplayer
yarn add github:Madraka/nextjs-videoplayer

Basic Usage

'use client';

import { ConfigurableVideoPlayer } from '@madraka/nextjs-videoplayer';

export default function MyVideoPage() {
  return (
    <div className="max-w-4xl mx-auto p-4">
      <ConfigurableVideoPlayer
        src="https://example.com/video.m3u8"
        poster="https://example.com/poster.jpg"
        aspectRatio="16/9"
      />
    </div>
  );
}

With Configuration

'use client';

import { 
  ConfigurableVideoPlayer,
  PlayerConfigProvider,
  PlayerPresets 
} from '@madraka/nextjs-videoplayer';

export default function AdvancedVideoPage() {
  return (
    <PlayerConfigProvider config={PlayerPresets.default}>
      <ConfigurableVideoPlayer
        src="https://example.com/video.m3u8"
        thumbnailUrl="https://example.com/thumbnails/"
        aspectRatio="16/9"
        autoPlay={false}
        muted={false}
        onPlay={() => console.log('Video started playing')}
        onPause={() => console.log('Video paused')}
      />
    </PlayerConfigProvider>
  );
}

πŸ“š Documentation

Props

Prop Type Default Description
src string - Video source URL (HLS, DASH, MP4)
poster string - Poster image URL
thumbnailUrl string - Base URL for thumbnail previews
aspectRatio 'auto' | '16/9' | '4/3' | '1/1' | '9/16' 'auto' Video aspect ratio
autoPlay boolean false Auto-play video
muted boolean false Start muted
loop boolean false Loop video
playsInline boolean true Plays inline on mobile

Event Callbacks

<ConfigurableVideoPlayer
  src="video.m3u8"
  onReady={() => console.log('Player ready')}
  onPlay={() => console.log('Playing')}
  onPause={() => console.log('Paused')}
  onError={(error) => console.error('Error:', error)}
  onTimeUpdate={(currentTime, duration) => {
    console.log(`${currentTime}s / ${duration}s`);
  }}
/>

Preset

Use the official default setup:

import { PlayerPresets } from '@madraka/nextjs-videoplayer';

<PlayerConfigProvider config={PlayerPresets.default}>

πŸ”§ Configuration Options

Player Configuration

Create custom configurations for different use cases:

import { PlayerConfig } from '@madraka/nextjs-videoplayer';

const customConfig: PlayerConfig = {
  theme: {
    primaryColor: '#3b82f6',
    backgroundColor: '#000000',
    controlsOpacity: 0.8,
  },
  controls: {
    showPlayButton: true,
    showVolumeControl: true,
    showProgressBar: true,
    showFullscreenButton: true,
    showSettingsButton: true,
    autoHide: true,
    autoHideDelay: 3000,
  },
  playback: {
    autoPlay: false,
    muted: false,
    loop: false,
    playsInline: true,
    preload: 'metadata',
  },
  gestures: {
    enabled: true,
    doubleTapToSeek: true,
    swipeToSeek: true,
    pinchToZoom: false,
  },
  analytics: {
    enabled: true,
    trackPlay: true,
    trackPause: true,
    trackSeek: true,
    trackQualityChange: true,
  }
};

<PlayerConfigProvider config={customConfig}>
  <ConfigurableVideoPlayer src="video.m3u8" />
</PlayerConfigProvider>

Video Formats Support

The player automatically detects and handles multiple video formats:

  • HLS (.m3u8) - HTTP Live Streaming for adaptive bitrate
  • DASH (.mpd) - Dynamic Adaptive Streaming over HTTP
  • MP4 - Standard progressive download
  • WebM - Modern web video format
  • MOV - QuickTime format
// HLS Stream
<ConfigurableVideoPlayer src="https://example.com/stream.m3u8" />

// DASH Stream  
<ConfigurableVideoPlayer src="https://example.com/stream.mpd" />

// Progressive MP4
<ConfigurableVideoPlayer src="https://example.com/video.mp4" />

// Multiple sources with fallback
<ConfigurableVideoPlayer 
  src={[
    { src: "video.m3u8", type: "application/x-mpegURL" },
    { src: "video.mp4", type: "video/mp4" }
  ]} 
/>

🎨 Styling

With Tailwind CSS

The player works seamlessly with Tailwind CSS:

<ConfigurableVideoPlayer
  src="video.m3u8"
  className="rounded-lg shadow-xl"
  aspectRatio="16/9"
/>

πŸ“± Mobile Optimization

The player automatically detects mobile devices and provides:

  • Touch-optimized controls
  • Gesture support (tap, double-tap, swipe)
  • Auto-hide controls
  • Responsive layout
  • Mobile-first design

πŸ”§ Advanced Features

Analytics

const analyticsConfig = {
  analytics: {
    enabled: true,
    trackPlay: true,
    trackPause: true,
    trackSeek: true,
    trackQualityChange: true
  }
};

Keyboard Shortcuts

  • Space - Play/Pause
  • F - Fullscreen
  • M - Mute/Unmute
  • ←/β†’ - Seek backward/forward
  • ↑/↓ - Volume up/down

Thumbnail Previews

<ConfigurableVideoPlayer
  src="video.m3u8"
  thumbnailUrl="https://cdn.example.com/thumbnails/"
  // Expects thumbnails at: thumbnailUrl + "sprite.jpg"
  // And thumbnails.vtt for timing information
/>

πŸ› οΈ Development

# Clone the repository
git clone https://github.com/madraka/nextjs-videoplayer.git

# Install dependencies
pnpm install

# Start showcase development server
pnpm dev

# Build showcase
pnpm build

# Build npm package
pnpm build:package

# Run package tests
pnpm test

CI/CD Pipelines

This repository uses two separate GitHub Actions workflows:

  • Showcase CI (.github/workflows/showcase-ci.yml)

    • Runs on push and pull_request to main
    • Validates showcase quality: lint, type-check, build
    • Does not publish to npm
  • Package Publish (.github/workflows/package-publish.yml)

    • Runs on version tags like v1.2.3
    • Validates package quality and runs build:package
    • Publishes to npm and creates a GitHub Release

This keeps Vercel showcase deployment and npm package publishing isolated.

Monorepo Migration Status

  • Workspace scaffolding is active via pnpm-workspace.yaml.
  • Active layout:
    • apps/showcase (Next.js showcase app)
    • packages/player (publishable npm package)
  • Root scripts orchestrate both workspaces.
  • Migration plan and phases are documented in docs/ROADMAP.md.

Vercel Deploy

  • Root vercel.json now builds the showcase app from apps/showcase.
  • Build command: pnpm -C apps/showcase build
  • Output directory: apps/showcase/.next

Release Flow

# Option A (automated release script)
pnpm release:patch
# or
pnpm release:minor
pnpm release:major

# Option B (changesets-first workflow)
pnpm changeset
pnpm changeset:version
pnpm release:check
pnpm release:tag

When the vX.Y.Z tag is pushed, Package Publish handles npm publish + GitHub release.

GitHub Installation

For direct GitHub installation:

# Latest from main branch
npm install github:Madraka/nextjs-videoplayer

# Specific version/tag
npm install github:Madraka/nextjs-videoplayer#v1.0.0

# In package.json
{
  "dependencies": {
    "@madraka/nextjs-videoplayer": "github:Madraka/nextjs-videoplayer#v1.0.0"
  }
}

πŸ“¦ Package Structure

nextjs-videoplayer/
β”œβ”€β”€ apps/
β”‚   └── showcase/         # Next.js showcase app
β”œβ”€β”€ packages/
β”‚   └── player/           # Publishable npm package (@madraka/nextjs-videoplayer)
β”œβ”€β”€ docs/
β”œβ”€β”€ pnpm-workspace.yaml
└── turbo.json

🀝 Contributing

Contributions are welcome! Please read our Contributing Guide for details.

πŸ“„ License

MIT License - see LICENSE file for details.

πŸ™ Acknowledgments


Made with ❀️ for the Next.js community

About

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages