jerrrycans commited on
Commit
1944a80
·
verified ·
1 Parent(s): 14bb70c

Update bot/server/templates/player.html

Browse files
Files changed (1) hide show
  1. bot/server/templates/player.html +151 -527
bot/server/templates/player.html CHANGED
@@ -1,530 +1,154 @@
1
  <!DOCTYPE html>
2
  <html lang="en">
3
- <head>
4
- <title>Premium Media Player</title>
5
-
6
- <meta charset="UTF-8">
7
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
8
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
9
- <meta name="description" content="Advanced HTML5 Video Player">
10
-
11
- <!-- Favicon -->
12
- <link rel="icon" type="image/png" href="https://cdn.jsdelivr.net/npm/plyr@3.7.8/dist/plyr.svg">
13
-
14
- <!-- CSS Libraries -->
15
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/plyr@3.7.8/dist/plyr.css">
16
- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
17
- <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap">
18
-
19
- <!-- Scripts -->
20
- <script src="https://cdn.jsdelivr.net/npm/plyr@3.7.8/dist/plyr.polyfilled.js"></script>
21
-
22
- <style>
23
- :root {
24
- --primary-color: #3498db;
25
- --secondary-color: #2ecc71;
26
- --background-color: #000;
27
- --text-color: #fff;
28
- --button-hover: rgba(52, 152, 219, 0.8);
29
- }
30
-
31
- * {
32
- margin: 0;
33
- padding: 0;
34
- box-sizing: border-box;
35
- }
36
-
37
- html, body {
38
- margin: 0;
39
- height: 100%;
40
- font-family: 'Roboto', Arial, sans-serif;
41
- background-color: var(--background-color);
42
- overflow: hidden;
43
- }
44
-
45
- .player-container {
46
- position: relative;
47
- height: 100%;
48
- width: 100%;
49
- display: flex;
50
- align-items: center;
51
- justify-content: center;
52
- }
53
-
54
- #stream-media {
55
- height: 100%;
56
- width: 100%;
57
- max-height: 100vh;
58
- }
59
-
60
- .loading-overlay {
61
- position: absolute;
62
- top: 0;
63
- left: 0;
64
- width: 100%;
65
- height: 100%;
66
- background-color: rgba(0, 0, 0, 0.7);
67
- display: flex;
68
- align-items: center;
69
- justify-content: center;
70
- z-index: 100;
71
- opacity: 1;
72
- transition: opacity 0.5s ease;
73
- }
74
-
75
- .loading-spinner {
76
- width: 50px;
77
- height: 50px;
78
- border: 5px solid rgba(255, 255, 255, 0.3);
79
- border-radius: 50%;
80
- border-top-color: var(--primary-color);
81
- animation: spin 1s ease-in-out infinite;
82
- }
83
-
84
- @keyframes spin {
85
- to { transform: rotate(360deg); }
86
- }
87
-
88
- .hidden {
89
- opacity: 0;
90
- pointer-events: none;
91
- }
92
-
93
- #error-message {
94
- position: absolute;
95
- top: 50%;
96
- left: 50%;
97
- transform: translate(-50%, -50%);
98
- color: #e74c3c;
99
- font-size: 18px;
100
- text-align: center;
101
- background-color: rgba(0, 0, 0, 0.8);
102
- padding: 20px;
103
- border-radius: 8px;
104
- max-width: 80%;
105
- z-index: 50;
106
- display: none;
107
- }
108
-
109
- .plyr--full-ui input[type=range] {
110
- color: var(--primary-color);
111
- }
112
-
113
- .plyr__control--overlaid {
114
- background: var(--primary-color);
115
- }
116
-
117
- .plyr--video .plyr__control:hover {
118
- background: var(--primary-color);
119
- }
120
-
121
- .plyr--video .plyr__control.plyr__tab-focus {
122
- background: var(--primary-color);
123
- }
124
-
125
- .plyr__menu__container .plyr__control[role=menuitemradio][aria-checked=true]::before {
126
- background: var(--primary-color);
127
- }
128
-
129
- .plyr__control.plyr__control--pressed {
130
- background: var(--secondary-color);
131
- }
132
-
133
- .custom-button {
134
- position: absolute;
135
- width: 40px;
136
- height: 40px;
137
- border-radius: 50%;
138
- background-color: rgba(0, 0, 0, 0.6);
139
- display: flex;
140
- align-items: center;
141
- justify-content: center;
142
- color: white;
143
- cursor: pointer;
144
- z-index: 10;
145
- transition: all 0.3s ease;
146
- border: 2px solid rgba(255, 255, 255, 0.2);
147
- }
148
-
149
- .custom-button:hover {
150
- background-color: var(--button-hover);
151
- transform: scale(1.1);
152
- border-color: rgba(255, 255, 255, 0.5);
153
- }
154
-
155
- .custom-button i {
156
- font-size: 16px;
157
- }
158
-
159
- .plyr__video-wrapper .download-button {
160
- top: 15px;
161
- right: 15px;
162
- }
163
-
164
- .plyr__video-wrapper .share-button {
165
- top: 15px;
166
- right: 65px;
167
- }
168
-
169
- .plyr__video-wrapper .info-button {
170
- top: 15px;
171
- right: 115px;
172
- }
173
-
174
- .video-info-panel {
175
- position: absolute;
176
- top: 70px;
177
- right: 15px;
178
- background-color: rgba(0, 0, 0, 0.8);
179
- border-radius: 8px;
180
- padding: 15px;
181
- color: white;
182
- max-width: 300px;
183
- transform: translateY(-20px);
184
- opacity: 0;
185
- transition: all 0.3s ease;
186
- z-index: 9;
187
- pointer-events: none;
188
- border: 1px solid rgba(255, 255, 255, 0.1);
189
- }
190
-
191
- .video-info-panel.active {
192
- transform: translateY(0);
193
- opacity: 1;
194
- pointer-events: all;
195
- }
196
-
197
- .video-info-panel h3 {
198
- margin-bottom: 10px;
199
- font-size: 16px;
200
- font-weight: 500;
201
- color: var(--primary-color);
202
- }
203
-
204
- .video-info-panel p {
205
- margin-bottom: 8px;
206
- font-size: 14px;
207
- line-height: 1.4;
208
- }
209
-
210
- .keyboard-shortcuts {
211
- position: absolute;
212
- bottom: 70px;
213
- left: 20px;
214
- background-color: rgba(0, 0, 0, 0.7);
215
- border-radius: 4px;
216
- padding: 8px 12px;
217
- color: white;
218
- font-size: 12px;
219
- opacity: 0;
220
- transition: opacity 0.3s ease;
221
- pointer-events: none;
222
- }
223
-
224
- .plyr--playing:hover .keyboard-shortcuts {
225
- opacity: 1;
226
- }
227
-
228
- .plyr__volume {
229
- max-width: 120px;
230
- }
231
-
232
- @media (max-width: 768px) {
233
- .custom-button {
234
- width: 36px;
235
- height: 36px;
236
- }
237
-
238
- .plyr__video-wrapper .download-button {
239
- top: 10px;
240
- right: 10px;
241
- }
242
-
243
- .plyr__video-wrapper .share-button {
244
- top: 10px;
245
- right: 56px;
246
- }
247
-
248
- .plyr__video-wrapper .info-button {
249
- top: 10px;
250
- right: 102px;
251
- }
252
-
253
- .video-info-panel {
254
- max-width: 250px;
255
- top: 60px;
256
- }
257
- }
258
-
259
- @media (max-width: 480px) {
260
- .custom-button {
261
- width: 32px;
262
- height: 32px;
263
- }
264
-
265
- .custom-button i {
266
- font-size: 14px;
267
- }
268
-
269
- .plyr__video-wrapper .share-button {
270
- right: 52px;
271
- }
272
-
273
- .plyr__video-wrapper .info-button {
274
- right: 94px;
275
- }
276
-
277
- .video-info-panel {
278
- max-width: 200px;
279
- }
280
- }
281
-
282
- .plyr {
283
- --plyr-color-main: var(--primary-color);
284
- --plyr-video-control-color: #fff;
285
- --plyr-video-control-color-hover: #fff;
286
- --plyr-video-control-background-hover: var(--primary-color);
287
- height: 100%;
288
- }
289
-
290
- .plyr__progress__buffer {
291
- color: rgba(255, 255, 255, 0.3);
292
- }
293
-
294
- .plyr--video .plyr__control.plyr__tab-focus,
295
- .plyr--video .plyr__control:hover,
296
- .plyr--video .plyr__control[aria-expanded=true] {
297
- background: var(--primary-color);
298
- }
299
-
300
- .plyr--captions-enabled .plyr__captions {
301
- font-size: 18px;
302
- background-color: rgba(0, 0, 0, 0.7);
303
- padding: 8px 16px;
304
- border-radius: 4px;
305
- }
306
- </style>
307
- </head>
308
-
309
- <body>
310
- <div class="player-container">
311
- <div class="loading-overlay" id="loading-overlay">
312
- <div class="loading-spinner"></div>
313
- </div>
314
-
315
- <video id="stream-media" crossorigin="anonymous" playsinline>
316
- <source src="" type="">
317
- <track kind="captions" label="English" src="" srclang="en" default>
318
- <p class="vjs-no-js">
319
- To view this video please enable JavaScript, and consider upgrading to a web browser that supports HTML5 video
320
- </p>
321
- </video>
322
-
323
- <div id="error-message"></div>
324
-
325
- <div class="video-info-panel" id="info-panel">
326
- <h3>Media Information</h3>
327
- <p><strong>Title:</strong> <span id="video-title">Video Title</span></p>
328
- <p><strong>Duration:</strong> <span id="video-duration">00:00</span></p>
329
- <p><strong>Quality:</strong> <span id="video-quality">HD</span></p>
330
- </div>
331
-
332
- <div class="keyboard-shortcuts" id="shortcuts-info">
333
- Press <strong>Space</strong> to play/pause, <strong>F</strong> for fullscreen
334
- </div>
335
- </div>
336
-
337
- <script>
338
- document.addEventListener('DOMContentLoaded', function() {
339
- // Create player instance with enhanced options
340
- const player = new Plyr('#stream-media', {
341
- controls: [
342
- 'play-large',
343
- 'restart',
344
- 'rewind',
345
- 'play',
346
- 'fast-forward',
347
- 'progress',
348
- 'current-time',
349
- 'duration',
350
- 'mute',
351
- 'volume',
352
- 'captions',
353
- 'settings',
354
- 'pip',
355
- 'airplay',
356
- 'fullscreen'
357
- ],
358
- settings: ['captions', 'quality', 'speed', 'loop'],
359
- speed: { selected: 1, options: [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 3] },
360
- seekTime: 10,
361
- volume: 0.8,
362
- keyboard: { focused: true, global: true },
363
- tooltips: { controls: true, seek: true },
364
- captions: { active: false, language: 'en' },
365
- quality: { default: 1080, options: [4320, 2880, 2160, 1440, 1080, 720, 576, 480, 360, 240] },
366
- invertTime: true,
367
- displayDuration: true,
368
- blankVideo: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=',
369
- ratio: '16:9',
370
- disableContextMenu: false,
371
- autoplay: false,
372
- clickToPlay: true,
373
- hideControls: true,
374
- resetOnEnd: false,
375
- debug: false
376
- });
377
-
378
- // Define media source (replace with actual media URL in production)
379
- const mediaLink = "YOUR_MEDIA_URL_HERE";
380
- const mediaTitle = "Your Video Title";
381
- const mediaDuration = "01:30:45";
382
- const mediaQuality = "1080p";
383
-
384
- // Initialize loading overlay
385
- const loadingOverlay = document.getElementById('loading-overlay');
386
-
387
- // Set up media and process loading
388
- if (mediaLink) {
389
- document.querySelector('#stream-media source').setAttribute('src', mediaLink);
390
-
391
- // Update video info panel
392
- document.getElementById('video-title').textContent = mediaTitle;
393
- document.getElementById('video-duration').textContent = mediaDuration;
394
- document.getElementById('video-quality').textContent = mediaQuality;
395
-
396
- // Create and add custom buttons
397
- const playerWrapper = player.elements.container.querySelector('.plyr__video-wrapper');
398
-
399
- // Download Button
400
- const downloadButton = document.createElement('div');
401
- downloadButton.className = 'custom-button download-button';
402
- downloadButton.innerHTML = '<i class="fas fa-download"></i>';
403
- downloadButton.setAttribute('aria-label', 'Download video');
404
- downloadButton.setAttribute('title', 'Download video');
405
- downloadButton.onclick = function(event) {
406
- event.stopPropagation();
407
- const link = document.createElement('a');
408
- link.href = mediaLink;
409
- link.download = mediaTitle || 'video';
410
- document.body.appendChild(link);
411
- link.click();
412
- document.body.removeChild(link);
413
- };
414
- playerWrapper.appendChild(downloadButton);
415
-
416
- // Share Button
417
- const shareButton = document.createElement('div');
418
- shareButton.className = 'custom-button share-button';
419
- shareButton.innerHTML = '<i class="fas fa-share-alt"></i>';
420
- shareButton.setAttribute('aria-label', 'Share video');
421
- shareButton.setAttribute('title', 'Share video');
422
- shareButton.onclick = function(event) {
423
- event.stopPropagation();
424
- if (navigator.share) {
425
- navigator.share({
426
- title: mediaTitle || 'Video',
427
- url: window.location.href
428
- }).catch(err => {
429
- console.error('Share failed:', err);
430
- });
431
- } else {
432
- // Fallback for browsers that don't support navigator.share
433
- prompt('Copy this link to share:', window.location.href);
434
- }
435
- };
436
- playerWrapper.appendChild(shareButton);
437
-
438
- // Info Button
439
- const infoButton = document.createElement('div');
440
- infoButton.className = 'custom-button info-button';
441
- infoButton.innerHTML = '<i class="fas fa-info"></i>';
442
- infoButton.setAttribute('aria-label', 'Video information');
443
- infoButton.setAttribute('title', 'Video information');
444
-
445
- const infoPanel = document.getElementById('info-panel');
446
- infoButton.onclick = function(event) {
447
- event.stopPropagation();
448
- infoPanel.classList.toggle('active');
449
- };
450
- playerWrapper.appendChild(infoButton);
451
-
452
- // Hide info panel when clicking elsewhere
453
- document.addEventListener('click', function(event) {
454
- if (!infoButton.contains(event.target) && !infoPanel.contains(event.target)) {
455
- infoPanel.classList.remove('active');
456
- }
457
- });
458
-
459
- // Handle player events
460
- player.on('ready', event => {
461
- console.log('Player is ready');
462
- loadingOverlay.classList.add('hidden');
463
-
464
- // Get actual duration if available
465
- if (player.duration !== Infinity && !isNaN(player.duration)) {
466
- const formatTime = seconds => {
467
- const h = Math.floor(seconds / 3600);
468
- const m = Math.floor((seconds % 3600) / 60);
469
- const s = Math.floor(seconds % 60);
470
- return `${h.toString().padStart(2, '0')}:${m.toString().padStart(2, '0')}:${s.toString().padStart(2, '0')}`;
471
- };
472
- document.getElementById('video-duration').textContent = formatTime(player.duration);
473
- }
474
- });
475
-
476
- player.on('play', () => {
477
- console.log('Video started playing');
478
- });
479
-
480
- player.on('pause', () => {
481
- console.log('Video paused');
482
- });
483
-
484
- player.on('ended', () => {
485
- console.log('Video ended');
486
- });
487
-
488
- player.on('error', error => {
489
- console.error('Player error:', error);
490
- loadingOverlay.classList.add('hidden');
491
- showError('Error loading video. Please try again later.');
492
- });
493
-
494
- // Initialize the player
495
- player.restart();
496
-
497
- } else {
498
- // Handle missing media
499
- loadingOverlay.classList.add('hidden');
500
- showError('Error: Media URL not provided');
501
- }
502
-
503
- // Error display function
504
- function showError(message) {
505
- const errorElement = document.getElementById('error-message');
506
- errorElement.textContent = message;
507
- errorElement.style.display = 'block';
508
- }
509
-
510
- // Add keyboard shortcut info on ctrl press
511
- document.addEventListener('keydown', function(e) {
512
- if (e.key === 'Control') {
513
- document.getElementById('shortcuts-info').style.opacity = '1';
514
- }
515
- });
516
-
517
- document.addEventListener('keyup', function(e) {
518
- if (e.key === 'Control') {
519
- document.getElementById('shortcuts-info').style.opacity = '0';
520
- }
521
- });
522
-
523
- // Handle window resize events for responsive behavior
524
- window.addEventListener('resize', function() {
525
- player.ratio = '16:9';
526
- });
527
- });
528
- </script>
529
- </body>
530
  </html>
 
