myetv-player 1.0.6 → 1.0.10

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.
@@ -435,6 +435,8 @@ constructor(videoElement, options = {}) {
435
435
  hlsLibUrl: 'https://cdn.jsdelivr.net/npm/hls.js@latest',
436
436
  adaptiveQualityControl: true,
437
437
 
438
+ seekHandleShape: 'circle',
439
+
438
440
  audiofile: false,
439
441
  audiowave: false,
440
442
 
@@ -1508,14 +1510,19 @@ seek(e) {
1508
1510
  if (!this.video || !this.progressContainer || !this.progressFilled || !this.progressHandle || this.isChangingQuality) return;
1509
1511
 
1510
1512
  const rect = this.progressContainer.getBoundingClientRect();
1511
- const clickX = e.clientX - rect.left;
1513
+
1514
+
1515
+ const clientX = e.clientX !== undefined ? e.clientX : (e.touches && e.touches[0] ? e.touches[0].clientX : (e.changedTouches && e.changedTouches[0] ? e.changedTouches[0].clientX : 0));
1516
+
1517
+ const clickX = clientX - rect.left;
1512
1518
  const percentage = Math.max(0, Math.min(1, clickX / rect.width));
1513
1519
 
1514
1520
  if (this.video.duration && !isNaN(this.video.duration)) {
1515
1521
  this.video.currentTime = percentage * this.video.duration;
1516
- const progress = percentage * 100;
1517
- this.progressFilled.style.width = progress + '%';
1518
- this.progressHandle.style.left = progress + '%';
1522
+
1523
+ const progress = `${percentage * 100}%`;
1524
+ this.progressFilled.style.width = progress;
1525
+ this.progressHandle.style.left = progress;
1519
1526
  }
1520
1527
  }
1521
1528
 
@@ -2038,6 +2045,41 @@ loadScript(src) {
2038
2045
  });
2039
2046
  }
2040
2047
 
2048
+
2049
+ setSeekHandleShape(shape) {
2050
+ const validShapes = ['none', 'circle', 'square', 'diamond', 'arrow', 'triangle', 'heart', 'star'];
2051
+
2052
+ if (!validShapes.includes(shape)) {
2053
+ if (this.options.debug) console.warn('Invalid seek handle shape:', shape);
2054
+ return this;
2055
+ }
2056
+
2057
+ this.options.seekHandleShape = shape;
2058
+
2059
+
2060
+ if (this.progressHandle) {
2061
+
2062
+ validShapes.forEach(s => {
2063
+ this.progressHandle.classList.remove(`progress-handle-${s}`);
2064
+ });
2065
+
2066
+ this.progressHandle.classList.add(`progress-handle-${shape}`);
2067
+ }
2068
+
2069
+ if (this.options.debug) console.log('Seek handle shape changed to:', shape);
2070
+ return this;
2071
+ }
2072
+
2073
+
2074
+ getSeekHandleShape() {
2075
+ return this.options.seekHandleShape;
2076
+ }
2077
+
2078
+
2079
+ getAvailableSeekHandleShapes() {
2080
+ return ['none', 'circle', 'square', 'diamond', 'arrow', 'triangle', 'heart', 'star'];
2081
+ }
2082
+
2041
2083
  dispose() {
2042
2084
  if (this.qualityMonitorInterval) {
2043
2085
  clearInterval(this.qualityMonitorInterval);
@@ -2392,12 +2434,28 @@ addEventListener(eventType, callback) {
2392
2434
  });
2393
2435
  }
2394
2436
 
2395
- if (this.progressContainer) {
2396
- this.progressContainer.addEventListener('click', (e) => this.seek(e));
2397
- this.progressContainer.addEventListener('mousedown', (e) => this.startSeeking(e));
2398
- }
2437
+ if (this.progressContainer) {
2438
+
2439
+ this.progressContainer.addEventListener('click', (e) => this.seek(e));
2440
+ this.progressContainer.addEventListener('mousedown', (e) => this.startSeeking(e));
2441
+
2442
+
2443
+ this.progressContainer.addEventListener('touchstart', (e) => {
2444
+ e.preventDefault();
2445
+ this.startSeeking(e);
2446
+ }, { passive: false });
2399
2447
 
2400
2448
  this.setupSeekTooltip();
2449
+ }
2450
+
2451
+
2452
+ if (this.progressHandle) {
2453
+ this.progressHandle.addEventListener('touchstart', (e) => {
2454
+ e.preventDefault();
2455
+ e.stopPropagation();
2456
+ this.startSeeking(e);
2457
+ }, { passive: false });
2458
+ }
2401
2459
 
