myetv-player 1.1.4 → 1.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -0
- package/css/myetv-player.css +21 -0
- package/css/myetv-player.min.css +1 -1
- package/dist/myetv-player.js +158 -49
- package/dist/myetv-player.min.js +114 -29
- package/package.json +3 -1
- package/plugins/facebook/README.md +3 -0
- package/plugins/facebook/myetv-player-facebook-plugin.js +283 -17
- package/plugins/vimeo/README.md +3 -0
- package/plugins/vimeo/myetv-player-vimeo.js +556 -39
- package/plugins/youtube/README.md +7 -0
- package/plugins/youtube/myetv-player-youtube-plugin.js +817 -288
- package/scss/_controls.scss +21 -0
- package/src/controls.js +136 -32
- package/src/core.js +22 -17
package/scss/_controls.scss
CHANGED
|
@@ -165,3 +165,24 @@
|
|
|
165
165
|
.controls-right .brand-logo-link .brand-logo {
|
|
166
166
|
margin-right: 0;
|
|
167
167
|
}
|
|
168
|
+
|
|
169
|
+
/* Hide cursor when controlbar is hidden */
|
|
170
|
+
.video-wrapper.hide-cursor {
|
|
171
|
+
cursor: none !important;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/* Ensure cursor is visible on controls even when hide-cursor is active */
|
|
175
|
+
.video-wrapper.hide-cursor .controls {
|
|
176
|
+
cursor: default !important;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/* Ensure cursor is visible on buttons */
|
|
180
|
+
.video-wrapper.hide-cursor .control-btn {
|
|
181
|
+
cursor: pointer !important;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/* do not hide mouse on iframes */
|
|
185
|
+
.video-wrapper.hide-cursor iframe {
|
|
186
|
+
cursor: auto !important;
|
|
187
|
+
pointer-events: auto !important;
|
|
188
|
+
}
|
package/src/controls.js
CHANGED
|
@@ -85,6 +85,7 @@ initAutoHide() {
|
|
|
85
85
|
|
|
86
86
|
onMouseMoveInPlayer(e) {
|
|
87
87
|
this.showControlsNow();
|
|
88
|
+
this.showCursor();
|
|
88
89
|
this.resetAutoHideTimer();
|
|
89
90
|
}
|
|
90
91
|
|
|
@@ -142,66 +143,69 @@ resetAutoHideTimer() {
|
|
|
142
143
|
showControlsNow() {
|
|
143
144
|
if (this.controls) {
|
|
144
145
|
this.controls.classList.add('show');
|
|
145
|
-
}
|
|
146
146
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
147
|
+
// Add has-controls class to container (for watermark visibility)
|
|
148
|
+
if (this.container) {
|
|
149
|
+
this.container.classList.add('has-controls');
|
|
150
|
+
}
|
|
151
|
+
|
|
150
152
|
this.updateControlbarHeight();
|
|
153
|
+
|
|
151
154
|
// Update watermark position
|
|
152
155
|
if (this.updateWatermarkPosition) {
|
|
153
156
|
this.updateWatermarkPosition();
|
|
154
157
|
}
|
|
155
|
-
}
|
|
156
158
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
159
|
+
// Show title overlay with controls (if not persistent)
|
|
160
|
+
if (this.options.showTitleOverlay && !this.options.persistentTitle && this.options.videoTitle) {
|
|
161
|
+
this.showTitleOverlay();
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// *show cursor when controls are shown*
|
|
165
|
+
this.showCursor();
|
|
161
166
|
|
|
162
|
-
|
|
167
|
+
if (this.autoHideDebug && this.options.debug) console.log('✅ Controls shown');
|
|
168
|
+
}
|
|
163
169
|
}
|
|
164
170
|
|
|
165
171
|
hideControlsNow() {
|
|
166
|
-
//
|
|
172
|
+
// Dont hide if mouse is still over controls (allow hiding on touch devices)
|
|
167
173
|
const isTouchDevice = 'ontouchstart' in window || navigator.maxTouchPoints > 0;
|
|
168
|
-
|
|
169
174
|
if (this.mouseOverControls && !isTouchDevice) {
|
|
170
|
-
if (this.autoHideDebug && this.options.debug)
|
|
171
|
-
console.log('🚫 Not hiding - mouse still over controls');
|
|
172
|
-
}
|
|
175
|
+
if (this.autoHideDebug && this.options.debug) console.log('❌ Not hiding - mouse still over controls');
|
|
173
176
|
return;
|
|
174
177
|
}
|
|
175
178
|
|
|
176
|
-
//
|
|
179
|
+
// Dont hide if video is paused
|
|
177
180
|
if (this.video && this.video.paused) {
|
|
178
|
-
if (this.autoHideDebug && this.options.debug)
|
|
179
|
-
console.log('🚫 Not hiding - video is paused');
|
|
180
|
-
}
|
|
181
|
+
if (this.autoHideDebug && this.options.debug) console.log('❌ Not hiding - video is paused');
|
|
181
182
|
return;
|
|
182
183
|
}
|
|
183
184
|
|
|
184
185
|
if (this.controls) {
|
|
185
186
|
this.controls.classList.remove('show');
|
|
186
187
|
|
|
187
|
-
// Remove has-controls class from container for watermark visibility
|
|
188
|
+
// Remove has-controls class from container (for watermark visibility)
|
|
188
189
|
if (this.container) {
|
|
189
190
|
this.container.classList.remove('has-controls');
|
|
190
|
-
this.updateControlbarHeight();
|
|
191
|
-
// Update watermark position
|
|
192
|
-
if (this.updateWatermarkPosition) {
|
|
193
|
-
this.updateWatermarkPosition();
|
|
194
|
-
}
|
|
195
191
|
}
|
|
196
|
-
}
|
|
197
192
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
193
|
+
this.updateControlbarHeight();
|
|
194
|
+
|
|
195
|
+
// Update watermark position
|
|
196
|
+
if (this.updateWatermarkPosition) {
|
|
197
|
+
this.updateWatermarkPosition();
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Hide title overlay with controls (if not persistent)
|
|
201
|
+
if (this.options.showTitleOverlay && !this.options.persistentTitle) {
|
|
202
|
+
this.hideTitleOverlay();
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// *hide cursor after controls are hidden*
|
|
206
|
+
this.hideCursor();
|
|
202
207
|
|
|
203
|
-
|
|
204
|
-
console.log('👁️ Controls hidden');
|
|
208
|
+
if (this.autoHideDebug && this.options.debug) console.log('✅ Controls hidden');
|
|
205
209
|
}
|
|
206
210
|
}
|
|
207
211
|
|
|
@@ -225,6 +229,52 @@ clearControlsTimeout() {
|
|
|
225
229
|
}
|
|
226
230
|
}
|
|
227
231
|
|
|
232
|
+
// Default controlbar styles injection
|
|
233
|
+
injectDefaultControlbarStyles() {
|
|
234
|
+
if (document.getElementById('default-controlbar-styles')) {
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
const controlBarOpacity = Math.max(0, Math.min(1, this.options.controlBarOpacity));
|
|
239
|
+
const titleOverlayOpacity = Math.max(0, Math.min(1, this.options.titleOverlayOpacity));
|
|
240
|
+
|
|
241
|
+
const style = document.createElement('style');
|
|
242
|
+
style.id = 'default-controlbar-styles';
|
|
243
|
+
style.textContent = `
|
|
244
|
+
.video-wrapper:not(.youtube-active):not(.vimeo-active):not(.facebook-active) .controls {
|
|
245
|
+
background: linear-gradient(
|
|
246
|
+
to top,
|
|
247
|
+
rgba(0, 0, 0, ${controlBarOpacity}) 0%,
|
|
248
|
+
rgba(0, 0, 0, ${controlBarOpacity * 0.89}) 20%,
|
|
249
|
+
rgba(0, 0, 0, ${controlBarOpacity * 0.74}) 40%,
|
|
250
|
+
rgba(0, 0, 0, ${controlBarOpacity * 0.53}) 60%,
|
|
251
|
+
rgba(0, 0, 0, ${controlBarOpacity * 0.32}) 80%,
|
|
252
|
+
rgba(0, 0, 0, ${controlBarOpacity * 0.21}) 100%
|
|
253
|
+
);
|
|
254
|
+
backdrop-filter: blur(3px);
|
|
255
|
+
min-height: 60px;
|
|
256
|
+
padding-bottom: 10px;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
.video-wrapper:not(.youtube-active):not(.vimeo-active):not(.facebook-active) .title-overlay {
|
|
260
|
+
background: linear-gradient(
|
|
261
|
+
to bottom,
|
|
262
|
+
rgba(0, 0, 0, ${titleOverlayOpacity}) 0%,
|
|
263
|
+
rgba(0, 0, 0, ${titleOverlayOpacity * 0.89}) 20%,
|
|
264
|
+
rgba(0, 0, 0, ${titleOverlayOpacity * 0.74}) 40%,
|
|
265
|
+
rgba(0, 0, 0, ${titleOverlayOpacity * 0.53}) 60%,
|
|
266
|
+
rgba(0, 0, 0, ${titleOverlayOpacity * 0.32}) 80%,
|
|
267
|
+
rgba(0, 0, 0, ${titleOverlayOpacity * 0.21}) 100%
|
|
268
|
+
);
|
|
269
|
+
backdrop-filter: blur(3px);
|
|
270
|
+
min-height: 80px;
|
|
271
|
+
padding-top: 20px;
|
|
272
|
+
}
|
|
273
|
+
`;
|
|
274
|
+
|
|
275
|
+
document.head.appendChild(style);
|
|
276
|
+
}
|
|
277
|
+
|
|
228
278
|
// Debug methods
|
|
229
279
|
enableAutoHideDebug() {
|
|
230
280
|
this.autoHideDebug = true;
|
|
@@ -1067,6 +1117,60 @@ isAutoHideInitialized() {
|
|
|
1067
1117
|
return this.autoHideInitialized;
|
|
1068
1118
|
}
|
|
1069
1119
|
|
|
1120
|
+
/**
|
|
1121
|
+
* Hide mouse cursor in player container
|
|
1122
|
+
* Only hides cursor in main container, not in plugin iframes
|
|
1123
|
+
*/
|
|
1124
|
+
hideCursor() {
|
|
1125
|
+
if (!this.options.hideCursor) {
|
|
1126
|
+
return; // Do not hide cursor if option is disabled
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
if (this.container) {
|
|
1130
|
+
this.container.classList.add('hide-cursor');
|
|
1131
|
+
if (this.options.debug) console.log('🖱️ Cursor hidden');
|
|
1132
|
+
}
|
|
1133
|
+
}
|
|
1134
|
+
|
|
1135
|
+
/**
|
|
1136
|
+
* Show mouse cursor in player container
|
|
1137
|
+
*/
|
|
1138
|
+
showCursor() {
|
|
1139
|
+
if (this.container) {
|
|
1140
|
+
this.container.classList.remove('hide-cursor');
|
|
1141
|
+
if (this.options.debug) console.log('🖱️ Cursor shown');
|
|
1142
|
+
}
|
|
1143
|
+
}
|
|
1144
|
+
|
|
1145
|
+
/**
|
|
1146
|
+
* Enable cursor hiding when controlbar is hidden
|
|
1147
|
+
* @returns {Object} this
|
|
1148
|
+
*/
|
|
1149
|
+
enableCursorHiding() {
|
|
1150
|
+
this.options.hideCursor = true;
|
|
1151
|
+
if (this.options.debug) console.log('Cursor hiding enabled');
|
|
1152
|
+
return this;
|
|
1153
|
+
}
|
|
1154
|
+
|
|
1155
|
+
/**
|
|
1156
|
+
* Disable cursor hiding - cursor will always be visible
|
|
1157
|
+
* @returns {Object} this
|
|
1158
|
+
*/
|
|
1159
|
+
disableCursorHiding() {
|
|
1160
|
+
this.options.hideCursor = false;
|
|
1161
|
+
this.showCursor(); // Ensure cursor is shown immediately
|
|
1162
|
+
if (this.options.debug) console.log('Cursor hiding disabled');
|
|
1163
|
+
return this;
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1166
|
+
/**
|
|
1167
|
+
* Check if cursor hiding is enabled
|
|
1168
|
+
* @returns {Boolean} True if cursor hiding is enabled
|
|
1169
|
+
*/
|
|
1170
|
+
isCursorHidingEnabled() {
|
|
1171
|
+
return this.options.hideCursor;
|
|
1172
|
+
}
|
|
1173
|
+
|
|
1070
1174
|
/* PLAYLIST CONTROLS */
|
|
1071
1175
|
showPlaylistControls() {
|
|
1072
1176
|
if (!this.playlistPrevBtn || !this.playlistNextBtn) return;
|
package/src/core.js
CHANGED
|
@@ -12,22 +12,25 @@ constructor(videoElement, options = {}) {
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
this.options = {
|
|
15
|
-
showQualitySelector: true,
|
|
16
|
-
showSpeedControl: true,
|
|
17
|
-
showFullscreen: true,
|
|
18
|
-
showPictureInPicture: true,
|
|
19
|
-
showSubtitles: true,
|
|
20
|
-
subtitlesEnabled: false,
|
|
21
|
-
autoHide: true,
|
|
22
|
-
autoHideDelay: 3000,
|
|
15
|
+
showQualitySelector: true, // Enable quality selector button
|
|
16
|
+
showSpeedControl: true, // Enable speed control button
|
|
17
|
+
showFullscreen: true, // Enable fullscreen button
|
|
18
|
+
showPictureInPicture: true, // Enable PiP button
|
|
19
|
+
showSubtitles: true, // Enable subtitles button
|
|
20
|
+
subtitlesEnabled: false, // Enable subtitles by default if available
|
|
21
|
+
autoHide: true, // auto-hide controls when idle
|
|
22
|
+
autoHideDelay: 3000, // hide controls after ... seconds of inactivity (specificed in milliseconds)
|
|
23
|
+
hideCursor: true, // hide mouse cursor when idle
|
|
23
24
|
poster: null, // URL of poster image
|
|
24
25
|
showPosterOnEnd: false, // Show poster again when video ends
|
|
25
|
-
keyboardControls: true,
|
|
26
|
-
showSeekTooltip: true,
|
|
27
|
-
showTitleOverlay: false,
|
|
28
|
-
videoTitle: '',
|
|
29
|
-
videoSubtitle: '',
|
|
30
|
-
persistentTitle: false,
|
|
26
|
+
keyboardControls: true, // Enable keyboard controls
|
|
27
|
+
showSeekTooltip: true, // Show tooltip on seek bar at mouse hover
|
|
28
|
+
showTitleOverlay: false, // Show video title overlay
|
|
29
|
+
videoTitle: '', // Title text to show in overlay
|
|
30
|
+
videoSubtitle: '', // Subtitle text to show in overlay
|
|
31
|
+
persistentTitle: false, // If true, title overlay stays visible
|
|
32
|
+
controlBarOpacity: options.controlBarOpacity !== undefined ? options.controlBarOpacity : 0.95, // Opacity of control bar (0.0 to 1.0)
|
|
33
|
+
titleOverlayOpacity: options.titleOverlayOpacity !== undefined ? options.titleOverlayOpacity : 0.95, // Opacity of title overlay (0.0 to 1.0)
|
|
31
34
|
debug: false, // Enable/disable debug logging
|
|
32
35
|
autoplay: false, // if video should autoplay at start
|
|
33
36
|
defaultQuality: 'auto', // 'auto', '1080p', '720p', '480p', etc.
|
|
@@ -57,8 +60,8 @@ constructor(videoElement, options = {}) {
|
|
|
57
60
|
//seek shape
|
|
58
61
|
seekHandleShape: 'circle', // Available shape: none, circle, square, diamond, arrow, triangle, heart, star
|
|
59
62
|
// AUDIO PLAYER
|
|
60
|
-
audiofile: false,
|
|
61
|
-
audiowave: false,
|
|
63
|
+
audiofile: false, // if true, adapt player to audio file (hide video element)
|
|
64
|
+
audiowave: false, // if true, show audio wave visualization (Web Audio API)
|
|
62
65
|
// RESOLUTION CONTROL
|
|
63
66
|
resolution: "normal", // "normal", "4:3", "16:9", "stretched", "fit-to-screen", "scale-to-fit"
|
|
64
67
|
...options
|
|
@@ -168,7 +171,9 @@ constructor(videoElement, options = {}) {
|
|
|
168
171
|
};
|
|
169
172
|
|
|
170
173
|
this.lastTimeUpdate = 0; // For throttling timeupdate events
|
|
171
|
-
|
|
174
|
+
// Inject default styles
|
|
175
|
+
this.injectDefaultControlbarStyles();
|
|
176
|
+
// Set language if specified
|
|
172
177
|
if (this.options.language && this.isI18nAvailable()) {
|
|
173
178
|
VideoPlayerTranslations.setLanguage(this.options.language);
|
|
174
179
|
}
|