jd-devix-player-test
v1.0.22
Published
The `VPPlayer` component is a React-based video player built using the VP Player library from `https://host.vpplayer.tech`.
Readme
VP Player Component Documentation
The VPPlayer component is a React-based video player built using the VP Player library from https://host.vpplayer.tech.
It supports multiple ways to configure and play videos, including single files, playlists with direct files, single videos fetched via API, and playlists fetched via API. This document outlines the component's interface, configuration, and usage.
Overview
The VPPlayer component dynamically loads the VP Player script (vpplayer.js) and initializes it with a configuration object. The configuration is built based on the provided props, which determine the source and type of video data to play. It supports Horizontal (Standard) and Vertical (Reels) modes, along with comprehensive analytics tracking.
Installation
To install the package, run:
npm install @devix-technologies/react-gjirafa-vp-player
# or
yarn add @devix-technologies/react-gjirafa-vp-player
# or
pnpm add @devix-technologies/react-gjirafa-vp-playerQuick Start
Here is a basic example of how to use the VPPlayer component in your React application:
import { VPPlayer } from "@devix-technologies/react-gjirafa-vp-player";
const App = () => {
return (
<div style={{ maxWidth: "800px", margin: "0 auto" }}>
<VPPlayer
playerId="my-unique-player-id"
videoUrl="https://example.com/video.mp4"
version="latest"
/>
</div>
);
};
export default App;Source Files Structure
├── src/
│ ├── components/
│ │ └── VPPlayer/
│ │ ├── index.ts
│ │ └── ui/
│ │ ├── index.ts
│ │ ├── styled.tsx
│ ├── config/
│ │ ├── index.ts
│ │ ├── vpPlayerConfig.ts
│ ├── constants/
│ │ ├── index.ts
│ │ ├── vpPlayer.ts
│ ├── contexts/
│ │ ├── VPPlayerContext.tsx
│ │ ├── index.ts
│ ├── features/
│ │ ├── VPPlayer.tsx
│ │ ├── stories/
│ │ │ ├── ads/
│ │ │ │ ├── Ads.stories.tsx
│ │ │ ├── context/
│ │ │ │ ├── Context.stories.tsx
│ │ │ ├── playback/
│ │ │ │ ├── Playback.stories.tsx
│ ├── fixtures/
│ │ ├── index.ts
│ │ ├── playlist.ts
│ ├── hooks/
│ │ ├── index.ts
│ │ ├── useVPPlayerEvents.ts
│ │ ├── useVPPlayerLogic.ts
│ │ ├── useVPPlayerScript.ts
│ │ ├── useVideoData.ts
│ ├── interfaces/
│ │ ├── config.ts
│ │ ├── index.ts
│ │ ├── instance.ts
│ │ ├── props.ts
│ │ ├── styles.ts
│ ├── types/
│ │ ├── api.types.ts
│ │ ├── playerEvents.types.ts
│ │ ├── index.ts
│ ├── utils/
│ │ ├── index.ts
│ │ ├── vpPlayerConfigBuilder.ts
│ │ ├── vpPlayerUtils.ts
│ ├── App.css
│ ├── App.tsx
│ ├── index.css
│ ├── main.tsx
│ ├── vite-env.d.tsInterface
The component accepts props defined by the VPPlayerProps interface:
interface VPPlayerProps {
playerId: string; // Unique identifier for the player instance, might be random integer,
but must be unique, for multiple VPPlayer instances use different values
videoId?: string; // Unique identifier for the video or a placeholder
version?: string | null; // Optional version e.g. "v2.1.1" of the VP Player script (defaults to 'latest')
videoUrl?: string; // Direct URL to a single video file (e.g., .mp4, .m3u8)
projectId?: string; // Project ID for API calls (used with videoId or playlistId)
playlistId?: string; // Playlist ID for fetching a playlist from API
config?: Partial<VPPlayerConfig>; // Optional partial configuration to override defaults
isReels?: boolean; // Optional flag to enable Reels/iShorties mode (defaults to false)
thumbnailUrl?: string; // Optional URL to a thumbnail image for Reels mode
hiddenClasses?: string[]; // Optional array of CSS class names to hide specific player elements
className?: string; // Optional CSS class name for additional styling of the player
onClose, // Handler function triggered when the player is closed.
isPlayerVisible, // Flag indicating whether the player is currently visible.
onPlaylistData?: (videos: PlaylistItem[]) => void; // Optional callback that fires when playlist data is loaded
onVideoStarted?: (videoData: CurrentVideoData) => void; // Optional callback that fires when a video starts playing
// Analytics & Event Callbacks
onPlayerStart?: (event: string) => void; // Fires when playback starts for the first time
onPlayerPlay?: (event: string) => void; // Fires on subsequent play actions
onPlayerPause?: (event: string) => void; // Fires when playback is paused
onPlayerResume?: (event: string) => void; // Fires when playback is resumed
onPlayerNext?: (event: string) => void; // Fires on next video click
onPlayerPrevious?: (event: string) => void; // Fires on previous video click
onPlayerEnd?: (event: string) => void; // Fires when video ends
onPlayerProgressEvery10Seconds?: (event: string, currentPosition: number) => void; // Fires every 10s
onPlayerProgressAt20Seconds?: (event: string, currentPosition: number) => void; // Fires specifically at 20s
onPlayerQuartile25?: (event: string, currentPosition: number) => void; // Fires at 25% progress
onPlayerQuartile50?: (event: string, currentPosition: number) => void; // Fires at 50% progress
onPlayerQuartile75?: (event: string, currentPosition: number) => void; // Fires at 75% progress
onPlayerEvent?: (event: string, currentPosition?: number) => void; // Universal callback for all events
}Props Description
playerId: string
- Unique identifier for the player instance. Must be unique across multiple
VPPlayerinstances to avoid conflicts.
videoId?: string
- Optional identifier for a single video to fetch from the API. Used in conjunction with
projectIdfor API-based video playback.
version?: string | null
- Optional version of the VP Player script (e.g.,
"v2.1.1"). Defaults to"latest"if not specified.
videoUrl?: string
- Optional direct URL to a video file (e.g.,
.mp4,.m3u8) for single-file playback without API involvement.
projectId?: string
- Optional project ID for API calls. Required when using
videoIdorplaylistIdto fetch video data from the API.
playlistId?: string
- Optional playlist ID for fetching a playlist from the API. Used with
projectIdto retrieve a dynamic playlist.
config?: Partial
- Optional partial configuration object to override the default
VPPlayerConfig. Allows customization of player behavior and settings.
isReels?: boolean
- Optional flag to enable Reels/iShorties mode, optimizing the player for short vertical video playback (e.g., 9:16 aspect ratio). Defaults to
false.
thumbnailUrl?: string
- Optional URL to a thumbnail image displayed in Reels mode before playback starts. Enhances the visual preview for short videos.
hiddenClasses?: string[]
- Optional array of CSS class names corresponding to player elements that should be hidden. Elements with these classes will have
display: noneapplied, effectively removing them from the visible UI without affecting their underlying functionality (unless explicitly disabled). Useful for customizing the player's appearance by hiding unwanted controls. - Example:
["vp-icon-share", "vp-icon-fullscreen"]hides the share and fullscreen buttons.
className?: string
- Optional CSS class name for additional styling of the player. This prop allows you to apply custom styles to the entire player component or its internal elements by targeting specific CSS classes (e.g., vp-play-pause, vp-control-bar). Styles must be defined in an external CSS file, and you can use !important to override default styles if needed. This provides flexibility to customize the player's appearance, such as changing colors, repositioning buttons, or adjusting layout.
- Example:
"custom-player"can be used to apply styles defined in an external CSS file like.custom-player { border: 2px solid red; }or.custom-player .vp-play-pause { display: none; }.
onClose?: => void;
- Optional handler function triggered when the player is closed. This callback is invoked when the user closes the player, typically via a close button or an overlay dismissal.
isPlayerVisible?: boolean;
- Optional flag indicating whether the player is currently visible. Controls the visibility of the player component, typically used to show or hide the player in a modal, overlay, or inline context.
onPlaylistData?: (videos: PlaylistItem[]) => void
- Optional callback function that fires when playlist data is successfully loaded from the API. This is useful for:
- Getting a list of all videos in the playlist (including main and backup playlists)
- Displaying a video list/menu in your UI
- Pre-loading thumbnails or metadata
- Building custom playlist navigation
- Parameters:
videos: Array ofPlaylistItemobjects containing video metadata (title, hlsUrl, thumbnailUrl, duration, isBackupPlaylist, mediaId)
- When it fires:
- Once when playlist data is fetched from API (for playlists via
playlistId)
- Once when playlist data is fetched from API (for playlists via
- Example:
<VPPlayer
playerId="player"
projectId="agmipnzb"
playlistId="lzxikgjw"
onPlaylistData={(videos) => {
console.log('Playlist loaded:', videos.length, 'videos');
console.log('Main videos:', videos.filter(v => !v.isBackupPlaylist).length);
console.log('Backup videos:', videos.filter(v => v.isBackupPlaylist).length);
// Update your UI with playlist data
}}
/>onVideoStarted?: (videoData: CurrentVideoData) => void
Optional callback function that fires when a video starts playing. This provides real-time information about the currently playing video. Behavior differs between player types:
Vertical Player (Reels):
- Fires on scroll (swipe up/down) to navigate between videos
- Fires on arrow button clicks (next/previous)
- Returns basic metadata from the already-loaded playlist
Horizontal Player (Standard):
- Fires on Next/Previous button clicks
- Fires when video ends and next video auto-plays
- Fetches complete metadata from API (
https://host.vpplayer.tech/player/{playerId}/{videoId}.json) - Returns comprehensive data including author, tags, publishDate, premium status, etc.
Parameters:
videoData: Object containing video metadata:videoId- Video IDtitle- Video titledescription- Video description (HTML)file/hlsUrl- Video stream URLthumbnailUrl- Thumbnail image URLduration- Video duration in secondsvideoIndex- Index in playlist (0-based)playlistVideoIndex- VP Player playlist indexisBackupPlaylist- Whether video is from backup playlist- Horizontal player additional fields:
publishDate- Publication date (ISO format)projectId- Project/entity IDpremium- Whether video is locked/premiumauthor- Video author nametags- Array of video tags
Use cases:
- Analytics tracking: Track video views, engagement, navigation patterns
- Custom UI updates: Display current video info, progress indicators
- Content recommendations: Use tags/author to suggest related content
- Monetization: Check premium status, track ad opportunities
- Social features: Display author info, enable sharing
Example (Vertical Player):
<VPPlayer
playerId="vertical-player"
projectId="agmipnzb"
playlistId="lzxikgjw"
scriptUrl="https://host.vpplayer.tech/vertical-player/rbqcdwznd.js"
isReels={true}
onVideoStarted={(videoData) => {
console.log('Video changed:', videoData.title);
console.log('Video index:', videoData.videoIndex);
// Track analytics, update UI
}}
/>- Example (Horizontal Player with full metadata):
<VPPlayer
playerId="horizontal-player"
projectId="agmipnzb"
videoId="vjsnuhvm"
scriptUrl="https://host.vpplayer.tech/player/ptkzurnx.js"
onVideoStarted={(videoData) => {
console.log('Video started:', videoData.title);
console.log('Author:', videoData.author);
console.log('Tags:', videoData.tags);
console.log('Published:', videoData.publishDate);
console.log('Premium:', videoData.premium);
// Send to analytics
analytics.track('video_started', {
video_id: videoData.videoId,
title: videoData.title,
author: videoData.author,
tags: videoData.tags
});
}}
/>Configuration
The player configuration is defined by the VPPlayerConfig interface, which is partially overridden by the config prop and dynamically built based on the input types.
Script Loading: Loads the VP Player script (https://host.vpplayer.tech/player/${PLAYER_VERSION}/vpplayer.js) asynchronously if not already present.
Player Setup: Once the script is loaded and the DOM element is rendered, the vpPlayer function is called with the element's ID and the final configuration.
Supported Data Input Types
Supported Data Input Types
The VPPlayer component supports multiple types of video data inputs, determined by the props provided:
- Single Video File
Props: videoUrl
Behavior: Plays a single video directly from the provided URL.
Usage:
<VPPlayer
playerId="player-1" // Must be a unique string (e.g., "player-1", "123", etc.)
version="latest"
videoUrl="http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"
/>- Playlist with Files
Props: config with video.playlist
Behavior: Plays a playlist of videos defined statically in the config prop.
Usage:
<VPPlayer
playerId="player-2"
version="latest"
config={{
projectId: 'vp-player-projectId', // optional placeholder
video: {
file: playlist.videos[0].file, // Initial video file, first in the queue
playlist: playlist, // Pass the full playlist array object
},
}}
/>- Single Video via API (VideoId)
Props: projectId, videoId
Behavior: Fetches the playbackUrl from the API endpoint https://vp-api.gjirafa.tech/api/v2/projects/{projectId}/videos?search={videoId} and plays the video.
Usage:
<VPPlayer
playerId="player-3"
version="latest"
videoId="vjsnuxxx"
projectId="agmipxxx"
/>- Playlist via API (PlaylistId)
Props: projectId, playlistId
Behavior: Fetches a playlist from the API endpoint https://vp-api.gjirafa.tech/api/projects/{projectId}/playlists/{playlistId}/videos and builds a playlist object dynamically.
Usage:
<VPPlayer
playerId="player-4"
version="latest"
projectId="agmipxxx"
playlistId="lzxikxxx"
/>- Example with
hiddenClassesandclassName\
Usage:
<VPPlayer
playerId="player-5"
isReels={true}
thumbnailUrl="https://images.pexels.com/videos/4678261/pexels-photo-4678261.jpeg?auto=compress&cs=tinysrgb&w=600"
hiddenClasses={["vp-icon-share", "vp-icon-fullscreen"]} // Hides share and fullscreen buttons
className="custom-player" // Defined class for custom styling
config={{
video: {
playlist: {
state: true,
playlistVideoIndex: 0,
videos: [
{ videoId: "1", file: "https://videos.pexels.com/video-files/4678261/4678261-hd_1080_1920_25fps.mp4" },
{ videoId: "2", file: "https://videos.pexels.com/video-files/4678261/4678261-hd_1080_1920_25fps.mp4" },
],
},
},
}}
/>
# e.g.
/* Define custom styles in your CSS file */
.custom-player {
/* Your own styles here */
}Video Tracking & Analytics
The VPPlayer component provides two powerful callbacks for tracking video playback and playlist data:
onPlaylistData - Playlist Data Callback
Fires once when playlist is loaded. Useful for building custom UI or pre-loading data.
import { VPPlayer } from "@dvxx/vp-player";
import { useState } from "react";
const MyPlaylistComponent = () => {
const [videos, setVideos] = useState([]);
return (
<>
{/* Display video list */}
<ul>
{videos.map((video, idx) => (
<li key={idx}>
{video.title} {video.isBackupPlaylist && "(Backup)"}
</li>
))}
</ul>
{/* Player with callback */}
<VPPlayer
playerId="my-playlist-player"
projectId="agmipnzb"
playlistId="lzxikgjw"
onPlaylistData={(playlistVideos) => {
setVideos(playlistVideos);
console.log("Loaded videos:", playlistVideos.length);
}}
/>
</>
);
};onVideoStarted - Video Change Tracking
Fires every time a video starts (scroll, click, auto-play). Perfect for analytics and real-time UI updates.
Vertical Player Example:
<VPPlayer
playerId="reels-player"
projectId="agmipnzb"
playlistId="lzxikgjw"
scriptUrl="https://host.vpplayer.tech/vertical-player/rbqcdwznd.js"
isReels={true}
onVideoStarted={(videoData) => {
// Fires on scroll or arrow navigation
console.log("Now playing:", videoData.title);
console.log("Video index:", videoData.videoIndex);
// Send to analytics
trackVideoView({
videoId: videoData.videoId,
index: videoData.videoIndex,
isBackup: videoData.isBackupPlaylist
});
}}
/>Horizontal Player Example (with full metadata):
<VPPlayer
playerId="standard-player"
projectId="agmipnzb"
videoId="vjsnuhvm"
scriptUrl="https://host.vpplayer.tech/player/ptkzurnx.js"
onVideoStarted={(videoData) => {
// Fires on next/previous or auto-play
// Full metadata fetched from API
console.log({
title: videoData.title,
author: videoData.author,
tags: videoData.tags,
publishDate: videoData.publishDate,
premium: videoData.premium,
description: videoData.description
});
// Rich analytics tracking
analytics.track("video_view", {
video_id: videoData.videoId,
video_title: videoData.title,
author: videoData.author,
tags: videoData.tags,
is_premium: videoData.premium,
project_id: videoData.projectId
});
}}
/>Combined Example (both callbacks):
import { VPPlayer } from "@dvxx/vp-player";
import { useState } from "react";
const AdvancedPlayerComponent = () => {
const [playlistVideos, setPlaylistVideos] = useState([]);
const [currentVideo, setCurrentVideo] = useState(null);
return (
<div>
{/* Current video info */}
{currentVideo && (
<div className="video-info">
<h3>{currentVideo.title}</h3>
<p>Video {currentVideo.videoIndex + 1} of {playlistVideos.length}</p>
{currentVideo.author && <p>By: {currentVideo.author}</p>}
{currentVideo.tags && <p>Tags: {currentVideo.tags.join(", ")}</p>}
</div>
)}
{/* Player */}
<VPPlayer
playerId="advanced-player"
projectId="agmipnzb"
playlistId="lzxikgjw"
scriptUrl="https://host.vpplayer.tech/player/ptkzurnx.js"
onPlaylistData={(videos) => {
setPlaylistVideos(videos);
console.log(`Playlist loaded: ${videos.length} videos`);
}}
onVideoStarted={(videoData) => {
setCurrentVideo(videoData);
console.log(`Playing video ${videoData.videoIndex + 1}`);
}}
/>
{/* Video playlist */}
<div className="playlist">
{playlistVideos.map((video, idx) => (
<div
key={idx}
className={currentVideo?.videoIndex === idx ? "active" : ""}
>
{video.title}
</div>
))}
</div>
</div>
);
};Playback Event Tracking (Analytics)
Besides tracking playlist and video changes, VPPlayer offers granular callbacks for tracking player state and progress. This is ideal for sending data to analytics services (e.g., Google Analytics, Segment).
You can use specific callbacks for each event type or a single universal callback.
1. Available Events
The following events are tracked:
- State Events:
player_start,player_play,player_pause,player_resume,player_end,player_next,player_previous - Progress Events:
player_progress_every_10_seconds,player_progress_at_20_seconds - Quartile Events:
player_quartile_25,player_quartile_50,player_quartile_75
Note: Progress and Quartile events allow you to access the currentPosition (in seconds).
2. Using Specific Callbacks
Use this approach if you want to handle only specific events.
<VPPlayer
// ... other props
onPlayerStart={(event) => console.log("Started:", event)}
onPlayerPause={(event) => console.log("Paused:", event)}
onPlayerQuartile50={(event, time) => console.log("50% watched at:", time)}
onPlayerEnd={(event) => console.log("Finished:", event)}
/>3. Using Universal Callback (onPlayerEvent)
Use this approach to route all events through a single function, which simplifies integration with analytics providers.
const handleAnalytics = (eventName: string, currentPosition?: number) => {
// Example: Send to analytics layer
analytics.track(eventName, {
video_id: "12345",
timestamp: currentPosition || 0,
device: "desktop"
});
console.log(`[Analytics] ${eventName}`, currentPosition ? `Time: ${currentPosition}` : "");
};
<VPPlayer
playerId="analytics-player"
// ... other props
onPlayerEvent={handleAnalytics}
/>Release Notes
v1.0.27
- Fixes:
- Fixed
getCurrentVideoData()to support 2 data sources: config-based playlist, and single video - Fixed
onVideoStartedcallback to correctly return video data for config-based playlists
- Fixed
- Features:
- Improved video tracking for playlists passed directly via
configprop
- Improved video tracking for playlists passed directly via
v1.0.26
- Fixes:
- Fixed config-based playlist indexing for vertical players -
onVideoStartednow correctly reports video index on scroll. - Fixed
getCurrentVideoData()to properly handle playlists passed viaconfig.video.playlist.videos. - Improved
vpPlayerConfigBuilderto use correct initial video based onplaylistVideoIndex.
- Fixed config-based playlist indexing for vertical players -
- Refactor:
- Removed
fetchedPlaylistdependency fromuseVPPlayerLogic- all playlist data now flows through config. - Cleaned up unused constants (
DEFAULT_PLAYLIST_IDremoved from exports).
- Removed
v1.0.25 (unpublished)
v1.0.24
- Fixes:
- Fixed event tracking for vertical players with
isReels={false}. - Unified event listener setup logic - detection now based on
scriptUrlinstead ofisReelsprop. - Fixed 400 Bad Request errors for horizontal player tracking by ensuring
projectIdis always included in config. - Re-added
readyandplaylistItemevent listeners for horizontal player navigation.
- Fixed event tracking for vertical players with
- Features:
- Full metadata fetching now works for both vertical and horizontal players.
- Refactor:
- Changed
DEFAULT_PROJECT_IDto generic value for better reusability. - Replaced
edge.vpplayer.techwithhost.vpplayer.techfor better performance.
- Changed
v1.0.23
- Features:
- Enhanced vertical player analytics with improved event tracking.
- Added support for passing video arrays directly via
config.video.playlist.videos.
- Fixes:
- Fixed duplicate event triggering in vertical player.
- Improved
player_startandplayer_playevent logic forplayer_next/player_previousactions.
v1.0.22
- New Features:
- Added comprehensive Analytics Event Callbacks (
onPlayerStart,onPlayerPlay,onPlayerPause,onPlayerEnd, etc.). - Added Universal
onPlayerEventcallback for simplified event tracking. - Added support for Vertical Player analytics including
player_next/player_previouson scroll/swipe. - Added Progress & Quartile events (10s, 20s, 25%, 50%, 75%) with
currentPositiondata.
- Added comprehensive Analytics Event Callbacks (
- Fixes:
- Fixed
videoIdconfiguration issue in VP Player tracking causing 400 errors. - Refined event logic to prevent duplicate events (e.g.,
player_pauseduring scroll/click).
- Fixed
v1.0.21
- Fixes:
- Fixed vertical fullscreen video layout to rely on
aspect-ratio. - Cleaned up unused variables in Storybook examples.
- Fixed vertical fullscreen video layout to rely on
v1.0.20
- Features:
- Added full metadata API fetch for Vertical Player (
onVideoStartednow returns more comprehensive data).
- Added full metadata API fetch for Vertical Player (
v1.0.19
- Features:
- Added full metadata support for Horizontal Player.
- Introduced
onVideoStartedcallback for tracking video changes and retrieving metadata (title, author, tags, premium status, etc.).
- Documentation:
- Updated documentation to reflect new metadata capabilities.
v1.0.18
- Features:
- Added
onPlaylistDatacallback prop to access the full playlist structure (videos, backup status, etc.).
- Added
v1.0.17
- Styles:
- Adjusted vertical player wrapper sizing for better layout consistency.
v1.0.16
- Styles:
- Adjusted player container border radius overrides.
v1.0.15
- Styles:
- Removed default rounded corners and borders from VP Player to allow easier custom styling.
v1.0.14
- Features:
- Added support for backup playlist videos handling.
v1.0.13
- Fixes:
- Fixed video ID indexing issue in sliced playlists for vertical player.
v1.0.12
- Refactor:
- Reverted to original playlist configuration logic for better stability.
v1.0.11
- Fixes:
- Fixed logic regarding the removal of the first video from the playlist.
v1.0.10
- Features:
- Added TypeScript interfaces for tracks and
showCaptions.
- Added TypeScript interfaces for tracks and
- Fixes:
- Fixed video indexing and thumbnail display issues in vertical player.
v1.0.9
- Fixes:
- Ensure title and thumbnail are correctly applied to the first video in the playlist configuration.
v1.0.8
- Features:
- Improved player configuration builder.
- Fixes:
- Fixed playlist video index bug.
- Added functionality to start playlist from a specific index.
v1.0.7
- Fixes:
- Handled timeout issues in vertical player.
- Resolved all linting and TypeScript errors.
v1.0.6
- Fixes:
- Fixed TypeScript build errors.
v1.0.5
- Fixes:
- Fixed vertical player issue on page refresh.
- Removed unnecessary type assertions.
v1.0.4
- Fixes:
- Improved handling of vertical player video changes.
v1.0.0 - v1.0.3
- Initial Release:
- Core
VPPlayercomponent with support for:- Single video file playback.
- Playlist playback (file-based and API-based).
- Single video API fetching.
- Reels/Vertical mode.
- Added
useVPPlayerScriptanduseVideoDatahooks with retry and caching logic. - Unified error handling and configuration building.
- Added Storybook examples and comprehensive documentation.
- Core