2402
2460
 
2403
2461
 
@@ -2418,7 +2476,19 @@ addEventListener(eventType, callback) {
2418
2476
  document.addEventListener('mozfullscreenchange', () => this.updateFullscreenButton());
2419
2477
 
2420
2478
  document.addEventListener('mousemove', (e) => this.continueSeeking(e));
2421
- document.addEventListener('mouseup', () => this.endSeeking());
2479
+ document.addEventListener('mouseup', () => this.endSeeking());
2480
+
2481
+
2482
+ document.addEventListener('touchmove', (e) => {
2483
+ if (this.isUserSeeking) {
2484
+ e.preventDefault();
2485
+ this.continueSeeking(e);
2486
+ }
2487
+ }, { passive: false });
2488
+
2489
+ document.addEventListener('touchend', () => this.endSeeking());
2490
+ document.addEventListener('touchcancel', () => this.endSeeking());
2491
+
2422
2492
  }
2423
2493
 
2424
2494
 
@@ -2566,6 +2636,11 @@ showControlsNow() {
2566
2636
 
2567
2637
  if (this.container) {
2568
2638
  this.container.classList.add('has-controls');
2639
+ this.updateControlbarHeight();
2640
+
2641
+ if (this.updateWatermarkPosition) {
2642
+ this.updateWatermarkPosition();
2643
+ }
2569
2644
  }
2570
2645
 
2571
2646
 
@@ -2579,24 +2654,34 @@ showControlsNow() {
2579
2654
  hideControlsNow() {
2580
2655
 
2581
2656
  const isTouchDevice = 'ontouchstart' in window || navigator.maxTouchPoints > 0;
2657
+
2582
2658
  if (this.mouseOverControls && !isTouchDevice) {
2583
- if (this.autoHideDebug && this.options.debug) console.log('⏸️ Not hiding - mouse still over controls');
2659
+ if (this.autoHideDebug && this.options.debug) {
2660
+ console.log('🚫 Not hiding - mouse still over controls');
2661
+ }
2584
2662
  return;
2585
2663
  }
2586
2664
 
2587
2665
 
2588
2666
  if (this.video && this.video.paused) {
2589
- if (this.autoHideDebug && this.options.debug) console.log('⏸️ Not hiding - video is paused');
2667
+ if (this.autoHideDebug && this.options.debug) {
2668
+ console.log('🚫 Not hiding - video is paused');
2669
+ }
2590
2670
  return;
2591
2671
  }
2592
2672
 
2593
2673
  if (this.controls) {
2594
2674
  this.controls.classList.remove('show');
2595
- }
2596
2675
 
2597
-
2598
- if (this.container) {
2599
- this.container.classList.remove('has-controls');
2676
+
2677
+ if (this.container) {
2678
+ this.container.classList.remove('has-controls');
2679
+ this.updateControlbarHeight();
2680
+
2681
+ if (this.updateWatermarkPosition) {
2682
+ this.updateWatermarkPosition();
2683
+ }
2684
+ }
2600
2685
  }
2601
2686
 
2602
2687
 
@@ -2604,7 +2689,9 @@ hideControlsNow() {
2604
2689
  this.hideTitleOverlay();
2605
2690
  }
2606
2691
 
2607
- if (this.autoHideDebug && this.options.debug) console.log('❌ Controls hidden');
2692
+ if (this.autoHideDebug && this.options.debug) {
2693
+ console.log('👁️ Controls hidden');
2694
+ }
2608
2695
  }
2609
2696
 
2610
2697
  showControls() {
@@ -2772,7 +2859,7 @@ createControls() {
2772
2859
  <div class="progress-bar">
2773
2860
  <div class="progress-buffer"></div>
2774
2861
  <div class="progress-filled"></div>
2775
- <div class="progress-handle"></div>
2862
+ <div class="progress-handle progress-handle-${this.options.seekHandleShape}"></div>
2776
2863
  </div>
2777
2864
  ${this.options.showSeekTooltip ? '<div class="seek-tooltip">0:00</div>' : ''}
2778
2865
  </div>
@@ -2882,6 +2969,7 @@ createControls() {
2882
2969
 
2883
2970
  setTimeout(() => {
2884
2971
  this.initializeResponsiveMenu();
2972
+ this.updateControlbarHeight();
2885
2973
  }, 100);
2886
2974
  }
2887
2975
 
@@ -2895,14 +2983,46 @@ initializeResponsiveMenu() {
2895
2983
 
2896
2984
  this.checkScreenSize();
2897
2985
 
2898
- window.addEventListener('resize', () => {
2986
+
2987
+ const resizeHandler = () => {
2899
2988
  this.checkScreenSize();
2900
- });
2989
+ this.updateControlbarHeight();
2990
+ };
2991
+
2992
+
2993
+ this.resizeHandler = resizeHandler.bind(this);
2994
+ window.addEventListener('resize', this.resizeHandler);
2901
2995
 
2902
2996
 
2903
2997
  this.bindSettingsMenuEvents();
2904
2998
  }
2905
2999
 
3000
+ updateControlbarHeight() {
3001
+ if (!this.controls) return;
3002
+
3003
+ const height = this.controls.offsetHeight;
3004
+ if (this.container) {
3005
+
3006
+ this.container.style.setProperty('--player-controls-height', `${height}px`);
3007
+
3008
+ const watermark = this.container.querySelector('.video-watermark.watermark-bottomleft, .video-watermark.watermark-bottomright');
3009
+ if (watermark) {
3010
+ const hasControls = this.container.classList.contains('has-controls');
3011
+ const isHideOnAutoHide = watermark.classList.contains('hide-on-autohide');
3012
+
3013
+ if (hasControls || !isHideOnAutoHide) {
3014
+ watermark.style.bottom = `${height + 15}px`;
3015
+ } else {
3016
+ watermark.style.bottom = '15px';
3017
+ }
3018
+ }
3019
+ }
3020
+
3021
+ if (this.options.debug) {
3022
+ console.log(`Controlbar height updated: ${height}px`);
3023
+ }
3024
+ }
3025
+
2906
3026
 
2907
3027
  getResponsiveThreshold() {
2908
3028
 
@@ -2922,7 +3042,7 @@ checkScreenSize() {
2922
3042
  this.updateSettingsMenuVisibility();
2923
3043
 
2924
3044
  if (this.options.debug) {
2925
- console.log(`Screen check: ${window.innerWidth}px vs ${threshold}px threshold (logo: ${this.options.brandLogoEnabled}), small: ${this.isSmallScreen}`);
3045
+ console.log(`Screen check: ${window.innerWidth}px vs ${threshold}px (threshold), logo: ${this.options.brandLogoEnabled}, small: ${this.isSmallScreen}`);
2926
3046
  }
2927
3047
  }
2928
3048
  }
@@ -5584,8 +5704,18 @@ initializeWatermark() {
5584
5704
  }
5585
5705
 
5586
5706
 
5707
+
5587
5708
  this.watermarkElement = watermark;
5588
5709
 
5710
+
5711
+ this.updateWatermarkPosition();
5712
+
5713
+
5714
+ this.watermarkResizeHandler = () => {
5715
+ this.updateWatermarkPosition();
5716
+ };
5717
+ window.addEventListener('resize', this.watermarkResizeHandler);
5718
+
5589
5719
  if (this.options.debug) {
5590
5720
  console.log('🏷️ Watermark created:', {
5591
5721
  url: this.options.watermarkUrl,
@@ -5598,6 +5728,7 @@ initializeWatermark() {
5598
5728
  }
5599
5729
 
5600
5730
 
5731
+
5601
5732
  setWatermark(url, link = '', position = 'bottomright', title = '') {
5602
5733
 
5603
5734
  this.options.watermarkUrl = url;
@@ -5626,6 +5757,12 @@ removeWatermark() {
5626
5757
  this.watermarkElement = null;
5627
5758
  }
5628
5759
 
5760
+
5761
+ if (this.watermarkResizeHandler) {
5762
+ window.removeEventListener('resize', this.watermarkResizeHandler);
5763
+ this.watermarkResizeHandler = null;
5764
+ }
5765
+
5629
5766
  this.options.watermarkUrl = '';
5630
5767
  this.options.watermarkLink = '';
5631
5768
  this.options.watermarkPosition = 'bottomright';
@@ -5637,6 +5774,7 @@ removeWatermark() {
5637
5774
  }
5638
5775
 
5639
5776
 
5777
+
5640
5778
  setWatermarkPosition(position) {
5641
5779
  if (!['topleft', 'topright', 'bottomleft', 'bottomright'].includes(position)) {
5642
5780
  if (this.options.debug) console.warn('🏷️ Invalid watermark position:', position);
@@ -5664,6 +5802,36 @@ setWatermarkPosition(position) {
5664
5802
  }
5665
5803
 
5666
5804
 
5805
+ updateWatermarkPosition() {
5806
+ if (!this.watermarkElement) return;
5807
+ if (!this.controls) return;
5808
+
5809
+ const position = this.options.watermarkPosition || 'bottomright';
5810
+
5811
+
5812
+ if (position === 'bottomleft' || position === 'bottomright') {
5813
+ const controlsHeight = this.controls.offsetHeight;
5814
+ const spacing = 15;
5815
+ const bottomValue = controlsHeight + spacing;
5816
+
5817
+
5818
+ const hasControls = this.container.classList.contains('has-controls');
5819
+
5820
+ if (hasControls || !this.options.hideWatermark) {
5821
+
5822
+ this.watermarkElement.style.bottom = `${bottomValue}px`;
5823
+ } else {
5824
+
5825
+ this.watermarkElement.style.bottom = '15px';
5826
+ }
5827
+
5828
+ if (this.options.debug) {
5829
+ console.log(`🏷️ Watermark position updated: bottom ${this.watermarkElement.style.bottom}`);
5830
+ }
5831
+ }
5832
+ }
5833
+
5834
+
5667
5835
  setWatermarkAutoHide(hide) {
5668
5836
  this.options.hideWatermark = hide;
5669
5837
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "myetv-player",
3
- "version": "1.0.6",
3
+ "version": "1.0.10",
4
4
  "description": "MYETV Video Player - Modular JavaScript and SCSS Build System",
5
5
  "main": "dist/myetv-player.js",
6
6
  "scripts": {
@@ -30,3 +30,5 @@
30
30
 
31
31
 
32
32
 
33
+
34
+
@@ -117,7 +117,13 @@ const player = new MYETVPlayer('myVideo', {
117
117
  quality: 'default',
118
118
 
119
119
  // Enable quality control in player UI
120
- enableQualityControl: true
120
+ enableQualityControl: true,
121
+
122
+ // enable channel information retrieval (NEED THE APIKEY TO WORK)
123
+ enableChannelWatermark: false,
124
+
125
+ // Set the default language for auto subtitles
126
+ autoCaptionLanguage: 'en'
121
127
  }
122
128
  }
123
129
  });
@@ -197,16 +203,18 @@ const player = new MYETVPlayer('myVideo', {
197
203
  </script>
198
204
  ```
199
205
 
200
- ### Method 4: YouTube URL in Video Source
206
+ ### Method 4: YouTube video id in the initialization option
201
207
 
202
208
  ```html
203
- <video id="myVideo" class="video-player"
204
- src="https://youtu.be/dQw4w9WgXcQ">
209
+ <video id="myVideo" class="video-player">
205
210
  </video>
206
211
 
207
212
  <script>
208
213
  const player = new MYETVPlayer('myVideo', {
209
- plugins: { youtube: {} }
214
+ plugins: { youtube: {
215
+ videoId: 'dQw4w9WgXcQ', // YouTube video ID
216
+ autoplay: true
217
+ } }
210
218
  });
211
219
  </script>
212
220
  ```