Subham9126 commited on
Commit
77bca8d
·
verified ·
1 Parent(s): f19ddb9

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +149 -292
index.html CHANGED
@@ -3,326 +3,183 @@
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Video Hub - Private Collection</title>
7
- <script src="https://cdn.tailwindcss.com"></script>
8
- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
  <style>
10
- .video-container {
11
- aspect-ratio: 16/9;
 
 
12
  }
13
- .video-thumbnail {
14
- transition: all 0.3s ease;
 
 
 
 
15
  }
16
- .video-thumbnail:hover {
17
- transform: scale(1.03);
18
- box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1);
 
 
 
19
  }
20
- .scrollbar-hide::-webkit-scrollbar {
21
- display: none;
 
 
 
 
22
  }
23
- .scrollbar-hide {
24
- -ms-overflow-style: none;
25
- scrollbar-width: none;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  }
27
  </style>
 
 
28
  </head>
29
- <body class="bg-gray-900 text-gray-100 min-h-screen">
30
- <div class="container mx-auto px-4 py-8">
31
- <!-- Header -->
32
- <header class="flex flex-col md:flex-row justify-between items-center mb-8 gap-4">
33
- <div class="flex items-center gap-3">
34
- <i class="fas fa-video text-purple-500 text-3xl"></i>
35
- <h1 class="text-2xl md:text-3xl font-bold bg-gradient-to-r from-purple-500 to-pink-500 bg-clip-text text-transparent">
36
- Solo Leveling Video Hub
37
- </h1>
38
- </div>
39
-
40
- <div class="relative w-full md:w-64">
41
- <input
42
- type="text"
43
- id="searchInput"
44
- placeholder="Search videos..."
45
- class="w-full bg-gray-800 rounded-lg px-4 py-2 pl-10 focus:outline-none focus:ring-2 focus:ring-purple-500"
46
- >
47
- <i class="fas fa-search absolute left-3 top-3 text-gray-400"></i>
48
- </div>
49
- </header>
50
 
51
- <!-- Main Content -->
52
- <main>
53
- <!-- Video Player Section -->
54
- <section id="playerSection" class="hidden mb-8 bg-gray-800 rounded-xl overflow-hidden shadow-xl">
55
- <div class="video-container w-full bg-black">
56
- <video
57
- id="mainVideoPlayer"
58
- controls
59
- class="w-full h-full"
60
- poster="https://images.unsplash.com/photo-1579373903781-fd5c0c30c4cd?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1974&q=80"
61
- >
62
- Your browser does not support the video tag.
63
- </video>
64
- </div>
65
- <div class="p-4">
66
- <h2 id="videoTitle" class="text-xl font-bold mb-2">Select a video to play</h2>
67
- <div class="flex justify-between items-center">
68
- <div id="videoInfo" class="text-gray-400 text-sm">
69
- <span id="currentTime">00:00</span> / <span id="duration">00:00</span>
70
- </div>
71
- <div class="flex gap-2">
72
- <button id="fullscreenBtn" class="bg-gray-700 hover:bg-gray-600 px-3 py-1 rounded-lg">
73
- <i class="fas fa-expand"></i>
74
- </button>
75
- </div>
76
- </div>
77
- </div>
78
- </section>
79
 
80
- <!-- Video List Section -->
81
- <section>
82
- <h2 class="text-xl font-semibold mb-4 flex items-center gap-2">
83
- <i class="fas fa-list"></i>
84
- Video Collection
85
- </h2>
86
-
87
- <div id="videoGrid" class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4">
88
- <!-- Videos will be loaded here -->
89
- </div>
90
-
91
- <div id="loadingIndicator" class="text-center py-8">
92
- <i class="fas fa-spinner fa-spin text-2xl text-purple-500"></i>
93
- <p class="mt-2">Loading videos...</p>
94
- </div>
95
-
96
- <div id="noResults" class="hidden text-center py-8">
97
- <i class="fas fa-video-slash text-2xl text-gray-500"></i>
98
- <p class="mt-2 text-gray-400">No videos found matching your search</p>
99
- </div>
100
- </section>
101
- </main>
102
 
103
- <!-- Footer -->
104
- <footer class="mt-12 pt-6 border-t border-gray-800 text-center text-gray-500 text-sm">
105
- <p>Private Video Hub - For authorized use only</p>
106
- <p class="mt-1" 2023 Solo Leveling Collection. All rights reserved.</p>
107
- </footer>
108
  </div>
