@halibegic/react-video-player
v0.0.63
Published
A React video player library with HLS support for VOD and Live streaming
Maintainers
Readme
React Video Player
A React video player supporting HLS protocol for VOD / live streaming.
Installation
npm install @halibegic/react-video-playerUsage
Important: You need to import the CSS file for the player styles to work correctly.
Next.js
In your _app.js or _app.tsx:
import "@halibegic/react-video-player/style.css";Other React Applications
import "@halibegic/react-video-player/style.css";VOD Player
import "@halibegic/react-video-player/style.css";
import { VodPlayer } from "@halibegic/react-video-player";
function App() {
return <VodPlayer url="https://example.com/vod.m3u8" />;
}| Prop | Type | Description | Default |
| ----------- | ---------------------------------------- | ------------------------------------------------------------ | ------- |
| url | string | The vod stream URL | - |
| chaptersURL | string | (Optional) URL to a WebVTT (.vtt) file describing chapters | - |
| startTime | number | (Optional) Start time in seconds to begin playback from | - |
| messages | { unableToPlay?: string } | (Optional) Custom message for unable to play errors | - |
| onEvent | (event: string, data: unknown) => void | (Optional) Event handler callback for player events | - |
Example with chaptersURL:
import "@halibegic/react-video-player/style.css";
import { VodPlayer } from "@halibegic/react-video-player";
function App() {
return (
<VodPlayer
url="https://example.com/vod.m3u8"
chaptersURL="https://example.com/chapters.vtt"
/>
);
}When a chaptersURL is provided, the player fetches and parses the WebVTT file
and enables chapter features: the seek bar is split into chapter sections, the
hover tooltip shows the chapter title above the time, the current chapter name is
shown next to the duration, and a chapters dropdown is added to the controls for
jumping between chapters. The chapter UI stays hidden if the file is missing,
empty, or fails to load.
The expected WebVTT format (the cue text is used as the chapter title):
WEBVTT
00:00:00.000 --> 00:00:30.000
Introduction
00:00:30.000 --> 00:01:30.000
The SpritesExample with startTime:
import "@halibegic/react-video-player/style.css";
import { VodPlayer } from "@halibegic/react-video-player";
function App() {
return <VodPlayer url="https://example.com/vod.m3u8" startTime={10} />;
}Example with custom unableToPlay message:
import "@halibegic/react-video-player/style.css";
import { VodPlayer } from "@halibegic/react-video-player";
function App() {
return (
<VodPlayer
url="https://example.com/vod.m3u8"
messages={{
unableToPlay: "Video cannot be played. Please try again later.",
}}
/>
);
}Live Player
import "@halibegic/react-video-player/style.css";
import { LivePlayer } from "@halibegic/react-video-player";
function App() {
return (
<LivePlayer
url="https://example.com/live.m3u8"
messages={{
eventNotStarted: "Live stream još nije počeo. Molimo pričekajte.",
eventFinished: "Live stream je završen.",
eventStartingSoon: "Počinje za nekoliko sekundi...",
live: "Uživo",
unableToPlay:
"Stream ne može biti reprodukovan. Molimo pokušajte kasnije.",
}}
/>
);
}| Prop | Type | Description | Default |
| ---------- | ----------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| url | string | The live stream URL | - |
| onEvent | (event: string, data: unknown) => void | (Optional) Event handler callback for player events | - |
| messages | { eventNotStarted: string; eventFinished: string; eventStartingSoon?: string; live?: string; unableToPlay?: string; } | (Optional) Custom messages for event not started, finished, starting soon, live states, and unable to play errors | { eventNotStarted: "Event has not started yet.", eventFinished: "Event has finished.", eventStartingSoon: "Starting soon...", live: "Live" } |
Keyboard Shortcuts
The video player supports the following keyboard shortcuts:
| Key | Action | Description |
| ----------------- | ------------- | ----------------------------- |
| Space | Play/Pause | Toggle between play and pause |
| ← (Left Arrow) | Seek Backward | Jump back 10 seconds |
| → (Right Arrow) | Seek Forward | Jump forward 10 seconds |
| ↑ (Up Arrow) | Volume Up | Increase volume by 10% |
| ↓ (Down Arrow) | Volume Down | Decrease volume by 10% |
| M | Mute/Unmute | Toggle mute (0% ↔ 100%) |
| F | Fullscreen | Toggle fullscreen mode |
Events
Both VodPlayer and LivePlayer support event handling through the onEvent prop. This allows you to listen to various player events and respond accordingly.
Event Types
| Event Name | Data Type | Description |
| ------------------ | ------------------------------------------- | ----------------------------------------------------- |
| play | void | Fired when playback starts |
| pause | void | Fired when playback is paused |
| ended | void | Fired when playback reaches the end |
| seeking | void | Fired when seeking starts |
| seeked | void | Fired when seeking is complete |
| timeUpdate | { currentTime: number; duration: number } | Fired during playback with current time and duration |
| volumeChange | { volume: number } | Fired when volume changes (0-1) |
| fullscreenChange | { isFullscreen: boolean } | Fired when fullscreen mode changes |
| qualityChange | { level: string \| null } | Fired when video quality changes |
| loadedMetadata | { duration: number } | Fired when video metadata is loaded |
| loadStart | void | Fired when loading starts |
| playing | void | Fired when playback actually starts (after buffering) |
| waiting | void | Fired when playback is waiting for data |
| error | unknown | Fired when an error occurs |
Usage Examples
VOD Player with Events
import "@halibegic/react-video-player/style.css";
import { VodPlayer } from "@halibegic/react-video-player";
function App() {
const handlePlayerEvent = (event: string, data: unknown) => {
switch (event) {
case "play":
console.log("Play");
break;
case "pause":
console.log("Pause");
break;
case "timeUpdate":
const { currentTime, duration } = data as {
currentTime: number;
duration: number;
};
console.log(
`Progress: ${((currentTime / duration) * 100).toFixed(1)}%`
);
break;
case "volumeChange":
const { volume } = data as { volume: number };
console.log(`Volume changed to: ${(volume * 100).toFixed(0)}%`);
break;
case "fullscreenChange":
const { isFullscreen } = data as { isFullscreen: boolean };
console.log(`Fullscreen: ${isFullscreen ? "ON" : "OFF"}`);
break;
case "error":
console.error("Player error:", data);
break;
}
};
return (
<VodPlayer url="https://example.com/vod.m3u8" onEvent={handlePlayerEvent} />
);
}Live Player with Events
import "@halibegic/react-video-player/style.css";
import { LivePlayer } from "@halibegic/react-video-player";
function App() {
const handlePlayerEvent = (event: string, data: unknown) => {
switch (event) {
case "play":
console.log("Play");
break;
case "pause":
console.log("Pause");
break;
}
};
return (
<LivePlayer
url="https://example.com/live.m3u8"
onEvent={handlePlayerEvent}
/>
);
}Development
# Install dependencies
npm install
# Start development server
npm run dev
# Build library
npm run build
# Lint code
npm run lintLicense
MIT © halibegic
Note
This is a closed, private development project.