1
  <!DOCTYPE html>
2
  <html lang="en">
3
+ <head>
4
+ <title>Play Files</title>
5
+
6
+ <meta charset="UTF-8">
7
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
8
+ <meta http-equiv="X-Frame-Options" content="deny">
9
+
10
+ <link rel="stylesheet" href="https://cdn.plyr.io/3.7.8/plyr.css" />
11
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
12
+
13
+ <script src="https://cdn.plyr.io/3.7.8/plyr.polyfilled.js"></script>
14
+
15
+ <style>
16
+ html, body {
17
+ margin: 0;
18
+ height: 100%;
19
+ }
20
+
21
+ #stream-media {
22
+ height: 100%;
23
+ width: 100%;
24
+ }
25
+
26
+ #error-message {
27
+ color: red;
28
+ font-size: 24px;
29
+ text-align: center;
30
+ margin-top: 20px;
31
+ }
32
+
33
+ .plyr__video-wrapper .plyr-download-button{
34
+ position: absolute;
35
+ top: 10px;
36
+ left: 10px;
37
+ width: 30px;
38
+ height: 30px;
39
+ background-color: rgba(0, 0, 0, 0.7);
40
+ border-radius: 50%;
41
+ text-align: center;
42
+ line-height: 30px;
43
+ color: white;
44
+ z-index: 10;
45
+ }
46
+
47
+ .plyr__volume {
48
+ max-width: initial;
49
+ min-width: initial;
50
+ width: auto;
51
+ position: relative;
52
+ }
53
+
54
+
55
+ .plyr__video-wrapper .plyr-share-button{
56
+ position: absolute;
57
+ top: 50px;
58
+ left: 10px;
59
+ width: 30px;
60
+ height: 30px;
61
+ background-color: rgba(0, 0, 0, 0.7);
62
+ border-radius: 50%;
63
+ text-align: center;
64
+ line-height: 30px;
65
+ color: white;
66
+ z-index: 10;
67
+ }
68
+
69
+ .plyr__video-wrapper .plyr-download-button:hover,
70
+ .plyr__video-wrapper .plyr-share-button:hover{
71
+ background-color: rgba(255, 255, 255, 0.7);
72
+ color: black;
73
+ }
74
+
75
+ .plyr__video-wrapper .plyr-download-button:before {
76
+ font-family: "Font Awesome 5 Free";
77
+ content: "\f019";
78
+ font-weight: bold;
79
+ }
80
+
81
+ .plyr__video-wrapper .plyr-share-button:before {
82
+ font-family: "Font Awesome 5 Free";
83
+ content: "\f064";
84
+ font-weight: bold;
85
+ }
86
+
87
+ .plyr, .plyr__video-wrapper, .plyr__video-embed iframe {
88
+ height: 100%;
89
+ }
90
+
91
+ </style>
92
+ </head>
93
+
94
+ <body>
95
+ <video id="stream-media" controls preload="auto">
96
+ <source src="" type="">
97
+ <p class="vjs-no-js">
98
+ To view this video please enable JavaScript, and consider upgrading to a web browser that supports HTML5 video
99
+ </p>
100
+ </video>
101
+
102
+ <div id="error-message"></div>
103
+
104
+ <script>
105
+ var player = new Plyr('#stream-media', {
106
+ controls:['play-large', 'rewind', 'play', 'fast-forward', 'progress', 'current-time', 'mute', 'settings', 'pip', 'fullscreen'],
107
+ settings:['speed','loop'],
108
+ speed:{selected:1,options:[0.25,0.5,0.75,1,1.25,1.5,1.75,2]},
109
+ seek: 10,
110
+ keyboard: { focused: true, global: true },
111
+ });
112
+
113
+ var mediaLink = "{{ mediaLink }}";
114
+
115
+ if (mediaLink) {
116
+ document.querySelector('#stream-media source').setAttribute('src', mediaLink);
117
+ player.restart();
118
+
119
+ var downloadButton = document.createElement('div');
120
+ downloadButton.className = 'plyr-download-button';
121
+
122
+ downloadButton.onclick = function() {
123
+ event.stopPropagation();
124
+ var link = document.createElement('a');
125
+ link.href = mediaLink;
126
+ document.body.appendChild(link);
127
+ link.click();
128
+ document.body.removeChild(link);
129
+ };
130
+
131
+ player.elements.container.querySelector('.plyr__video-wrapper').appendChild(downloadButton);
132
+
133
+ var shareButton = document.createElement('div');
134
+ shareButton.className = 'plyr-share-button';
135
+
136
+ shareButton.onclick = function() {
137
+ event.stopPropagation();
138
+ if (navigator.share) {
139
+ navigator.share({
140
+ title: "Play",
141
+ url: mediaLink
142
+ });
143
+ }
144
+ };
145
+
146
+ player.elements.container.querySelector('.plyr__video-wrapper').appendChild(shareButton);
147
+
148
+ } else {
149
+ document.getElementById('error-message').textContent = 'Error: Media URL not provided';
150
+ }
151
+ </script>
152
+
153
+ </body>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
154
  </html>