JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 98
  • Score
    100M100P100Q77253F
  • License MIT

XStream Player SDK - A powerful video player SDK for streaming content

Package Exports

  • @xnstream/player-sdk
  • @xnstream/player-sdk/package.json

Readme

XStream Player SDK

A powerful and feature-rich video player SDK for streaming content, built with TypeScript and HLS.js.

Features

  • 🎥 HLS (HTTP Live Streaming) support - Industry-standard adaptive streaming
  • 📊 Adaptive bitrate streaming - Automatic quality adjustment based on network conditions
  • 🎯 Auto level capping - Restrict maximum quality based on resolution or bitrate
  • 🎬 Multi-audio track support - Switch between different audio languages
  • 📝 Subtitle/Caption support - Multiple subtitle tracks with language selection
  • 📈 Analytics tracking - Built-in watch time, bandwidth, and error tracking
  • 🎚️ Quality level switching - Manual or automatic quality control
  • Playback rate control - Speed up or slow down playback
  • 🎨 Customizable branding - Server-controlled theming and messaging
  • 📺 VAST/VPAID ads support - Pre-roll, mid-roll, and post-roll advertisements
  • 🔄 Automatic error recovery - Smart retry strategies for recoverable errors
  • 🎯 TypeScript support - Fully typed API for better development experience
  • 🌐 Comprehensive event system - React to all player state changes
  • 🔐 Secure playback - Session management and authentication
  • 💾 Local storage integration - Secure device registration

Installation

npm install @xnstream/player-sdk

Quick Start

import { StreamPlayer } from '@xnstream/player-sdk';

// Create player instance
const player = await StreamPlayer.create({
  appId: 'your-app-id',
  stream_code: 'your-stream-code',
  containerId: 'player-container',
  autoPlay: true,
  startAt: 0
});

// Initialize the player
await player.initialize();

// Listen for events
player.on('ready', () => {
  console.log('Player is ready');
});

player.on('playing', () => {
  console.log('Playback started');
});

player.on('error', (error) => {
  console.error('Playback error:', error);
});

// Play the stream
await player.play();

API Reference

StreamPlayer

The main player class that handles video playback and streaming.

Core Methods

Player Lifecycle
  • create(options: StreamPlayerOptions): Promise<StreamPlayer> - Create player instance
  • initialize(): Promise<void> - Initialize and load the stream
  • destroy(): void - Cleanup and destroy player instance
Playback Control
  • play(): Promise<void> - Start playback
  • pause(): void - Pause playback
  • seek(time: number): void - Seek to specific time
  • rewind(offset?: number): void - Rewind by offset (default: 10s)
  • fastForward(offset?: number): void - Fast forward by offset (default: 10s)
  • seekToLive(): void - Jump to live edge (for live streams)
Volume Control
  • setVolume(volume: number): void - Set volume (0.0 to 1.0)
  • getVolume(): number - Get current volume
  • toggleMute(): void - Toggle mute state
  • isMuted(): boolean - Check if muted
Playback Rate
  • setPlaybackRate(rate: number): void - Set playback speed (e.g., 0.5, 1.0, 2.0)
  • getPlaybackRate(): number - Get current playback rate
Quality Control
  • switchLevel(level: number): void - Switch to specific quality level
  • getLevels(): Level[] - Get available quality levels
  • getCurrentLevel(): number - Get current quality level ID
  • isAutolevelEnabled(): boolean - Check if automatic quality switching is enabled
Audio Tracks
  • getAudioTracks(): AudioTrack[] - Get available audio tracks
  • getCurrentAudioTrack(): number - Get current audio track ID
  • setAudioTrack(trackId: number): void - Switch audio track
Subtitle Tracks
  • getSubtitleTracks(): SubtitleTrack[] - Get available subtitle tracks
  • getCurrentSubtitleTrack(): number - Get current subtitle track ID (-1 = disabled)
  • setSubtitleTrack(trackId: number): void - Switch subtitle track (-1 to disable)
Configuration
  • getPlayerConfig(): PlayerConfig | undefined - Get player configuration from backend

Events

Playback Events
  • ready - Player is ready to play
  • playing - Playback has started
  • paused - Playback is paused
  • ended - Playback has finished
  • buffering - Player is buffering
Progress Events
  • onProgressUpdate: (progress: ProgressUpdate) => void - Progress updates (every 300ms)
  • onDataLoaded: (duration: number) => void - Video metadata loaded
Quality Events
  • onLevelsLoaded: (levels: Level[]) => void - Quality levels detected
  • onLevelSwitch: (level: number) => void - Quality level changed
  • onBufferUpdated: (buffer: BufferAppendedData) => void - Buffer updated
