Subham9126 commited on
Commit
aa7d607
·
verified ·
1 Parent(s): e5641db

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +181 -16
index.html CHANGED
@@ -249,6 +249,44 @@
249
  grid-column: 1 / -1;
250
  }
251
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
252
  @media (max-width: 768px) {
253
  .video-list {
254
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
@@ -295,6 +333,13 @@
295
  <h1>Video Player</h1>
296
  </header>
297
 
 
 
 
 
 
 
 
298
  <div class="search-container">
299
  <input type="text" id="search" placeholder="Search videos...">
300
  </div>
@@ -307,7 +352,7 @@
307
  <div class="video-player-container" id="playerContainer">
308
  <div class="video-player-wrapper">
309
  <button class="close-player" id="closePlayer">&times;</button>
310
- <video id="videoPlayer"></video>
311
  <div class="player-controls">
312
  <div class="control-group">
313
  <button class="control-btn" id="playPauseBtn">&#9658;</button>
@@ -338,6 +383,8 @@
338
  // Global variables
339
  let videos = [];
340
  let lastTapTime = 0;
 
 
341
 
342
  // DOM elements
343
  const videoListElement = document.getElementById('videoList');
@@ -356,6 +403,10 @@
356
  const volumeSlider = document.getElementById('volumeSlider');
357
  const fullscreenBtn = document.getElementById('fullscreenBtn');
358
  const closePlayer = document.getElementById('closePlayer');
 
 
 
 
359
 
360
  // Load videos from JSON
361
  async function loadVideos() {
@@ -365,7 +416,27 @@
365
  throw new Error('Failed to load videos');
366
  }
367
  videos = await response.json();
368
- displayVideos(videos);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
369
  } catch (error) {
370
  console.error('Error loading videos:', error);
371
  videoListElement.innerHTML = '<div class="no-results">Failed to load videos. Please try again later.</div>';
@@ -401,20 +472,48 @@
401
  }
402
 
403
  // Play selected video
404
- function playVideo(url, title) {
405
- videoPlayer.src = url;
406
- document.title = `${title} - Video Player`;
407
-
408
- // Show player
409
- playerContainer.classList.add('show');
410
-
411
- // Attempt to play (may need user interaction on some browsers)
412
- const playPromise = videoPlayer.play();
413
-
414
- if (playPromise !== undefined) {
415
- playPromise.catch(error => {
416
- console.log('Auto-play prevented:', error);
417
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
418
  }
419
  }
420
 
@@ -423,6 +522,11 @@
423
  videoPlayer.pause();
424
  playerContainer.classList.remove('show');
425
  document.title = 'Video Player';
 
 
 
 
 
426
  }
427
 
428
  // Format time (seconds to MM:SS)
@@ -476,6 +580,7 @@
476
  // Update volume
477
  function updateVolume() {
478
  videoPlayer.volume = volumeSlider.value;
 
479
  if (videoPlayer.volume === 0) {
480
  volumeBtn.innerHTML = '&#128263;';
481
  } else {
@@ -520,6 +625,17 @@
520
  }
521
  }
522
 
 
 
 
 
 
 
 
 
 
 
 
523
  // Handle double tap for skip
524
  function handleDoubleTap(e) {
525
  const currentTime = Date.now();
@@ -543,6 +659,40 @@
543
  lastTapTime = currentTime;
544
  }
545
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
546
  // Event listeners
547
  searchInput.addEventListener('input', () => {
548
  const searchTerm = searchInput.value.toLowerCase();
@@ -558,6 +708,14 @@
558
  });
559
  videoPlayer.addEventListener('click', togglePlayPause);
560
  videoPlayer.addEventListener('dblclick', handleDoubleTap);
 
 
 
 
 
 
 
 
561
 
562
  playPauseBtn.addEventListener('click', togglePlayPause);
563
  skipBackBtn.addEventListener('click', () => skip(-10));
@@ -571,6 +729,13 @@
571
 
572
  fullscreenBtn.addEventListener('click', toggleFullscreen);
573
  closePlayer.addEventListener('click', closeVideoPlayer);
 
 
 
 
 
 
 
574
 
575
  // Keyboard controls
576
  document.addEventListener('keydown', (e) => {
 
249
  grid-column: 1 / -1;
250
  }
251
 
252
+ .auth-container {
253
+ margin: 20px 0;
254
+ padding: 15px;
255
+ background-color: #f8f9fa;
256
+ border-radius: 5px;
257
+ display: none;
258
+ }
259
+
260
+ .auth-container.show {
261
+ display: block;
262
+ }
263
+
264
+ .auth-input {
265
+ width: 100%;
266
+ padding: 10px;
267
+ margin: 10px 0;
268
+ border: 1px solid #ddd;
269
+ border-radius: 4px;
270
+ }
271
+
272
+ .auth-btn {
273
+ background-color: #2c3e50;
274
+ color: white;
275
+ border: none;
276
+ padding: 10px 15px;
277
+ border-radius: 4px;
278
+ cursor: pointer;
279
+ }
280
+
281
+ .auth-btn:hover {
282
+ background-color: #1a252f;
283
+ }
284
+
285
+ .error-message {
286
+ color: #e74c3c;
287
+ margin-top: 10px;
288
+ }
289
+
290
  @media (max-width: 768px) {
291
  .video-list {
292
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
 
333
  <h1>Video Player</h1>
334
  </header>
335
 
336
+ <div class="auth-container" id="authContainer">
337
+ <h3>Private Repository Authentication</h3>
338
+ <input type="text" class="auth-input" id="hfToken" placeholder="Hugging Face Access Token">
339
+ <button class="auth-btn" id="authBtn">Authenticate</button>
340
+ <div class="error-message" id="authError"></div>
341
+ </div>
342
+
343
  <div class="search-container">
344
  <input type="text" id="search" placeholder="Search videos...">
345
  </div>
 
352
  <div class="video-player-container" id="playerContainer">
353
  <div class="video-player-wrapper">
354
  <button class="close-player" id="closePlayer">&times;</button>
355
+ <video id="videoPlayer" crossorigin="anonymous"></video>
356
  <div class="player-controls">
357
  <div class="control-group">
358
  <button class="control-btn" id="playPauseBtn">&#9658;</button>
 
383
  // Global variables
384
  let videos = [];
385
  let lastTapTime = 0;
386
+ let hfToken = null;
387
+ let isPrivateRepo = false;
388
 
389
  // DOM elements
390
  const videoListElement = document.getElementById('videoList');
 
403
  const volumeSlider = document.getElementById('volumeSlider');
404
  const fullscreenBtn = document.getElementById('fullscreenBtn');
405
  const closePlayer = document.getElementById('closePlayer');
406
+ const authContainer = document.getElementById('authContainer');
407
+ const hfTokenInput = document.getElementById('hfToken');
408
+ const authBtn = document.getElementById('authBtn');
409
+ const authError = document.getElementById('authError');
410
 
411
  // Load videos from JSON
412
  async function loadVideos() {
 
416
  throw new Error('Failed to load videos');
417
  }
418
  videos = await response.json();
419
+
420
+ // Check if any video URL contains 'huggingface.co' to determine if we need auth
421
+ isPrivateRepo = videos.some(video =>
422
+ video.url.includes('huggingface.co') &&
423
+ (video.url.includes('/blob/') || video.url.includes('/resolve/'))
424
+ );
425
+
426
+ if (isPrivateRepo) {
427
+ // Check if we already have a token in localStorage
428
+ const storedToken = localStorage.getItem('hfToken');
429
+ if (storedToken) {
430
+ hfToken = storedToken;
431
+ authContainer.classList.remove('show');
432
+ displayVideos(videos);
433
+ } else {
434
+ authContainer.classList.add('show');
435
+ }
436
+ } else {
437
+ authContainer.classList.remove('show');
438
+ displayVideos(videos);
439
+ }
440
  } catch (error) {
441
  console.error('Error loading videos:', error);
442
  videoListElement.innerHTML = '<div class="no-results">Failed to load videos. Please try again later.</div>';
 
472
  }
473
 
474
  // Play selected video
475
+ async function playVideo(url, title) {
476
+ try {
477
+ // For HF Hub videos, modify the URL to use raw content
478
+ let finalUrl = url;
479
+
480
+ if (url.includes('huggingface.co')) {
481
+ // Convert blob/resolve URLs to raw URLs
482
+ finalUrl = url
483
+ .replace('/blob/', '/resolve/')
484
+ .replace('https://huggingface.co/', 'https://cdn-lfs.huggingface.co/');
485
+
486
+ if (isPrivateRepo && hfToken) {
487
+ // Add token for private repos
488
+ finalUrl += `?token=${hfToken}`;
489
+ }
490
+ }
491
+
492
+ // Set the video source
493
+ videoPlayer.src = finalUrl;
494
+ document.title = `${title} - Video Player`;
495
+
496
+ // Show player
497
+ playerContainer.classList.add('show');
498
+
499
+ // Attempt to play (may need user interaction on some browsers)
500
+ const playPromise = videoPlayer.play();
501
+
502
+ if (playPromise !== undefined) {
503
+ playPromise.catch(error => {
504
+ console.log('Auto-play prevented:', error);
505
+ // Show play button to indicate user needs to click
506
+ playPauseBtn.innerHTML = '&#9658;';
507
+ });
508
+ }
509
+
510
+ // Set initial volume
511
+ videoPlayer.volume = volumeSlider.value;
512
+
513
+ } catch (error) {
514
+ console.error('Error playing video:', error);
515
+ alert('Failed to play video. Please check your authentication for private repositories.');
516
+ closeVideoPlayer();
517
  }
518
  }
519
 
 
522
  videoPlayer.pause();
523
  playerContainer.classList.remove('show');
524
  document.title = 'Video Player';
525
+
526
+ // Exit fullscreen if active
527
+ if (document.fullscreenElement) {
528
+ document.exitFullscreen();
529
+ }
530
  }
531
 
532
  // Format time (seconds to MM:SS)
 
580
  // Update volume
581
  function updateVolume() {
582
  videoPlayer.volume = volumeSlider.value;
583
+ videoPlayer.muted = (videoPlayer.volume === 0);
584
  if (videoPlayer.volume === 0) {
585
  volumeBtn.innerHTML = '&#128263;';
586
  } else {
 
625
  }
626
  }
627
 
628
+ // Handle fullscreen change
629
+ function handleFullscreenChange() {
630
+ if (document.fullscreenElement) {
631
+ // When entering fullscreen, ensure video is playing
632
+ if (videoPlayer.paused) {
633
+ videoPlayer.play();
634
+ playPauseBtn.innerHTML = '&#10074;&#10074;';
635
+ }
636
+ }
637
+ }
638
+
639
  // Handle double tap for skip
640
  function handleDoubleTap(e) {
641
  const currentTime = Date.now();
 
659
  lastTapTime = currentTime;
660
  }
661
 
662
+ // Handle authentication
663
+ function handleAuth() {
664
+ const token = hfTokenInput.value.trim();
665
+ if (!token) {
666
+ authError.textContent = 'Please enter a valid Hugging Face access token';
667
+ return;
668
+ }
669
+
670
+ // Test the token with a simple API call
671
+ fetch('https://huggingface.co/api/whoami', {
672
+ headers: {
673
+ 'Authorization': `Bearer ${token}`
674
+ }
675
+ })
676
+ .then(response => {
677
+ if (!response.ok) {
678
+ throw new Error('Invalid token');
679
+ }
680
+ return response.json();
681
+ })
682
+ .then(data => {
683
+ // Token is valid
684
+ hfToken = token;
685
+ localStorage.setItem('hfToken', token);
686
+ authContainer.classList.remove('show');
687
+ authError.textContent = '';
688
+ displayVideos(videos);
689
+ })
690
+ .catch(error => {
691
+ console.error('Authentication failed:', error);
692
+ authError.textContent = 'Authentication failed. Please check your token.';
693
+ });
694
+ }
695
+
696
  // Event listeners
697
  searchInput.addEventListener('input', () => {
698
  const searchTerm = searchInput.value.toLowerCase();
 
708
  });
709
  videoPlayer.addEventListener('click', togglePlayPause);
710
  videoPlayer.addEventListener('dblclick', handleDoubleTap);
711
+ videoPlayer.addEventListener('volumechange', () => {
712
+ volumeSlider.value = videoPlayer.volume;
713
+ if (videoPlayer.muted || videoPlayer.volume === 0) {
714
+ volumeBtn.innerHTML = '&#128263;';
715
+ } else {
716
+ volumeBtn.innerHTML = '&#128266;';
717
+ }
718
+ });
719
 
720
  playPauseBtn.addEventListener('click', togglePlayPause);
721
  skipBackBtn.addEventListener('click', () => skip(-10));
 
729
 
730
  fullscreenBtn.addEventListener('click', toggleFullscreen);
731
  closePlayer.addEventListener('click', closeVideoPlayer);
732
+ authBtn.addEventListener('click', handleAuth);
733
+
734
+ // Fullscreen change events
735
+ document.addEventListener('fullscreenchange', handleFullscreenChange);
736
+ document.addEventListener('webkitfullscreenchange', handleFullscreenChange);
737
+ document.addEventListener('mozfullscreenchange', handleFullscreenChange);
738
+ document.addEventListener('MSFullscreenChange', handleFullscreenChange);
739
 
740
  // Keyboard controls
741
  document.addEventListener('keydown', (e) => {