@ekg.training/ekg-video-player
v1.4.3
Published
EkgVideoPlayer is a customizable React-based video player library, bundled with Webpack. It supports both direct React integration and plain JavaScript usage.
Downloads
186
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 preferencessaveUserPreferences(function): Callback function with user preferences as an argument, which gets called whenever setting changes.userPreferences(object): User preference from databaseloop(boolean): Loop playbackonPause,onPlay,onPlaying,onLoopChange,onTimeUpdate,onLoad(function): Event handlers
userPreferences (object)
The order at which preference will be used,
- mediaPlayerProps.userPreferences object
- preference values stored in localstorage
- default values as per below table
ekg-video-storage(object): Preference object for custom features (eg. { thumbnails: true, isSkipQuiz: false })custom-pref-storage(object): Preference object for default features (eg. { volume: 0.38,muted: false, audioGain: null, lang: 'en-US', captions: true, rate: 0.8, quality: null })
Default behaviour of features if this object is not passed and not changed:
| Feature | Default Value | | -------------------- | ------------------------------- | | isSkipQuiz | true | | showThumbnails | true | | autoDetectThumbnail | true | | volume | 100% | | muted | false | | allowAnalytics | false | | allowPiP | false | | rewindBy | 3 | | clip | false | | loop | false | | trackUserPreferences | false | | playbackRates | { min: 0.5, max: 2, step: 0.1 } | | explanation_start | 0 | | captions | true |
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 featureallowAnalytics(boolean): Enable/disable Analytics to track user interaction with the video player by using AmplitudeamplitudeApiKey(string): API key for Amplitude
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) For this prop to work, It needs thumbnail vtt URL to be publically available.
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.
Amplitude for Product Analytics
cc_text_toggled(boolean): tracks whether closed captions (CC) are toggled on or off.thumbnail_toggled(boolean): tracks whether the thumbnail preview is toggled on or off.info_popup_toggled(boolean): tracks whether the info popup is opened or closed.in_vid_quiz_toggled(boolean): tracks whether in-video quizzes are toggled on or off.ecg_popup_toggled(boolean): tracks whether the ECG popup is opened or closed.ecg_notes_toggled(boolean): tracks whether ECG notes visibility is toggled on or off.chapter_popup_toggled(boolean): tracks whether the chapter popup is opened or closed.chapter_changed(string): tracks the name of the chapter the user switched to.pip_mode_toggled(boolean): tracks whether Picture-in-Picture (PiP) mode is toggled on or off.fullscreen_mode_toggled(boolean): tracks whether fullscreen mode is toggled on or off.handout_popup_toggled(boolean): tracks whether the handout popup is opened or closed.handout_file(string): tracks which handout file the user clicked.settings_popup_toggled(boolean): tracks whether the settings popup is opened or closed.playback_speed_changed(number): tracks the playback speed chosen by the user.volume_level_changed(number): tracks the volume level set by the user.
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