Audio Track Events
  • onAudioTracksLoaded: (tracks: AudioTrack[]) => void - Audio tracks detected
  • onAudioTrackSwitch: (trackId: number) => void - Audio track switched
Subtitle Track Events
  • onSubtitleTracksLoaded: (tracks: SubtitleTrack[]) => void - Subtitle tracks detected
  • onSubtitleTrackSwitch: (trackId: number) => void - Subtitle track switched
Control Events
  • volumechange: (volume: number) => void - Volume changed
  • ratechange: (rate: number) => void - Playback rate changed
Resource Events
  • onResourceChange: (resource: Resource) => void - Stream resource loaded
Error Events
  • error: (error: UnifiedError) => void - Error occurred (with retry information)
Ad Events
  • onAdStart: () => void - Ad playback started
  • onAdEnd: () => void - Ad playback completed
  • onAdProgress: (progress) => void - Ad playback progress
  • onAdError: (error: UnifiedError) => void - Ad error occurred
  • onAdClick: () => void - User clicked on ad
  • onAdFirstQuartile: () => void - Ad 25% complete
  • onAdSecondQuartile: () => void - Ad 50% complete
  • onAdThirdQuartile: () => void - Ad 75% complete

Configuration

StreamPlayerOptions

interface StreamPlayerOptions {
  appId: string;                      // Your application ID
  stream_code: string;                // Stream identifier
  containerId: string;                // DOM element ID for player
  autoPlay?: boolean;                 // Auto-start playback (default: false)
  startAt?: number;                   // Start position in seconds
  lowlatenctMode?: boolean;           // Enable low-latency mode for live streams
  context?: Record<string, any>;      // Custom context for analytics
  adOptions?: IAdsRequest;            // Advertisement configuration
  levelCapping?: LevelCappingOptions; // Auto quality level capping options
}

interface LevelCappingOptions {
  width?: number;                     // Maximum video width
  height?: number;                    // Maximum video height
  bitrate?: number;                   // Maximum bitrate in bps
}

PlayerConfig (Backend Configuration)

The player receives configuration from the backend that controls branding and behavior:

interface PlayerConfig {
  controls?: {
    viewsCounter?: boolean;          // Show view counter
    disablePause?: boolean;          // Disable pause button
    liveRewind?: boolean;            // Enable rewind for live streams
    autoPlay?: boolean;              // Override client autoPlay setting
    liveIcon?: boolean;              // Show live indicator
  };
  branding?: {
    theme?: string;                  // Theme name
    colorScheme?: string;            // Color scheme
    pageTitle?: string;              // Custom page title
    offlineMessage?: string;         // Custom offline message title
    offlineDescription?: string;     // Custom offline message description
  };
}

The backend configuration takes precedence over client options and provides custom error messages.

Advanced Features

Audio and Subtitle Tracks

The player supports multiple audio and subtitle tracks:

// Listen for available tracks
player.on('onAudioTracksLoaded', (tracks) => {
  console.log('Audio tracks:', tracks);
  // Display track selector UI
});

player.on('onSubtitleTracksLoaded', (tracks) => {
  console.log('Subtitle tracks:', tracks);
  // Display subtitle selector UI
});

// Switch tracks
player.setAudioTrack(1);      // Switch to audio track 1
player.setSubtitleTrack(0);   // Enable subtitle track 0
player.setSubtitleTrack(-1);  // Disable subtitles

// React to track changes
player.on('onAudioTrackSwitch', (trackId) => {
  console.log('Audio switched to:', trackId);
});

player.on('onSubtitleTrackSwitch', (trackId) => {
  console.log('Subtitle switched to:', trackId);
});

Error Handling

The SDK includes comprehensive error handling with automatic retry strategies:

player.on('error', (error) => {
  console.log('Error type:', error.type);
  console.log('Error context:', error.context);
  console.log('Is retryable:', error.isRetryable);
  console.log('Retry strategy:', error.retryStrategy);
  console.log('Severity:', error.severity);
  
  // All errors are automatically retried if retryable
  // Custom error messages from backend are displayed
});

Error Types:

  • validation - Input validation errors
  • client - Client-side errors (4xx)
  • server - Server-side errors (5xx)
  • network - Network connectivity issues
  • media - Media playback errors
  • storage - Local storage errors
  • security - Security/encryption errors
  • ads - Advertisement errors

Error Contexts:

  • unauthorized, forbidden, notFound
  • sourceOffline, sessionExpired
  • geoRestricted, deviceLimitReached, subscriptionRequired
  • mediaUnavailable, manifestError, fragmentError
  • networkTimeout, networkUnavailable
  • And more...

All errors include retry strategies with exponential backoff where appropriate.

Auto Level Capping