109
 
110
  <script>
111
- // Video database (would normally be fetched from database.json)
112
- const videoDatabase = {
113
- "videos": [
114
- {
115
- "title": "E02",
116
- "url": "https://huggingface.co/Subham9126/DB/blob/main/E05/output.m3u8"
117
- },
118
- {
119
- "title": "E03",
120
- "url": "https://huggingface.co/Subham9126/DB/resolve/main/Solo.Leveling.Arise.from.the.Shadow.S02E03.1080p.WEB-DL.Hindi.2.0-English.2.0.ESub.x264-HDHub4u.Tv.mkv?download=true"
121
- },
122
- {
123
- "title": "E04",
124
- "url": "https://huggingface.co/Subham9126/DB/resolve/main/Solo.Leveling.Arise.from.the.Shadow.S02E04.1080p.WEB-DL.Hindi.2.0-English.2.0.ESub.x264-HDHub4u.Tv.mkv"
125
- },
126
- {
127
- "title": "E05",
128
- "url": "https://huggingface.co/Subham9126/DB/resolve/main/Solo.Leveling.Arise.from.the.Shadow.S02E05.1080p.WEB-DL.Hindi.2.0-English.2.0.ESub.x264-HDHub4u.Tv.mkv"
129
- },
130
- {
131
- "title": "Recurrent Neural Networks",
132
- "url": "https://pub-ae4961d7376541d7ac8c9c9f32eed981.r2.dev/Solo.Leveling.Arise.from.the.Shadow.S02E04.1080p.WEB-DL.Hindi.2.0-English.2.0.ESub.x264-HDHub4u.Tv.mkv"
133
- },
134
- {
135
- "title": "Transformers Architecture",
136
- "url": "https://pub-ae4961d7376541d7ac8c9c9f32eed981.r2.dev/Solo.Leveling.Arise.from.the.Shadow.S02E05.1080p.WEB-DL.Hindi.2.0-English.2.0.ESub.x264-HDHub4u.Tv.mkv"
137
- },
138
- {
139
- "title": "Natural Language Processing",
140
- "url": "https://pub-ae4961d7376541d7ac8c9c9f32eed981.r2.dev/Solo.Leveling.Arise.from.the.Shadow.S02E06.1080p.WEB-DL.Hindi.2.0-English.2.0.ESub.x264-HDHub4u.Tv.mkv"
141
- },
142
- {
143
- "title": "Computer Vision Basics",
144
- "url": "https://huggingface.co/username/model-repo/resolve/main/cv-basics.mp4"
145
- },
146
- {
147
- "title": "Object Detection Methods",
148
- "url": "https://huggingface.co/username/model-repo/resolve/main/object-detection.mp4"
149
- },
150
- {
151
- "title": "Image Segmentation Techniques",
152
- "url": "https://huggingface.co/username/model-repo/resolve/main/segmentation.mp4"
153
- },
154
- {
155
- "title": "Reinforcement Learning",
156
- "url": "https://huggingface.co/username/model-repo/resolve/main/rl.mp4"
157
- },
158
- {
159
- "title": "Transfer Learning",
160
- "url": "https://huggingface.co/username/model-repo/resolve/main/transfer-learning.mp4"
161
- },
162
- {
163
- "title": "GANs: Generative Adversarial Networks",
164
- "url": "https://huggingface.co/username/model-repo/resolve/main/gans.mp4"
165
- },
166
- {
167
- "title": "Diffusion Models Explained",
168
- "url": "https://huggingface.co/username/model-repo/resolve/main/diffusion.mp4"
169
- },
170
- {
171
- "title": "Training Large Language Models",
172
- "url": "https://huggingface.co/username/model-repo/resolve/main/llm-training.mp4"
173
- },
174
- {
175
- "title": "Python for Data Science",
176
- "url": "https://huggingface.co/username/model-repo/resolve/main/python-ds.mp4"
177
- },
178
- {
179
- "title": "TensorFlow Tutorial",
180
- "url": "https://huggingface.co/username/model-repo/resolve/main/tensorflow.mp4"
181
- },
182
- {
183
- "title": "PyTorch Basics",
184
- "url": "https://huggingface.co/username/model-repo/resolve/main/pytorch.mp4"
185
- },
186
- {
187
- "title": "Deploying ML Models",
188
- "url": "https://huggingface.co/username/model-repo/resolve/main/deployment.mp4"
189
- },
190
- {
191
- "title": "MLOps Introduction",
192
- "url": "https://huggingface.co/username/model-repo/resolve/main/mlops.mp4"
193
- },
194
- {
195
- "title": "Big Buck Bunny (Sample)",
196
- "url": "https://storage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"
197
- },
198
- {
199
- "title": "Sintel (Sample)",
200
- "url": "https://storage.googleapis.com/gtv-videos-bucket/sample/Sintel.mp4"
201
- }
202
- ]
203
- };
204
 
