@ekg.training/ekg-video-player
v1.2.0
Published
EkgVideoPlayer is a customizable React-based video player library, bundled with Webpack. It supports both direct React integration and plain JavaScript usage.
Readme
@ekg.training/ekg-video-player
A customizable React-based video player library, supporting both React and plain JavaScript usage. Built on top of @vidstack/react.
Table of Contents
Installation
npm install @ekg.training/ekg-video-player
# or
yarn add @ekg.training/ekg-video-playerUsage
Below html is common and required for all examples, in which, evp-root class is neccessary to load tailwind styles used by the ekg video player
<div id="root" class="evp-root"></div>React
import { VideoPlayer } from '@ekg.training/ekg-video-player';
useEffect(() => {
const player = new VideoPlayer('root', { mediaPlayerProps: { src: '...', poster: '...' } });
player.init();
}, []);ESM (Browser)
<script src="https://unpkg.com/@ekg.training/ekg-video-player@latest/dist/ekg_video_player.bundle.js"></script>
<script type="module">
const player = new EkgVideoPlayer.VideoPlayer('root', {
mediaPlayerProps: { src: '...', poster: '...' },
});
player.init();
</script>UMD (Browser)
<script src="https://unpkg.com/@ekg.training/ekg-video-player@latest/dist/ekg_video_player.bundle.js"></script>
<script>
document.addEventListener('DOMContentLoaded', () => {
const player = new EkgVideoPlayer.VideoPlayer('root', {
mediaPlayerProps: { src: '...', poster: '...' },
});
player.init();
});
</script>Limitations
- No UI support for youtube videos.
Player Props Reference
The configuration object passed to new VideoPlayer('root', config) (standalone JS) or as props in React usage supports the following keys. The same structure is used in both approaches.
For a full working config, see examples/React/src/App.js for React usage, or examples/Javascript/main.js for plain JS usage.
Top-level Config Object
- mediaPlayerProps (object, required): Main video/audio player options (see below)
- posterProps (object, optional): Poster image options
- subtitleTracks (array, optional): Subtitle track objects (see below)
- chapterTracks (array, optional): Chapter track objects (see below)
- videoLayoutProps (object, optional): Video layout customization (see below)
- audioLayoutProps (object, optional): Audio layout customization
- videoWrapperProps (object, optional): Advanced wrapper options (see src/index.tsx)
- translations (object, optional): Custom UI translations
mediaPlayerProps (object)
src(string): Video/audio source URL (required)poster(string): Poster image URLtitle(string): Media titlerewindBy(number): Amount (seconds) to rewindclipStartTime(number): Start time for clipclipEndTime(number|null): End time for clipviewType(string): 'video' or 'audio'streamType(string): e.g. 'on-demand'logLevel(string): Logging levelcrossOrigin(boolean): Set crossorigin attributeplaysInline(boolean): Play inline on mobiletrackUserPreferences(boolean): Enable/disable tracking of user preferencesloop(boolean): Loop playbackonPause,onPlay,onPlaying,onLoopChange,onTimeUpdate,onLoad(function): Event handlers
posterProps (object)
src(string): Poster image URLalt(string): Alt textcrossOrigin(boolean): Set crossorigin attribute
subtitleTracks / chapterTracks (array)
Each track is an object with at least:
{
src: 'https://files.vidstack.io/sprite-fight/subs/english.vtt',
label: 'English',
language: 'en-US',
kind: 'subtitles' | 'chapters',
default: true // optional
}See examples/React/src/App.js or examples/Javascript/main.js for more examples.
videoLayoutProps (object)
thumbnails(object): Thumbnail visibillity & VTT file URL for thumbnailsplaybackRates(object):{ min, max, step }for playback speedhandouts(array): Downloadable handout objects ({ language, title, url })quizzes(array): Quiz objects (seeexamples/React/src/App.js)isSkipQuiz(boolean): Enable/disable quiz skipping Order in which factors are affecting visibility of quiz - 1. mediaPlayerProps.trackUserPreferences if this flag is true, then isSkipQuiz value in 'custom-pref-storage' localstorage 2. videoLayoutProps.isSkipQuiz 3. default is true (i.e Quiz will not be visible)isPseudoFullscreen(boolean): iOS fullscreen workaroundtoggleSkipQuiz,toggleIphoneFullScreen,toggleInfo(function): UI togglesisQuizOpen,isInfoOpen(boolean): UI statechapterTracks,subtitleTracks(array): Track arrays (see above)windowProps(object): Window size/orientationtranslations(object): UI translationsinfoLink(string): The link (image or video) to player information (e.g. instructions to use player)ecgLinks(string or array): Array of an ECG image links or url of single ECG image linkecgNotes(object):{ title, content }for ECG NotesallowPiP(boolean): Enable/disable availability of PIP feature
thumbnails (object)
showThumbnails(boolean): Enable/disable visibility of thumbnails over seek bar (default_value: true)customUrl(string): VTT file URLautoDetectThumbnail(boolean): Enable/disable feature of searching for VTT file in the same folder the video is present. (eg. video URL: https://storage.googleapis.com/muxdemofiles/mux.mp4, thumbnail URL: https://storage.googleapis.com/muxdemofiles/thumbnail/mux.vtt) (default_value: true)
audioLayoutProps (object)
Coming soon: Audio layout customization is not yet implemented.
videoWrapperProps (object)
Advanced options for wrapper (see [examples/React/src/App.js](https://github.com/close2realtraining/ekg-video-player/blob/main/examples/React/src/App.js) for example usage)translations (object)
The translations object allows you to customize UI text labels and messages. Available keys:
| Key | Description | | --------------------------- | ------------------------------------------- | | playInstruction | Message shown to rotate device to landscape | | playButtonLabel | Play button text | | continueButtonLabel | Continue video button text | | skipQuizButtonLabel | Skip quiz button text | | submitAnswerButtonLabel | Submit answer button text | | watchExplanationButtonLabel | Watch explanation button text | | settingsLabel | Settings menu label | | playbackSpeedLabel | Playback speed label | | customLabel | Custom speed label | | normalLabel | Normal speed label | | captionsLabel | Captions menu label | | playLabel | Play label | | pauseLabel | Pause label | | unmuteLabel | Unmute label | | muteLabel | Mute label | | showQuizLabel | Show quiz label | | skipQuizLabel | Skip quiz label | | closedCaptionsOffLabel | Closed captions off label | | closedCaptionsOnLabel | Closed captions on label | | exitPipLabel | Exit picture-in-picture label | | enterPipLabel | Enter picture-in-picture label | | exitFullscreenLabel | Exit fullscreen label | | enterFullscreenLabel | Enter fullscreen label | | downloadLabel | Download label | | downloadHandoutsLabel | Download handouts label | | allhandoutsDownloadedLabel | All handouts downloaded label | | chaptersLabel | Chapters label | | inVideoQuiz | In-video quiz label | | minLabel | Minutes label | | showInfoLabel | Show toolbar info label | | hideInfoLabel | Hide toolbar info label | | hideECGLabel | Hide ECG | | showECGLabel | Show ECG | | ekgGraphLabel | ECG | | openECGNotesLbl | Open Notes | | closeECGNotesLbl | Close Notes | | warningLabel | WARNING text | | slowInternetSpeedWarning | Slow internet speed warning | | popupBlockedWarning | Popup or redirects blocked warning | | pipBlockedWarning | PiP blocked warning | | thumbnailsLabel | Thumbnails | | onLabel | On | | offLabel | Off |
See examples/React/src/App.js and src/index.tsx for real-world usage.
ecgNotes (object)
Extended ECG Notes Format (With JSON-driven UI Support)
The ecgNotes.content field supports a dynamic JSON structure used by ContentDrivenUI.
Example supported keys inside content:
- text: WhatsApp-style rich text (
*bold*,_italic_,~strike~, code blocks, links,,) - html: Raw HTML rendered using
dangerouslySetInnerHTML - tabs: Array of tab objects (
{ id, label, content }) - accordion: Accordion sections (
{ head, content }) - content: Nested container enabling recursive structure (content → tabs → accordion → content → …)
Example:
{
"ecgNotes": {
"title": "ECG Interpretation Notes",
"content": {
"text": "*Bold text*, _italic_, and a link: https://example.com",
"html": "<div style='color:red'>Important alert</div>",
"tabs": [
{
"id": "tab1",
"label": "Overview",
"content": { "text": "Overview content" }
}
],
"accordion": {
"head": "Detailed Analysis",
"content": {
"text": "Nested details",
"html": "<span>More info</span>"
}
}
}
}
}WhatsApp-style Markup Table
| Format | Example | Output |
| ------------- | ------------ | ---------- |
| Bold | *text* | text |
| Italic | _text_ | text |
| Strikethrough | ~text~ | ~~text~~ |
| Inline Code | `code` | code |
| Newline | \n | line break |
| Tab | \t | 4 spaces |
Example 1 — Links
Check this: https://example.com
Or visit [Google](https://google.com)
Or [[https://openai.com|OpenAI]]Output: Check this: https://example.com Or visit Google Or OpenAI
Example 2 — Newlines & Tabs
Line 1\nLine 2\n\tIndented LineOutput:
Line 1
Line 2
Indented LineDocumentation & Examples
- See GitHub repository for full documentation, advanced usage, and examples.
- Example configs:
examples/React/src/App.js,examples/Javascript/main.js
License
Apache-2.0