The SDK allows you to restrict the maximum quality level that can be selected automatically by the adaptive bitrate algorithm. This is useful for:

  • Limiting bandwidth usage on mobile networks
  • Matching video quality to device capabilities
  • Preventing high-resolution playback on smaller screens
// Cap quality to 1080p (Full HD)
const player = await StreamPlayer.create({
  appId: 'my-app-id',
  stream_code: 'my-stream',
  containerId: 'player-container',
  levelCapping: {
    width: 1920,
    height: 1080
  }
});

// Cap quality by bitrate (e.g., 5 Mbps)
const player = await StreamPlayer.create({
  appId: 'my-app-id',
  stream_code: 'my-stream',
  containerId: 'player-container',
  levelCapping: {
    bitrate: 5000000  // 5 Mbps in bits per second
  }
});

// Cap to 720p for mobile devices
const isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
const player = await StreamPlayer.create({
  appId: 'my-app-id',
  stream_code: 'my-stream',
  containerId: 'player-container',
  levelCapping: isMobile ? {
    width: 1280,
    height: 720
  } : undefined
});

How it works:

  • The player finds the highest quality level that doesn't exceed your specified constraints
  • If both width/height and bitrate are provided, width/height takes priority
  • The cap only affects automatic quality selection (ABR), not manual quality switching
  • If no level matches the constraints, no capping is applied

Custom Error Messages

The player displays custom error messages from the backend configuration:

// Backend provides custom offline message via PlayerConfig
{
  "branding": {
    "offlineMessage": "Stream Temporarily Unavailable",
    "offlineDescription": "We're experiencing technical difficulties. Check back soon."
  }
}

Analytics

The SDK includes built-in analytics tracking for:

  • Watch time - Accurate playback duration tracking
  • Bandwidth usage - Data consumption monitoring
  • Error tracking - Comprehensive error reporting
  • Quality level changes - Bitrate switching events
  • Delivery metrics - Fragment loading performance
  • Ad analytics - Advertisement interaction tracking

Type Definitions

The SDK is fully typed. Key types include:

import type {
  StreamPlayer,
  StreamPlayerOptions,
  LevelCappingOptions,
  StreamPlayerEvents,
  Level,
  AudioTrack,
  SubtitleTrack,
  PlayerConfig,
  UnifiedError,
  ProgressUpdate,
  Resource
} from '@xnstream/player-sdk';

Browser Support

  • ✅ Chrome (latest)
  • ✅ Firefox (latest)
  • ✅ Safari (latest)
  • ✅ Edge (latest)
  • ✅ Mobile browsers (iOS Safari, Chrome Mobile)

Requires support for:

  • ES2015+ JavaScript
  • Promises/async-await
  • Fetch API
  • HLS.js compatibility

Example: Complete Player Setup

import { StreamPlayer } from '@xnstream/player-sdk';
import type { AudioTrack, SubtitleTrack, UnifiedError } from '@xnstream/player-sdk';

async function setupPlayer() {
  // Create player
  const player = await StreamPlayer.create({
    appId: 'my-app-id',
    stream_code: 'my-stream',
    containerId: 'player-container',
    autoPlay: false,
    startAt: 0,
    context: {
      user_id: '12345',
      session_type: 'premium'
    }
  });

  // Setup event listeners
  player.on('ready', () => {
    console.log('Player ready');
  });

  player.on('onLevelsLoaded', (levels) => {
    console.log('Quality levels:', levels);
  });

  player.on('onAudioTracksLoaded', (tracks) => {
    // Build audio track selector
    tracks.forEach(track => {
      console.log(`Audio: ${track.name} (${track.lang})`);
    });
  });

  player.on('onSubtitleTracksLoaded', (tracks) => {
    // Build subtitle track selector
    tracks.forEach(track => {
      console.log(`Subtitle: ${track.name} (${track.lang})`);
    });
  });

  player.on('error', (error: UnifiedError) => {
    console.error('Error:', error.message);
    if (error.isRetryable) {
      console.log('Will retry automatically');
    }
  });

  player.on('onProgressUpdate', (progress) => {
    console.log(`Position: ${progress.position}s`);
  });

  // Initialize and play
  await player.initialize();
  await player.play();

  // Example: Switch to Spanish audio
  const spanishAudio = player.getAudioTracks().find(t => t.lang === 'es');
  if (spanishAudio) {
    player.setAudioTrack(spanishAudio.id);
  }

  // Example: Enable English subtitles
  const englishSubs = player.getSubtitleTracks().find(t => t.lang === 'en');
  if (englishSubs) {
    player.setSubtitleTrack(englishSubs.id);
  }
}

setupPlayer();

License

MIT

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Support

For issues and questions, please visit our GitHub repository.

Repository

This project is hosted on GitHub: https://github.com/caltek/xPlayerSDKJS