205
- // DOM Elements
206
- const videoGrid = document.getElementById('videoGrid');
207
- const loadingIndicator = document.getElementById('loadingIndicator');
208
- const noResults = document.getElementById('noResults');
209
- const searchInput = document.getElementById('searchInput');
210
- const playerSection = document.getElementById('playerSection');
211
- const mainVideoPlayer = document.getElementById('mainVideoPlayer');
212
- const videoTitle = document.getElementById('videoTitle');
213
- const currentTime = document.getElementById('currentTime');
214
- const duration = document.getElementById('duration');
215
- const fullscreenBtn = document.getElementById('fullscreenBtn');
216
 
217
- // Initialize the app
218
- document.addEventListener('DOMContentLoaded', () => {
219
- // Load videos
220
- setTimeout(() => {
221
- loadVideos(videoDatabase.videos);
222
- }, 800); // Simulate loading delay
223
-
224
- // Setup event listeners
225
- searchInput.addEventListener('input', handleSearch);
226
- fullscreenBtn.addEventListener('click', toggleFullscreen);
227
-
228
- // Video player time updates
229
- mainVideoPlayer.addEventListener('timeupdate', updateVideoTime);
230
- mainVideoPlayer.addEventListener('loadedmetadata', () => {
231
- duration.textContent = formatTime(mainVideoPlayer.duration);
232
- });
233
- });
234
 
235
- // Load videos into the grid
236
- function loadVideos(videos) {
237
- loadingIndicator.classList.add('hidden');
238
-
239
- if (videos.length === 0) {
240
- noResults.classList.remove('hidden');
241
  return;
242
  }
243
-
244
- videoGrid.innerHTML = '';
245
-
246
- videos.forEach(video => {
247
- const videoCard = document.createElement('div');
248
- videoCard.className = 'video-thumbnail bg-gray-800 rounded-lg overflow-hidden cursor-pointer hover:shadow-lg transition-all';
249
- videoCard.innerHTML = `
250
- <div onclick="playVideo('${video.url}', '${video.title.replace(/'/g, "\\'")}')" class="h-full">
251
- <div class="relative pb-[56.25%] bg-gray-700">
252
- <div class="absolute inset-0 flex items-center justify-center">
253
- <i class="fas fa-play text-white text-4xl opacity-80"></i>
254
- </div>
255
- <img src="https://images.unsplash.com/photo-1579373903781-fd5c0c30c4cd?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1974&q=80"
256
- alt="${video.title}"
257
- class="absolute inset-0 w-full h-full object-cover opacity-70">
258
- </div>
259
- <div class="p-3">
260
- <h3 class="font-medium truncate">${video.title}</h3>
261
- <p class="text-xs text-gray-400 mt-1 truncate">${video.url}</p>
262
- </div>
263
- </div>
264
- `;
265
- videoGrid.appendChild(videoCard);
266
- });
267
- }
268
 
269
- // Play selected video
270
- function playVideo(url, title) {
271
- playerSection.classList.remove('hidden');
272
- mainVideoPlayer.src = url;
273
- videoTitle.textContent = title;
274
-
275
- // Scroll to player
276
- playerSection.scrollIntoView({ behavior: 'smooth' });
277
-
278
- // Attempt to play (may be blocked by autoplay policies)
279
- mainVideoPlayer.play().catch(e => {
280
- console.log('Autoplay was prevented:', e);
281
- });
282
- }
283
-
284
- // Handle search functionality
285
- function handleSearch() {
286
- const searchTerm = searchInput.value.toLowerCase();
287
-
288
- if (searchTerm === '') {
289
- loadVideos(videoDatabase.videos);
290
- return;
291
  }
292
-
293
- const filteredVideos = videoDatabase.videos.filter(video =>
294
- video.title.toLowerCase().includes(searchTerm) ||
295
- video.url.toLowerCase().includes(searchTerm)
296
- );
297
-
298
- loadVideos(filteredVideos);
299
- }
300
 
