zp1112 commited on
Commit
364776e
·
verified ·
1 Parent(s): 4be5f4a

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. index.html +617 -19
index.html CHANGED
@@ -1,19 +1,617 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
6
+ <title>Modern Mobile H5 Video Player</title>
7
+ <!-- FontAwesome for Icons -->
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
+
10
+ <style>
11
+ :root {
12
+ --primary-color: #3b82f6;
13
+ --primary-glow: rgba(59, 130, 246, 0.5);
14
+ --bg-dark: #0f172a;
15
+ --bg-panel: rgba(30, 41, 59, 0.8);
16
+ --text-main: #f8fafc;
17
+ --text-muted: #94a3b8;
18
+ --control-height: 60px;
19
+ --radius: 12px;
20
+ }
21
+
22
+ * {
23
+ box-sizing: border-box;
24
+ margin: 0;
25
+ padding: 0;
26
+ -webkit-tap-highlight-color: transparent;
27
+ }
28
+
29
+ body {
30
+ font-family: 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
31
+ background-color: var(--bg-dark);
32
+ color: var(--text-main);
33
+ height: 100vh;
34
+ display: flex;
35
+ flex-direction: column;
36
+ overflow: hidden; /* Prevent scrolling on mobile */
37
+ }
38
+
39
+ /* --- Header --- */
40
+ header {
41
+ padding: 15px 20px;
42
+ background: rgba(15, 23, 42, 0.9);
43
+ backdrop-filter: blur(10px);
44
+ display: flex;
45
+ justify-content: space-between;
46
+ align-items: center;
47
+ border-bottom: 1px solid rgba(255, 255, 255, 0.1);
48
+ z-index: 100;
49
+ }
50
+
51
+ .brand {
52
+ font-weight: 700;
53
+ font-size: 1.1rem;
54
+ display: flex;
55
+ align-items: center;
56
+ gap: 10px;
57
+ }
58
+
59
+ .brand i {
60
+ color: var(--primary-color);
61
+ }
62
+
63
+ .built-with {
64
+ font-size: 0.8rem;
65
+ color: var(--text-muted);
66
+ text-decoration: none;
67
+ transition: color 0.3s ease;
68
+ }
69
+
70
+ .built-with:hover {
71
+ color: var(--primary-color);
72
+ }
73
+
74
+ /* --- Main Video Area --- */
75
+ main {
76
+ flex: 1;
77
+ display: flex;
78
+ justify-content: center;
79
+ align-items: center;
80
+ padding: 20px;
81
+ position: relative;
82
+ background: radial-gradient(circle at center, #1e293b 0%, #0f172a 100%);
83
+ }
84
+
85
+ .player-container {
86
+ width: 100%;
87
+ max-width: 800px;
88
+ aspect-ratio: 16 / 9;
89
+ background: #000;
90
+ border-radius: var(--radius);
91
+ box-shadow: 0 20px 50px -12px rgba(0, 0, 0, 0.7);
92
+ position: relative;
93
+ overflow: hidden;
94
+ border: 1px solid rgba(255, 255, 255, 0.05);
95
+ }
96
+
97
+ video {
98
+ width: 100%;
99
+ height: 100%;
100
+ display: block;
101
+ object-fit: contain; /* Ensures video fits without cropping */
102
+ }
103
+
104
+ /* --- Controls Overlay --- */
105
+ .controls-overlay {
106
+ position: absolute;
107
+ bottom: 0;
108
+ left: 0;
109
+ width: 100%;
110
+ padding: 20px;
111
+ background: linear-gradient(to top, rgba(0,0,0,0.9), transparent);
112
+ opacity: 0;
113
+ transition: opacity 0.3s ease;
114
+ display: flex;
115
+ flex-direction: column;
116
+ gap: 10px;
117
+ }
118
+
119
+ /* Show controls on hover or when playing */
120
+ .player-container:hover .controls-overlay,
121
+ .controls-overlay.active {
122
+ opacity: 1;
123
+ }
124
+
125
+ /* --- Progress Bar --- */
126
+ .progress-container {
127
+ width: 100%;
128
+ height: 5px;
129
+ background: rgba(255, 255, 255, 0.2);
130
+ border-radius: 5px;
131
+ cursor: pointer;
132
+ position: relative;
133
+ transition: height 0.2s;
134
+ }
135
+
136
+ .progress-container:hover {
137
+ height: 8px;
138
+ }
139
+
140
+ .progress-fill {
141
+ height: 100%;
142
+ background: var(--primary-color);
143
+ border-radius: 5px;
144
+ width: 0%;
145
+ position: relative;
146
+ box-shadow: 0 0 10px var(--primary-glow);
147
+ }
148
+
149
+ .progress-thumb {
150
+ width: 14px;
151
+ height: 14px;
152
+ background: #fff;
153
+ border-radius: 50%;
154
+ position: absolute;
155
+ right: -7px;
156
+ top: 50%;
157
+ transform: translateY(-50%) scale(0);
158
+ transition: transform 0.2s;
159
+ }
160
+
161
+ .progress-container:hover .progress-thumb {
162
+ transform: translateY(-50%) scale(1);
163
+ }
164
+
165
+ /* --- Control Buttons Row --- */
166
+ .controls-row {
167
+ display: flex;
168
+ justify-content: space-between;
169
+ align-items: center;
170
+ }
171
+
172
+ .left-controls, .right-controls {
173
+ display: flex;
174
+ align-items: center;
175
+ gap: 15px;
176
+ }
177
+
178
+ .btn-control {
179
+ background: none;
180
+ border: none;
181
+ color: var(--text-main);
182
+ font-size: 1.2rem;
183
+ cursor: pointer;
184
+ display: flex;
185
+ align-items: center;
186
+ justify-content: center;
187
+ width: 36px;
188
+ height: 36px;
189
+ border-radius: 50%;
190
+ transition: background 0.2s, transform 0.1s;
191
+ }
192
+
193
+ .btn-control:hover {
194
+ background: rgba(255, 255, 255, 0.1);
195
+ }
196
+
197
+ .btn-control:active {
198
+ transform: scale(0.95);
199
+ }
200
+
201
+ .btn-play {
202
+ width: 44px;
203
+ height: 44px;
204
+ background: rgba(255, 255, 255, 0.15);
205
+ backdrop-filter: blur(5px);
206
+ }
207
+
208
+ .btn-play:hover {
209
+ background: var(--primary-color);
210
+ box-shadow: 0 0 15px var(--primary-glow);
211
+ }
212
+
213
+ /* --- Volume Slider --- */
214
+ .volume-container {
215
+ display: flex;
216
+ align-items: center;
217
+ gap: 8px;
218
+ width: 100px;
219
+ }
220
+
221
+ .volume-slider {
222
+ -webkit-appearance: none;
223
+ width: 100%;
224
+ height: 4px;
225
+ background: rgba(255, 255, 255, 0.2);
226
+ border-radius: 2px;
227
+ outline: none;
228
+ }
229
+
230
+ .volume-slider::-webkit-slider-thumb {
231
+ -webkit-appearance: none;
232
+ width: 12px;
233
+ height: 12px;
234
+ background: #fff;
235
+ border-radius: 50%;
236
+ cursor: pointer;
237
+ display: none; /* Hidden unless hovered */
238
+ }
239
+
240
+ .volume-container:hover .volume-slider::-webkit-slider-thumb {
241
+ display: block;
242
+ }
243
+
244
+ /* --- Time Display --- */
245
+ .time-display {
246
+ font-size: 0.85rem;
247
+ color: var(--text-muted);
248
+ font-variant-numeric: tabular-nums;
249
+ min-width: 100px;
250
+ text-align: right;
251
+ }
252
+
253
+ /* --- Upload Section --- */
254
+ .upload-section {
255
+ padding: 10px 20px 20px;
256
+ text-align: center;
257
+ }
258
+
259
+ .file-input-wrapper {
260
+ position: relative;
261
+ overflow: hidden;
262
+ display: inline-block;
263
+ }
264
+
265
+ .file-input-btn {
266
+ border: 1px dashed var(--text-muted);
267
+ color: var(--text-muted);
268
+ background: transparent;
269
+ padding: 10px 20px;
270
+ border-radius: 20px;
271
+ cursor: pointer;
272
+ font-size: 0.9rem;
273
+ transition: all 0.3s;
274
+ display: flex;
275
+ align-items: center;
276
+ gap: 8px;
277
+ }
278
+
279
+ .file-input-btn:hover {
280
+ border-color: var(--primary-color);
281
+ color: var(--primary-color);
282
+ }
283
+
284
+ input[type=file] {
285
+ font-size: 100px;
286
+ position: absolute;
287
+ left: 0;
288
+ top: 0;
289
+ opacity: 0;
290
+ cursor: pointer;
291
+ }
292
+
293
+ /* --- Loading Spinner --- */
294
+ .spinner {
295
+ position: absolute;
296
+ top: 50%;
297
+ left: 50%;
298
+ transform: translate(-50%, -50%);
299
+ color: var(--primary-color);
300
+ font-size: 3rem;
301
+ display: none;
302
+ z-index: 5;
303
+ }
304
+
305
+ /* --- Fullscreen --- */
306
+ .player-container:fullscreen {
307
+ border-radius: 0;
308
+ }
309
+
310
+ .player-container:fullscreen video {
311
+ object-fit: contain;
312
+ }
313
+
314
+ /* Mobile Specific Adjustments */
315
+ @media (max-width: 600px) {
316
+ .player-container {
317
+ border-radius: 0;
318
+ width: 100vw;
319
+ height: 100vh; /* Full screen video on mobile */
320
+ max-width: 100%;
321
+ position: absolute;
322
+ top: 0;
323
+ left: 0;
324
+ }
325
+
326
+ main {
327
+ padding: 0;
328
+ display: block;
329
+ }
330
+
331
+ header {
332
+ position: absolute;
333
+ top: 0;
334
+ width: 100%;
335
+ z-index: 50;
336
+ background: rgba(15, 23, 42, 0.5);
337
+ }
338
+
339
+ .controls-overlay {
340
+ background: linear-gradient(to top, rgba(0,0,0,0.95), transparent);
341
+ padding: 30px 20px 20px;
342
+ }
343
+
344
+ .time-display {
345
+ position: absolute;
346
+ bottom: 80px;
347
+ left: 20px;
348
+ right: 20px;
349
+ text-align: left;
350
+ text-shadow: 0 1px 2px rgba(0,0,0,0.8);
351
+ z-index: 10;
352
+ }
353
+
354
+ .volume-container {
355
+ width: 60px;
356
+ }
357
+ }
358
+ </style>
359
+ </head>
360
+ <body>
361
+
362
+ <header>
363
+ <div class="brand">
364
+ <i class="fa-solid fa-play-circle"></i>
365
+ <span>FlexPlayer</span>
366
+ </div>
367
+ <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="built-with">Built with anycoder</a>
368
+ </header>
369
+
370
+ <main>
371
+ <div class="player-container" id="playerContainer">
372
+ <!-- Default Sample Video -->
373
+ <video id="videoPlayer" poster="https://images.pexels.com/photos/3129671/pexels-photo-3129671.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1">
374
+ <source src="https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4" type="video/mp4">
375
+ Your browser does not support the video tag.
376
+ </video>
377
+
378
+ <div class="spinner" id="loadingSpinner">
379
+ <i class="fa-solid fa-circle-notch fa-spin"></i>
380
+ </div>
381
+
382
+ <div class="controls-overlay" id="controlsOverlay">
383
+ <!-- Progress -->
384
+ <div class="progress-container" id="progressContainer">
385
+ <div class="progress-fill" id="progressFill">
386
+ <div class="progress-thumb"></div>
387
+ </div>
388
+ </div>
389
+
390
+ <!-- Controls Row -->
391
+ <div class="controls-row">
392
+ <div class="left-controls">
393
+ <button class="btn-control btn-play" id="playPauseBtn" aria-label="Play/Pause">
394
+ <i class="fa-solid fa-play"></i>
395
+ </button>
396
+
397
+ <button class="btn-control" id="muteBtn" aria-label="Mute">
398
+ <i class="fa-solid fa-volume-high"></i>
399
+ </button>
400
+
401
+ <div class="volume-container">
402
+ <input type="range" class="volume-slider" id="volumeSlider" min="0" max="1" step="0.1" value="1">
403
+ </div>
404
+
405
+ <div class="time-display">
406
+ <span id="currentTime">0:00</span> / <span id="duration">0:00</span>
407
+ </div>
408
+ </div>
409
+
410
+ <div class="right-controls">
411
+ <button class="btn-control" id="pipBtn" aria-label="Picture in Picture">
412
+ <i class="fa-solid fa-clone"></i>
413
+ </button>
414
+ <button class="btn-control" id="fsBtn" aria-label="Fullscreen">
415
+ <i class="fa-solid fa-expand"></i>
416
+ </button>
417
+ </div>
418
+ </div>
419
+ </div>
420
+ </div>
421
+ </main>
422
+
423
+ <div class="upload-section">
424
+ <div class="file-input-wrapper">
425
+ <button class="file-input-btn">
426
+ <i class="fa-solid fa-upload"></i> Load Local Video
427
+ </button>
428
+ <input type="file" id="videoUpload" accept="video/*">
429
+ </div>
430
+ </div>
431
+
432
+ <script>
433
+ document.addEventListener('DOMContentLoaded', () => {
434
+ const video = document.getElementById('videoPlayer');
435
+ const container = document.getElementById('playerContainer');
436
+ const playPauseBtn = document.getElementById('playPauseBtn');
437
+ const muteBtn = document.getElementById('muteBtn');
438
+ const volumeSlider = document.getElementById('volumeSlider');
439
+ const progressContainer = document.getElementById('progressContainer');
440
+ const progressFill = document.getElementById('progressFill');
441
+ const currentTimeEl = document.getElementById('currentTime');
442
+ const durationEl = document.getElementById('duration');
443
+ const fsBtn = document.getElementById('fsBtn');
444
+ const pipBtn = document.getElementById('pipBtn');
445
+ const uploadInput = document.getElementById('videoUpload');
446
+ const spinner = document.getElementById('loadingSpinner');
447
+
448
+ // --- Utility Functions ---
449
+
450
+ // Format seconds to MM:SS
451
+ function formatTime(seconds) {
452
+ if (isNaN(seconds)) return "0:00";
453
+ const m = Math.floor(seconds / 60);
454
+ const s = Math.floor(seconds % 60);
455
+ return `${m}:${s < 10 ? '0' : ''}${s}`;
456
+ }
457
+
458
+ // --- Video Control Logic ---
459
+
460
+ function togglePlay() {
461
+ if (video.paused || video.ended) {
462
+ video.play();
463
+ playPauseBtn.innerHTML = '<i class="fa-solid fa-pause"></i>';
464
+ } else {
465
+ video.pause();
466
+ playPauseBtn.innerHTML = '<i class="fa-solid fa-play"></i>';
467
+ }
468
+ }
469
+
470
+ function updatePlayButtonIcon() {
471
+ if (video.paused) {
472
+ playPauseBtn.innerHTML = '<i class="fa-solid fa-play"></i>';
473
+ } else {
474
+ playPauseBtn.innerHTML = '<i class="fa-solid fa-pause"></i>';
475
+ }
476
+ }
477
+
478
+ function updateProgress() {
479
+ const percent = (video.currentTime / video.duration) * 100;
480
+ progressFill.style.width = `${percent}%`;
481
+ currentTimeEl.textContent = formatTime(video.currentTime);
482
+ }
483
+
484
+ function setProgress(e) {
485
+ const width = progressContainer.clientWidth;
486
+ const clickX = e.offsetX;
487
+ const duration = video.duration;
488
+ video.currentTime = (clickX / width) * duration;
489
+ }
490
+
491
+ function toggleMute() {
492
+ video.muted = !video.muted;
493
+ if (video.muted) {
494
+ muteBtn.innerHTML = '<i class="fa-solid fa-volume-xmark"></i>';
495
+ volumeSlider.value = 0;
496
+ } else {
497
+ muteBtn.innerHTML = '<i class="fa-solid fa-volume-high"></i>';
498
+ volumeSlider.value = video.volume;
499
+ }
500
+ }
501
+
502
+ function updateVolume() {
503
+ video.volume = volumeSlider.value;
504
+ video.muted = false;
505
+ if (video.volume === 0) {
506
+ muteBtn.innerHTML = '<i class="fa-solid fa-volume-xmark"></i>';
507
+ } else if (video.volume < 0.5) {
508
+ muteBtn.innerHTML = '<i class="fa-solid fa-volume-low"></i>';
509
+ } else {
510
+ muteBtn.innerHTML = '<i class="fa-solid fa-volume-high"></i>';
511
+ }
512
+ }
513
+
514
+ // --- Fullscreen Logic ---
515
+
516
+ function toggleFullscreen() {
517
+ if (!document.fullscreenElement) {
518
+ container.requestFullscreen().catch(err => {
519
+ alert(`Error attempting to enable full-screen mode: ${err.message} (${err.name})`);
520
+ });
521
+ } else {
522
+ document.exitFullscreen();
523
+ }
524
+ }
525
+
526
+ // --- Pip Logic ---
527
+
528
+ async function togglePiP() {
529
+ try {
530
+ if (video !== document.pictureInPictureElement) {
531
+ await video.requestPictureInPicture();
532
+ } else {
533
+ await document.exitPictureInPicture();
534
+ }
535
+ } catch (error) {
536
+ console.error("PiP Error:", error);
537
+ }
538
+ }
539
+
540
+ // --- Event Listeners ---
541
+
542
+ playPauseBtn.addEventListener('click', togglePlay);
543
+
544
+ // Auto hide controls on mobile after 3 seconds of inactivity
545
+ let controlsTimeout;
546
+ const showControls = () => {
547
+ document.getElementById('controlsOverlay').classList.add('active');
548
+ clearTimeout(controlsTimeout);
549
+ // On mobile, keep controls visible longer or until play
550
+ if(window.innerWidth <= 600) {
551
+ // Don't auto hide on mobile to ensure usability
552
+ } else {
553
+ controlsTimeout = setTimeout(() => {
554
+ if (!video.paused) {
555
+ document.getElementById('controlsOverlay').classList.remove('active');
556
+ }
557
+ }, 3000);
558
+ }
559
+ };
560
+
561
+ video.addEventListener('click', togglePlay);
562
+ video.addEventListener('play', () => {
563
+ updatePlayButtonIcon();
564
+ showControls();
565
+ });
566
+ video.addEventListener('pause', () => {
567
+ updatePlayButtonIcon();
568
+ showControls();
569
+ });
570
+
571
+ video.addEventListener('timeupdate', updateProgress);
572
+ video.addEventListener('loadedmetadata', () => {
573
+ durationEl.textContent = formatTime(video.duration);
574
+ });
575
+
576
+ progressContainer.addEventListener('click', setProgress);
577
+
578
+ muteBtn.addEventListener('click', toggleMute);
579
+ volumeSlider.addEventListener('input', updateVolume);
580
+
581
+ fsBtn.addEventListener('click', toggleFullscreen);
582
+ pipBtn.addEventListener('click', togglePiP);
583
+
584
+ // Handle fullscreen changes
585
+ document.addEventListener('fullscreenchange', () => {
586
+ const icon = fsBtn.querySelector('i');
587
+ if (document.fullscreenElement) {
588
+ icon.classList.remove('fa-expand');
589
+ icon.classList.add('fa-compress');
590
+ } else {
591
+ icon.classList.remove('fa-compress');
592
+ icon.classList.add('fa-expand');
593
+ }
594
+ });
595
+
596
+ // Handle File Upload
597
+ uploadInput.addEventListener('change', function() {
598
+ const file = this.files[0];
599
+ if (file) {
600
+ const fileURL = URL.createObjectURL(file);
601
+ video.src = fileURL;
602
+ video.play();
603
+ updatePlayButtonIcon();
604
+ }
605
+ });
606
+
607
+ // Keyboard Shortcuts
608
+ document.addEventListener('keydown', (e) => {
609
+ if (e.code === 'Space' && e.target.tagName !== 'INPUT') {
610
+ e.preventDefault();
611
+ togglePlay();
612
+ }
613
+ });
614
+ });
615
+ </script>
616
+ </body>
617
+ </html>