myetv-player 1.0.0 → 1.0.8

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.
Files changed (38) hide show
  1. package/.github/workflows/codeql.yml +100 -0
  2. package/README.md +49 -58
  3. package/SECURITY.md +50 -0
  4. package/css/myetv-player.css +424 -219
  5. package/css/myetv-player.min.css +1 -1
  6. package/dist/myetv-player.js +1759 -1502
  7. package/dist/myetv-player.min.js +1705 -1469
  8. package/package.json +7 -1
  9. package/plugins/README.md +1016 -0
  10. package/plugins/cloudflare/README.md +1068 -0
  11. package/plugins/cloudflare/myetv-player-cloudflare-stream-plugin.js +556 -0
  12. package/plugins/facebook/README.md +1024 -0
  13. package/plugins/facebook/myetv-player-facebook-plugin.js +437 -0
  14. package/plugins/gamepad-remote-controller/README.md +816 -0
  15. package/plugins/gamepad-remote-controller/myetv-player-gamepad-remote-plugin.js +678 -0
  16. package/plugins/google-adsense-ads/README.md +1 -0
  17. package/plugins/google-adsense-ads/g-adsense-ads-plugin.js +158 -0
  18. package/plugins/google-ima-ads/README.md +1 -0
  19. package/plugins/google-ima-ads/g-ima-ads-plugin.js +355 -0
  20. package/plugins/twitch/README.md +1185 -0
  21. package/plugins/twitch/myetv-player-twitch-plugin.js +569 -0
  22. package/plugins/vast-vpaid-ads/README.md +1 -0
  23. package/plugins/vast-vpaid-ads/vast-vpaid-ads-plugin.js +346 -0
  24. package/plugins/vimeo/README.md +1416 -0
  25. package/plugins/vimeo/myetv-player-vimeo.js +640 -0
  26. package/plugins/youtube/README.md +851 -0
  27. package/plugins/youtube/myetv-player-youtube-plugin.js +1714 -210
  28. package/scss/README.md +160 -0
  29. package/scss/_controls.scss +184 -30
  30. package/scss/_menus.scss +840 -672
  31. package/scss/_responsive.scss +67 -105
  32. package/scss/_volume.scss +67 -105
  33. package/src/README.md +559 -0
  34. package/src/controls.js +17 -5
  35. package/src/core.js +1237 -1060
  36. package/src/i18n.js +27 -1
  37. package/src/quality.js +478 -436
  38. package/src/subtitles.js +2 -2