301
- // Update video time display
302
- function updateVideoTime() {
303
- currentTime.textContent = formatTime(mainVideoPlayer.currentTime);
304
- }
305
 
306
- // Format time as MM:SS
307
- function formatTime(seconds) {
308
- const mins = Math.floor(seconds / 60);
309
- const secs = Math.floor(seconds % 60);
310
- return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
311
- }
312
 
313
- // Toggle fullscreen
314
- function toggleFullscreen() {
315
- if (!document.fullscreenElement) {
316
- mainVideoPlayer.requestFullscreen().catch(err => {
317
- console.error(`Error attempting to enable fullscreen: ${err.message}`);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
318
  });
319
- } else {
320
- document.exitFullscreen();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
321
  }
322
  }
323
 
324
- // Make functions available globally
325
- window.playVideo = playVideo;
 
 
 
 
 
 
326
  </script>
 
327
  </body>
328
  </html>
 
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Basic M3U8 Player</title>
 
 
7
  <style>
8
+ body {
9
+ font-family: sans-serif;
10
+ padding: 20px;
11
+ background-color: #f4f4f4;
12
  }
13
+ #player-container {
14
+ margin-top: 20px;
15
+ background-color: #fff;
16
+ padding: 15px;
17
+ border-radius: 5px;
18
+ box-shadow: 0 2px 5px rgba(0,0,0,0.1);
19
  }
20
+ #videoPlayer {
21
+ width: 100%;
22
+ max-width: 800px; /* Adjust as needed */
23
+ background-color: #000; /* Black background for letterboxing */
24
+ display: block; /* Prevents extra space below video */
25
+ margin-top: 10px;
26
  }
27
+ #urlInput {
28
+ width: calc(100% - 100px); /* Adjust width */
29
+ padding: 10px;
30
+ margin-right: 5px;
31
+ border: 1px solid #ccc;
32
+ border-radius: 3px;
33
  }
34
+ #loadButton {
35
+ padding: 10px 15px;
36
+ cursor: pointer;
37
+ background-color: #007bff;
38
+ color: white;
39
+ border: none;
40
+ border-radius: 3px;
41
+ }
42
+ #loadButton:hover {
43
+ background-color: #0056b3;
44
+ }
45
+ #status {
46
+ margin-top: 10px;
47
+ font-style: italic;
48
+ color: #555;
49
+ }
50
+ .error {
51
+ color: red;
52
+ font-weight: bold;
53
  }
54
  </style>
55
+ <!-- 1. Include hls.js library -->
56
+ <script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
57
  </head>
58
+ <body>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
 
60
+ <h1>Basic M3U8 Web Player</h1>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
 
62
+ <div id="player-container">
63
+ <label for="urlInput">M3U8 URL:</label>
64
+ <input type="text" id="urlInput" placeholder="https://example.com/stream.m3u8">
65
+ <button id="loadButton">Load Stream</button>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
 
67
+ <div id="status">Enter an M3U8 URL and click Load.</div>
68
+
69
+ <!-- 2. The Video Element -->
70
+ <video id="videoPlayer" controls></video>
 
71
  </div>
72
 
73
  <script>
74
+ const videoElement = document.getElementById('videoPlayer');
75
+ const urlInput = document.getElementById('urlInput');
76
+ const loadButton = document.getElementById('loadButton');
77
+ const statusDiv = document.getElementById('status');
78
+ let hls = null; // Variable to hold the Hls instance
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
 
80
+ loadButton.addEventListener('click', loadStream);
 
 
 
 
 
 
 
 
 
 
81
 