@@ -0,0 +1,1024 @@
1
+ # MYETV Player - Facebook Plugin
2
+ Official Facebook integration plugin for MYETV Video Player. Embed and control Facebook videos directly in your player with full API support.
3
+
4
+ ---
5
+
6
+ ## Table of Contents
7
+
8
+ - [Features](#features)
9
+ - [Installation](#installation)
10
+ - [Quick Start](#quick-start)
11
+ - [Configuration Options](#configuration-options)
12
+ - [Privacy & Video Access](#privacy--video-access)
13
+ - [Usage Methods](#usage-methods)
14
+ - [API Methods](#api-methods)
15
+ - [Events](#events)
16
+ - [Examples](#examples)
17
+ - [FAQ](#faq)
18
+ - [Troubleshooting](#troubleshooting)
19
+
20
+ ---
21
+
22
+ ## Features
23
+
24
+ - **Facebook Video Integration**: Embed any Facebook video using URL or ID
25
+ - **App ID Support**: Optional Facebook App ID for enhanced features
26
+ - **Public & Private Videos**: Support for public videos and authorized private content
27
+ - **Smart Loading**: Asynchronous Facebook SDK loading
28
+ - **Full API Control**: Complete playback control (play, pause, seek, volume)
29
+ - **Rich Events**: Comprehensive event system for all player states
30
+ - **Auto-Detection**: Automatically detects Facebook URLs from multiple sources
31
+ - **Easy Integration**: Seamless integration with MYETV Player
32
+ - **Responsive**: Works on desktop and mobile devices
33
+ - **Live Video Support**: Supports Facebook live streams
34
+
35
+ ---
36
+
37
+ ## Installation
38
+
39
+ ### Method 1: Direct Script Include
40
+
41
+ ```html
42
+ <!-- Load MYETV Player Core -->
43
+ <script src="dist/myetv-player.js"></script>
44
+
45
+ <!-- Load Facebook Plugin -->
46
+ <script src="plugins/myetv-player-facebook-plugin.js"></script>
47
+ ```
48
+
49
+ ### Method 2: Module Import
50
+
51
+ ```javascript
52
+ import MYETVPlayer from './myetv-player.js';
53
+ import './plugins/myetv-player-facebook-plugin.js';
54
+ ```
55
+
56
+ ---
57
+
58
+ ## Quick Start
59
+
60
+ ### Basic Usage
61
+
62
+ ```html
63
+ <!DOCTYPE html>
64
+ <html lang="en">
65
+ <head>
66
+ <meta charset="UTF-8">
67
+ <title>MYETV Player - Facebook Plugin</title>
68
+ <link rel="stylesheet" href="dist/myetv-player.css">
69
+ </head>
70
+ <body>
71
+ <!-- Video Element -->
72
+ <video id="myVideo" class="video-player"></video>
73
+
74
+ <script src="dist/myetv-player.js"></script>
75
+ <script src="plugins/myetv-player-facebook-plugin.js"></script>
76
+
77
+ <script>
78
+ // Initialize player with Facebook plugin
79
+ const player = new MYETVPlayer('myVideo', {
80
+ debug: true,
81
+ plugins: {
82
+ facebook: {
83
+ videoUrl: 'https://www.facebook.com/facebook/videos/10153231379946729/',
84
+ appId: 'YOUR_FACEBOOK_APP_ID', // Optional but recommended
85
+ autoplay: false
86
+ }
87
+ }
88
+ });
89
+ </script>
90
+ </body>
91
+ </html>
92
+ ```
93
+
94
+ ---
95
+
96
+ ## Configuration Options
97
+
98
+ ```javascript
99
+ const player = new MYETVPlayer('myVideo', {
100
+ plugins: {
101
+ facebook: {
102
+ // ========== Authentication ==========
103
+ // Facebook App ID (optional but recommended)
104
+ // Required for: private videos, enhanced analytics, custom features
105
+ appId: null,
106
+
107
+ // ========== Video Source ==========
108
+ // Facebook video URL (full URL)
109
+ videoUrl: 'https://www.facebook.com/facebook/videos/10153231379946729/',
110
+
111
+ // OR use video ID directly
112
+ videoId: '10153231379946729',
113
+
114
+ // ========== Embed Options ==========
115
+ width: 500, // Player width in pixels
116
+ autoplay: false, // Auto-play on load
117
+ allowFullscreen: true, // Enable fullscreen button
118
+ showText: true, // Show video title/description
119
+ showCaptions: true, // Show captions if available
120
+
121
+ // ========== Plugin Options ==========
122
+ debug: false, // Enable debug logging
123
+ replaceNativePlayer: true, // Replace native video element
124
+ autoLoadFromData: true // Auto-detect from data attributes
125
+ }
126
+ }
127
+ });
128
+ ```
129
+
130
+ ---
131
+
132
+ ## Privacy & Video Access
133
+
134
+ ### Understanding Video Privacy on Facebook
135
+
136
+ Facebook videos have different privacy levels that affect embedding:
137
+
138
+ #### 1. **Public Videos**
139
+ - **Access**: Anyone can view
140
+ - **App ID Required**: No (but recommended)
141
+ - **Example**: Videos from Facebook Pages, public posts
142
+ - **Works**: Always works in embedded player
143
+
144
+ ```javascript
145
+ plugins: {
146
+ facebook: {
147
+ videoUrl: 'https://www.facebook.com/facebook/videos/10153231379946729/'
148
+ // No appId needed for public videos
149
+ }
150
+ }
151
+ ```
152
+
153
+ ---
154
+
155
+ #### 2. **Unlisted Videos**
156
+ - **Access**: Anyone with the link
157
+ - **App ID Required**: Recommended
158
+ - **Example**: Videos shared with "Anyone with link"
159
+ - **Works**: Works with proper configuration
160
+
161
+ ```javascript
162
+ plugins: {
163
+ facebook: {
164
+ videoUrl: 'https://www.facebook.com/username/videos/123456789/',
165
+ appId: 'YOUR_APP_ID' // Recommended for better reliability
166
+ }
167
+ }
168
+ ```
169
+
170
+ ---
171
+
172
+ #### 3. **Private/Friends-Only Videos**
173
+ - **Access**: Restricted to specific users/friends
174
+ - **App ID Required**: Yes, with proper permissions
175
+ - **Example**: Videos visible only to friends
176
+ - **Works**: Only if user is logged in and authorized
177
+
178
+ ```javascript
179
+ plugins: {
180
+ facebook: {
181
+ videoUrl: 'https://www.facebook.com/username/videos/123456789/',
182
+ appId: 'YOUR_APP_ID', // Required
183
+ // User must be logged in to Facebook and have permission
184
+ }
185
+ }
186
+ ```
187
+
188
+ ---
189
+
190
+ #### 4. **Your Own Videos**
191
+ - **Access**: Videos you uploaded to your account/page
192
+ - **App ID Required**: Yes
193
+ - **Permissions Needed**:
194
+ - `user_videos` (for personal videos)
195
+ - `pages_read_engagement` (for page videos)
196
+ - **Works**: With proper App ID and permissions
197
+
198
+ ```javascript
199
+ plugins: {
200
+ facebook: {
201
+ videoUrl: 'https://www.facebook.com/yourpage/videos/123456789/',
202
+ appId: 'YOUR_APP_ID' // Required with proper permissions
203
+ }
204
+ }
205
+ ```
206
+
207
+ ---
208
+
209
+ ### How to Get a Facebook App ID
210
+
211
+ To access private videos or your own content, you need a Facebook App ID:
212
+
213
+ 1. **Go to**: [Facebook Developers](https://developers.facebook.com/)
214
+ 2. **Click**: "My Apps" → "Create App"
215
+ 3. **Choose**: "Business" or "Consumer" type
216
+ 4. **Fill in**: App name and contact email
217
+ 5. **Get**: Your App ID from the dashboard
218
+ 6. **Add Domain**: Add your website domain in App Settings → Basic → App Domains
219
+ 7. **Set Permissions**: Configure video access permissions if needed
220
+
221
+ **App Settings Example:**
222
+ ```javascript
223
+ plugins: {
224
+ facebook: {
225
+ appId: '1234567890123456', // Your 16-digit App ID
226
+ videoUrl: 'YOUR_VIDEO_URL'
227
+ }
228
+ }
229
+ ```
230
+
231
+ ---
232
+
233
+ ### Best Practices for Video Privacy
234
+
235
+ **Do:**
236
+ - Use public videos for maximum compatibility
237
+ - Add App ID even for public videos (better analytics)
238
+ - Test video accessibility before deploying
239
+ - Handle error events for restricted videos
240
+
241
+ **Don't:**
242
+ - Embed private videos without proper permissions
243
+ - Share your App ID publicly in client-side code (it's safe, but use App Secret server-side)
244
+ - Assume all videos are embeddable
245
+
246
+ ---
247
+
248
+ ## Usage Methods
249
+
250
+ ### Method 1: Using Video URL
251
+
252
+ ```html
253
+ <video id="myVideo" class="video-player"></video>
254
+
255
+ <script>
256
+ const player = new MYETVPlayer('myVideo', {
257
+ plugins: {
258
+ facebook: {
259
+ videoUrl: 'https://www.facebook.com/facebook/videos/10153231379946729/',
260
+ appId: 'YOUR_APP_ID'
261
+ }
262
+ }
263
+ });
264
+ </script>
265
+ ```
266
+
267
+ ---
268
+
269
+ ### Method 2: Using Video ID
270
+
271
+ ```html
272
+ <video id="myVideo" class="video-player"></video>
273
+
274
+ <script>
275
+ const player = new MYETVPlayer('myVideo', {
276
+ plugins: {
277
+ facebook: {
278
+ videoId: '10153231379946729',
279
+ appId: 'YOUR_APP_ID'
280
+ }
281
+ }
282
+ });
283
+ </script>
284
+ ```
285
+
286
+ ---
287
+
288
+ ### Method 3: Using Data Attributes
289
+
290
+ ```html
291
+ <video id="myVideo" class="video-player"
292
+ data-video-url="https://www.facebook.com/facebook/videos/10153231379946729/"
293
+ data-video-type="facebook">
294
+ </video>
295
+
296
+ <script>
297
+ const player = new MYETVPlayer('myVideo', {
298
+ plugins: {
299
+ facebook: {
300
+ appId: 'YOUR_APP_ID',
301
+ autoLoadFromData: true
302
+ }
303
+ }
304
+ });
305
+ </script>
306
+ ```
307
+
308
+ ---
309
+
310
+ ### Method 4: Load Video Dynamically
311
+
312
+ ```html
313
+ <video id="myVideo" class="video-player"></video>
314
+
315
+ <script>
316
+ const player = new MYETVPlayer('myVideo', {
317
+ plugins: {
318
+ facebook: {
319
+ appId: 'YOUR_APP_ID'
320
+ }
321
+ }
322
+ });
323
+
324
+ const fbPlugin = player.getPlugin('facebook');
325
+
326
+ // Load video after initialization
327
+ fbPlugin.loadVideo('https://www.facebook.com/facebook/videos/10153231379946729/');
328
+ </script>
329
+ ```
330
+
331
+ **Supported URL Formats:**
332
+ - `https://www.facebook.com/username/videos/VIDEO_ID/`
333
+ - `https://www.facebook.com/video.php?v=VIDEO_ID`
334
+ - `https://fb.watch/VIDEO_ID/`
335
+
336
+ ---
337
+
338
+ ## API Methods
339
+
340
+ The Facebook plugin provides the following methods:
341
+
342
+ ```javascript
343
+ const fbPlugin = player.getPlugin('facebook');
344
+ ```
345
+
346
+ ### Playback Control
347
+
348
+ #### `play()`
349
+ Play the video.
350
+
351
+ ```javascript
352
+ fbPlugin.play().then(() => {
353
+ console.log('Video playing');
354
+ });
355
+ ```
356
+
357
+ **Returns:** Promise
358
+
359
+ ---
360
+
361
+ #### `pause()`
362
+ Pause the video.
363
+
364
+ ```javascript
365
+ fbPlugin.pause().then(() => {
366
+ console.log('Video paused');
367
+ });
368
+ ```
369
+
370
+ **Returns:** Promise
371
+
372
+ ---
373
+
374
+ #### `seek(seconds)`
375
+ Seek to specific time position.
376
+
377
+ ```javascript
378
+ fbPlugin.seek(60).then(() => {
379
+ console.log('Seeked to 60 seconds');
380
+ });
381
+ ```
382
+
383
+ **Parameters:**
384
+ - `seconds` (Number): Time position in seconds
385
+
386
+ **Returns:** Promise
387
+
388
+ ---
389
+
390
+ #### `getCurrentTime()`
391
+ Get current playback position.
392
+
393
+ ```javascript
394
+ fbPlugin.getCurrentTime().then(time => {
395
+ console.log('Current time:', time, 'seconds');
396
+ });
397
+ ```
398
+
399
+ **Returns:** Promise<Number>
400
+
401
+ ---
402
+
403
+ #### `getDuration()`
404
+ Get video duration.
405
+
406
+ ```javascript
407
+ fbPlugin.getDuration().then(duration => {
408
+ console.log('Duration:', duration, 'seconds');
409
+ });
410
+ ```
411
+
412
+ **Returns:** Promise<Number>
413
+
414
+ ---
415
+
416
+ ### Volume Control
417
+
418
+ #### `mute()`
419
+ Mute the video.
420
+
421
+ ```javascript
422
+ fbPlugin.mute().then(() => {
423
+ console.log('Video muted');
424
+ });
425
+ ```
426
+
427
+ **Returns:** Promise
428
+
429
+ ---
430
+
431
+ #### `unmute()`
432
+ Unmute the video.
433
+
434
+ ```javascript
435
+ fbPlugin.unmute().then(() => {
436
+ console.log('Video unmuted');
437
+ });
438
+ ```
439
+
440
+ **Returns:** Promise
441
+
442
+ ---
443
+
444
+ #### `isMuted()`
445
+ Check if video is muted.
446
+
447
+ ```javascript
448
+ fbPlugin.isMuted().then(muted => {
449
+ console.log('Is muted:', muted);
450
+ });
451
+ ```
452
+
453
+ **Returns:** Promise<Boolean>
454
+
455
+ ---
456
+
457
+ #### `setVolume(volume)`
458
+ Set volume level.
459
+
460
+ ```javascript
461
+ fbPlugin.setVolume(0.5).then(() => {
462
+ console.log('Volume set to 50%');
463
+ });
464
+ ```
465
+
466
+ **Parameters:**
467
+ - `volume` (Number): Volume level (0-1)
468
+
469
+ **Returns:** Promise
470
+
471
+ ---
472
+
473
+ #### `getVolume()`
474
+ Get current volume level.
475
+
476
+ ```javascript
477
+ fbPlugin.getVolume().then(volume => {
478
+ console.log('Current volume:', volume);
479
+ });
480
+ ```
481
+
482
+ **Returns:** Promise<Number>
483
+
484
+ ---
485
+
486
+ ### Video Management
487
+
488
+ #### `loadVideo(videoUrl)`
489
+ Load a new video.
490
+
491
+ ```javascript
492
+ fbPlugin.loadVideo('https://www.facebook.com/facebook/videos/10153231379946729/')
493
+ .then(() => {
494
+ console.log('New video loaded');
495
+ });
496
+ ```
497
+
498
+ **Parameters:**
499
+ - `videoUrl` (String): Facebook video URL
500
+
501
+ **Returns:** Promise
502
+
503
+ ---
504
+
505
+ ## Events
506
+
507
+ The Facebook plugin triggers the following events:
508
+
509
+ ### Playback Events
510
+
511
+ #### `play`
512
+ Video started playing.
513
+
514
+ ```javascript
515
+ player.addEventListener('play', () => {
516
+ console.log('Video started');
517
+ });
518
+ ```
519
+
520
+ ---
521
+
522
+ #### `playing`
523
+ Video is actively playing.
524
+
525
+ ```javascript
526
+ player.addEventListener('playing', () => {
527
+ console.log('Video playing');
528
+ });
529
+ ```
530
+
531
+ ---
532
+
533
+ #### `pause`
534
+ Video paused.
535
+
536
+ ```javascript
537
+ player.addEventListener('pause', () => {
538
+ console.log('Video paused');
539
+ });
540
+ ```
541
+
542
+ ---
543
+
544
+ #### `ended`
545
+ Video playback ended.
546
+
547
+ ```javascript
548
+ player.addEventListener('ended', () => {
549
+ console.log('Video ended');
550
+ });
551
+ ```
552
+
553
+ ---
554
+
555
+ ### Buffering Events
556
+
557
+ #### `waiting`
558
+ Video buffering started.
559
+
560
+ ```javascript
561
+ player.addEventListener('waiting', () => {
562
+ console.log('Buffering...');
563
+ });
564
+ ```
565
+
566
+ ---
567
+
568
+ #### `canplay`
569
+ Video buffering completed, ready to play.
570
+
571
+ ```javascript
572
+ player.addEventListener('canplay', () => {
573
+ console.log('Ready to play');
574
+ });
575
+ ```
576
+
577
+ ---
578
+
579
+ ### Plugin-Specific Events
580
+
581
+ #### `facebookplugin:playerready`
582
+ Facebook player initialized and ready.
583
+
584
+ ```javascript
585
+ player.addEventListener('facebookplugin:playerready', () => {
586
+ console.log('Facebook player ready');
587
+ });
588
+ ```
589
+
590
+ ---
591
+
592
+ #### `facebookplugin:videoloaded`
593
+ Video loaded successfully.
594
+
595
+ ```javascript
596
+ player.addEventListener('facebookplugin:videoloaded', (data) => {
597
+ console.log('Video loaded:', data.videoUrl);
598
+ });
599
+ ```
600
+
601
+ ---
602
+
603
+ #### `facebookplugin:error`
604
+ Player error occurred.
605
+
606
+ ```javascript
607
+ player.addEventListener('facebookplugin:error', (error) => {
608
+ console.error('Facebook player error:', error);
609
+ });
610
+ ```
611
+
612
+ ---
613
+
614
+ #### `error`
615
+ General error event.
616
+
617
+ ```javascript
618
+ player.addEventListener('error', (error) => {
619
+ console.error('Error:', error);
620
+ });
621
+ ```
622
+
623
+ ---
624
+
625
+ ## Examples
626
+
627
+ ### Example 1: Video Playlist
628
+
629
+ ```html
630
+ <video id="myVideo" class="video-player"></video>
631
+
632
+ <div id="playlist">
633
+ <button onclick="loadFBVideo('https://www.facebook.com/facebook/videos/10153231379946729/')">
634
+ Video 1
635
+ </button>
636
+ <button onclick="loadFBVideo('https://www.facebook.com/facebook/videos/10153095973521729/')">
637
+ Video 2
638
+ </button>
639
+ <button onclick="loadFBVideo('https://www.facebook.com/facebook/videos/10152454700553729/')">
640
+ Video 3
641
+ </button>
642
+ </div>
643
+
644
+ <script>
645
+ const player = new MYETVPlayer('myVideo', {
646
+ plugins: {
647
+ facebook: {
648
+ appId: 'YOUR_APP_ID'
649
+ }
650
+ }
651
+ });
652
+
653
+ const fbPlugin = player.getPlugin('facebook');
654
+
655
+ function loadFBVideo(url) {
656
+ fbPlugin.loadVideo(url).then(() => {
657
+ console.log('Loaded:', url);
658
+ });
659
+ }
660
+ </script>
661
+ ```
662
+
663
+ ---
664
+
665
+ ### Example 2: Custom Controls
666
+
667
+ ```html
668
+ <video id="myVideo" class="video-player"></video>
669
+
670
+ <div id="custom-controls">
671
+ <button id="playBtn">Play</button>
672
+ <button id="pauseBtn">Pause</button>
673
+ <button id="muteBtn">Mute</button>
674
+ <input type="range" id="volumeSlider" min="0" max="100" value="100">
675
+ </div>
676
+
677
+ <script>
678
+ const player = new MYETVPlayer('myVideo', {
679
+ plugins: {
680
+ facebook: {
681
+ videoUrl: 'https://www.facebook.com/facebook/videos/10153231379946729/',
682
+ appId: 'YOUR_APP_ID'
683
+ }
684
+ }
685
+ });
686
+
687
+ const fbPlugin = player.getPlugin('facebook');
688
+
689
+ // Play button
690
+ document.getElementById('playBtn').onclick = () => {
691
+ fbPlugin.play();
692
+ };
693
+
694
+ // Pause button
695
+ document.getElementById('pauseBtn').onclick = () => {
696
+ fbPlugin.pause();
697
+ };
698
+
699
+ // Mute button
700
+ document.getElementById('muteBtn').onclick = () => {
701
+ fbPlugin.isMuted().then(muted => {
702
+ if (muted) {
703
+ fbPlugin.unmute();
704
+ } else {
705
+ fbPlugin.mute();
706
+ }
707
+ });
708
+ };
709
+
710
+ // Volume slider
711
+ document.getElementById('volumeSlider').oninput = (e) => {
712
+ const volume = e.target.value / 100;
713
+ fbPlugin.setVolume(volume);
714
+ };
715
+ </script>
716
+ ```
717
+
718
+ ---
719
+
720
+ ### Example 3: Progress Tracker
721
+
722
+ ```html
723
+ <video id="myVideo" class="video-player"></video>
724
+
725
+ <div id="progress-info">
726
+ <p>Current Time: <span id="currentTime">0:00</span></p>
727
+ <p>Duration: <span id="duration">0:00</span></p>
728
+ <div id="progress-bar" style="width: 100%; height: 5px; background: #ddd;">
729
+ <div id="progress" style="width: 0%; height: 100%; background: #4267B2;"></div>
730
+ </div>
731
+ </div>
732
+
733
+ <script>
734
+ const player = new MYETVPlayer('myVideo', {
735
+ plugins: {
736
+ facebook: {
737
+ videoUrl: 'https://www.facebook.com/facebook/videos/10153231379946729/',
738
+ appId: 'YOUR_APP_ID'
739
+ }
740
+ }
741
+ });
742
+
743
+ const fbPlugin = player.getPlugin('facebook');
744
+
745
+ // Update progress
746
+ setInterval(() => {
747
+ fbPlugin.getCurrentTime().then(current => {
748
+ fbPlugin.getDuration().then(duration => {
749
+ const percent = (current / duration) * 100;
750
+
751
+ document.getElementById('currentTime').textContent = formatTime(current);
752
+ document.getElementById('duration').textContent = formatTime(duration);
753
+ document.getElementById('progress').style.width = percent + '%';
754
+ });
755
+ });
756
+ }, 1000);
757
+
758
+ function formatTime(seconds) {
759
+ const mins = Math.floor(seconds / 60);
760
+ const secs = Math.floor(seconds % 60);
761
+ return `${mins}:${secs.toString().padStart(2, '0')}`;
762
+ }
763
+ </script>
764
+ ```
765
+
766
+ ---
767
+
768
+ ### Example 4: Error Handling
769
+
770
+ ```javascript
771
+ const player = new MYETVPlayer('myVideo', {
772
+ plugins: {
773
+ facebook: {
774
+ videoUrl: 'https://www.facebook.com/facebook/videos/10153231379946729/',
775
+ appId: 'YOUR_APP_ID'
776
+ }
777
+ }
778
+ });
779
+
780
+ // Handle errors gracefully
781
+ player.addEventListener('facebookplugin:error', (error) => {
782
+ console.error('Facebook error:', error);
783
+
784
+ // Show user-friendly message
785
+ const errorDiv = document.createElement('div');
786
+ errorDiv.className = 'error-message';
787
+ errorDiv.style.cssText = 'padding: 20px; background: #ff4444; color: white;';
788
+ errorDiv.textContent = 'Unable to load video. It may be private or unavailable.';
789
+
790
+ document.getElementById('player-container').appendChild(errorDiv);
791
+ });
792
+
793
+ // Handle video loaded
794
+ player.addEventListener('facebookplugin:videoloaded', (data) => {
795
+ console.log('Video loaded successfully:', data.videoUrl);
796
+ });
797
+ ```
798
+
799
+ ---
800
+
801
+ ### Example 5: Autoplay with Mute (Mobile-Friendly)
802
+
803
+ ```javascript
804
+ const player = new MYETVPlayer('myVideo', {
805
+ plugins: {
806
+ facebook: {
807
+ videoUrl: 'https://www.facebook.com/facebook/videos/10153231379946729/',
808
+ appId: 'YOUR_APP_ID',
809
+ autoplay: true // Autoplay enabled
810
+ }
811
+ }
812
+ });
813
+
814
+ const fbPlugin = player.getPlugin('facebook');
815
+
816
+ // Mute for autoplay (required on mobile)
817
+ player.addEventListener('facebookplugin:playerready', () => {
818
+ fbPlugin.mute().then(() => {
819
+ console.log('Muted for autoplay');
820
+ });
821
+ });
822
+
823
+ // Add unmute button
824
+ const unmuteBtn = document.createElement('button');
825
+ unmuteBtn.textContent = 'Unmute';
826
+ unmuteBtn.onclick = () => {
827
+ fbPlugin.unmute();
828
+ };
829
+ document.body.appendChild(unmuteBtn);
830
+ ```
831
+
832
+ ---
833
+
834
+ ## FAQ
835
+
836
+ ### Q: Do I need a Facebook App ID?
837
+
838
+ **A:** Not required for public videos, but **highly recommended** for:
839
+ - Better reliability and performance
840
+ - Access to analytics
841
+ - Private or unlisted videos
842
+ - Your own videos
843
+ - Enhanced error handling
844
+
845
+ ---
846
+
847
+ ### Q: Can I embed private Facebook videos?
848
+
849
+ **A:** Yes, but with limitations:
850
+ - You need a Facebook App ID
851
+ - The viewer must be logged into Facebook
852
+ - The viewer must have permission to view the video
853
+ - Works best for videos from your own page/profile
854
+
855
+ ---
856
+
857
+ ### Q: Why isn't my video loading?
858
+
859
+ **Possible reasons:**
860
+ 1. Video is private and viewer doesn't have access
861
+ 2. Video has been deleted
862
+ 3. Domain restrictions on the video
863
+ 4. Missing or invalid App ID for restricted content
864
+ 5. CORS or security policy blocking the embed
865
+
866
+ ---
867
+
868
+ ### Q: Can I use Facebook live streams?
869
+
870
+ **A:** Yes! Facebook live videos work the same way as regular videos. Just use the live video URL.
871
+
872
+ ---
873
+
874
+ ### Q: How do I get video analytics?
875
+
876
+ **A:** Use a Facebook App ID and track events:
877
+
878
+ ```javascript
879
+ player.addEventListener('play', () => {
880
+ // Send to your analytics
881
+ trackEvent('facebook_video_play');
882
+ });
883
+
884
+ player.addEventListener('ended', () => {
885
+ trackEvent('facebook_video_complete');
886
+ });
887
+ ```
888
+
889
+ ---
890
+
891
+ ### Q: Does this work on mobile?
892
+
893
+ **A:** Yes! The Facebook embedded player is fully responsive and works on iOS and Android.
894
+
895
+ ---
896
+
897
+ ### Q: Can I customize the player appearance?
898
+
899
+ **A:** Limited customization is available through Facebook's embed options:
900
+ - Show/hide text
901
+ - Show/hide captions
902
+ - Set width
903
+ - Enable/disable fullscreen
904
+
905
+ For more control, consider using custom overlay controls.
906
+
907
+ ---
908
+
909
+ ## Troubleshooting
910
+
911
+ ### Issue: "Video cannot be displayed"
912
+
913
+ **Possible causes:**
914
+ - Video is private
915
+ - Domain not whitelisted in Facebook App settings
916
+ - Video has been deleted
917
+
918
+ **Solution:**
919
+ 1. Verify video is public or you have access
920
+ 2. Add your domain to Facebook App settings
921
+ 3. Check Facebook App ID is correct
922
+ 4. Test video URL directly on Facebook
923
+
924
+ ---
925
+
926
+ ### Issue: Facebook SDK not loading
927
+
928
+ **Solution:**
929
+ - Check browser console for errors
930
+ - Verify internet connection
931
+ - Ensure no ad blockers blocking Facebook scripts
932
+ - Check Content Security Policy allows Facebook domains
933
+
934
+ ```html
935
+ <!-- Add to <head> if using CSP -->
936
+ <meta http-equiv="Content-Security-Policy"
937
+ content="script-src 'self' https://connect.facebook.net;">
938
+ ```
939
+
940
+ ---
941
+
942
+ ### Issue: Video plays but controls don't work
943
+
944
+ **Solution:**
945
+ 1. Ensure Facebook SDK loaded successfully
946
+ 2. Check browser console for API errors
947
+ 3. Verify App ID is valid
948
+ 4. Wait for `facebookplugin:playerready` event
949
+
950
+ ```javascript
951
+ player.addEventListener('facebookplugin:playerready', () => {
952
+ // Now safe to use API methods
953
+ fbPlugin.play();
954
+ });
955
+ ```
956
+
957
+ ---
958
+
959
+ ### Issue: Autoplay not working
960
+
961
+ **Solution:**
962
+ Browsers require muted videos for autoplay:
963
+
964
+ ```javascript
965
+ plugins: {
966
+ facebook: {
967
+ videoUrl: 'YOUR_VIDEO_URL',
968
+ autoplay: true
969
+ }
970
+ }
971
+
972
+ // Mute immediately after player ready
973
+ player.addEventListener('facebookplugin:playerready', () => {
974
+ fbPlugin.mute();
975
+ });
976
+ ```
977
+
978
+ ---
979
+
980
+ ### Debug Mode
981
+
982
+ Enable detailed logging:
983
+
984
+ ```javascript
985
+ const player = new MYETVPlayer('myVideo', {
986
+ debug: true,
987
+ plugins: {
988
+ facebook: {
989
+ videoUrl: 'YOUR_VIDEO_URL',
990
+ appId: 'YOUR_APP_ID',
991
+ debug: true
992
+ }
993
+ }
994
+ });
995
+ ```
996
+
997
+ Debug messages appear with `Facebook Plugin:` prefix.
998
+
999
+ ---
1000
+
1001
+ ## Resources
1002
+
1003
+ - **MYETV Player**: [https://www.myetv.tv](https://www.myetv.tv)
1004
+ - **Facebook Embedded Video Player**: [Facebook Developers - Embedded Videos](https://developers.facebook.com/docs/plugins/embedded-video-player/)
1005
+ - **Facebook for Developers**: [https://developers.facebook.com](https://developers.facebook.com)
1006
+ - **Facebook SDK Documentation**: [JavaScript SDK](https://developers.facebook.com/docs/javascript)
1007
+ - **GitHub**: [MYETV Video Player Open Source](https://github.com/OskarCosimo/myetv-video-player-opensource)
1008
+ - **Author**: [https://oskarcosimo.com](https://oskarcosimo.com)
1009
+
1010
+ ---
1011
+
1012
+ ## License
1013
+
1014
+ MIT License - See main project for details.
1015
+
1016
+ ---
1017
+
1018
+ ## Contributing
1019
+
1020
+ Contributions are welcome! Please submit pull requests or open issues on GitHub.
1021
+
1022
+ ---
1023
+
1024
+ **Enjoy Facebook video integration!**