82
+ function loadStream() {
83
+ const m3u8Url = urlInput.value.trim();
84
+ statusDiv.textContent = ''; // Clear previous status
85
+ statusDiv.classList.remove('error');
 
 
 
 
 
 
 
 
 
 
 
 
 
86
 
87
+ if (!m3u8Url) {
88
+ statusDiv.textContent = 'Please enter an M3U8 URL.';
89
+ statusDiv.classList.add('error');
 
 
 
90
  return;
91
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
 
93
+ // Destroy previous instance if it exists
94
+ if (hls) {
95
+ hls.destroy();
96
+ hls = null;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
  }
 
 
 
 
 
 
 
 
98
 
99
+ // Check if HLS is supported by the browser (using hls.js)
100
+ if (Hls.isSupported()) {
101
+ console.log("HLS.js is supported. Initializing...");
102
+ statusDiv.textContent = 'Loading stream with HLS.js...';
103
 
104
+ hls = new Hls(); // Create a new Hls instance
 
 
 
 
 
105
 
106
+ // Bind error handling
107
+ hls.on(Hls.Events.ERROR, function (event, data) {
108
+ if (data.fatal) {
109
+ switch(data.type) {
110
+ case Hls.ErrorTypes.NETWORK_ERROR:
111
+ console.error('Fatal network error encountered:', data);
112
+ statusDiv.textContent = `Error: Network error - ${data.details}. Check URL and CORS policy.`;
113
+ statusDiv.classList.add('error');
114
+ hls.destroy(); // Clean up on fatal error
115
+ hls = null;
116
+ break;
117
+ case Hls.ErrorTypes.MEDIA_ERROR:
118
+ console.error('Fatal media error encountered:', data);
119
+ statusDiv.textContent = `Error: Media error - ${data.details}. Trying to recover...`;
120
+ statusDiv.classList.add('error');
121
+ hls.recoverMediaError();
122
+ break;
123
+ default:
124
+ // Cannot recover
125
+ console.error('Unrecoverable fatal error:', data);
126
+ statusDiv.textContent = `Error: Unrecoverable error - ${data.details}.`;
127
+ statusDiv.classList.add('error');
128
+ hls.destroy();
129
+ hls = null;
130
+ break;
131
+ }
132
+ } else {
133
+ console.warn('Non-fatal HLS error:', data);
134
+ statusDiv.textContent = `Warning: ${data.details}`;
135
+ statusDiv.classList.remove('error'); // Maybe not a fatal error shown to user
136
+ }
137
  });
138
+
139
+ hls.loadSource(m3u8Url);
140
+ hls.attachMedia(videoElement);
141
+
142
+ hls.on(Hls.Events.MANIFEST_PARSED, function() {
143
+ console.log('Manifest parsed. Ready to play.');
144
+ statusDiv.textContent = 'Stream loaded. Press play!';
145
+ // You could uncomment the next line to autoplay, but user interaction is often required by browsers
146
+ // videoElement.play();
147
+ });
148
+
149
+ }
150
+ // Check for native browser HLS support (e.g., Safari on iOS/macOS)
151
+ else if (videoElement.canPlayType('application/vnd.apple.mpegurl')) {
152
+ console.log("Native HLS support detected (e.g., Safari).");
153
+ statusDiv.textContent = 'Loading stream using native browser support...';
154
+ videoElement.src = m3u8Url;
155
+ videoElement.addEventListener('loadedmetadata', function() {
156
+ console.log('Metadata loaded. Ready to play.');
157
+ statusDiv.textContent = 'Stream loaded. Press play!';
158
+ // videoElement.play(); // Autoplay if desired and allowed
159
+ });
160
+ videoElement.addEventListener('error', function(e) {
161
+ console.error('Native HLS playback error:', e);
162
+ statusDiv.textContent = 'Error loading stream with native player. Check URL/CORS.';
163
+ statusDiv.classList.add('error');
164
+ });
165
+ }
166
+ // HLS is not supported on this browser
167
+ else {
168
+ statusDiv.textContent = 'Error: HLS is not supported in this browser.';
169
+ statusDiv.classList.add('error');
170
+ console.error("HLS is not supported by hls.js or natively.");
171
  }
172
  }
173
 
174
+ // Optional: Add listener to Enter key in input field
175
+ urlInput.addEventListener('keypress', function(event) {
176
+ if (event.key === 'Enter') {
177
+ event.preventDefault(); // Prevent potential form submission
178
+ loadButton.click(); // Trigger the button click
179
+ }
180
+ });
181
+
182
  </script>
183
+
184
  </body>
185
  </html>