Spaces:
Sleeping
Sleeping
| <html> | |
| <head> | |
| <title>HarshDhane Camera Viewer</title> | |
| <style> | |
| body { | |
| font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; | |
| background: linear-gradient(135deg, #232526, #414345); | |
| margin: 0; | |
| padding: 20px; | |
| min-height: 100vh; | |
| color: white; | |
| text-align: center; | |
| } | |
| .header { | |
| padding: 20px; | |
| margin-bottom: 30px; | |
| background: rgba(0, 0, 0, 0.4); | |
| border-radius: 15px; | |
| max-width: 800px; | |
| margin: 20px auto; | |
| } | |
| h1 { | |
| font-size: 2.8rem; | |
| margin-bottom: 10px; | |
| color: #fdbb2d; | |
| text-shadow: 0 2px 5px rgba(0, 0, 0, 0.5); | |
| } | |
| .subtitle { | |
| font-size: 1.2rem; | |
| opacity: 0.9; | |
| max-width: 600px; | |
| margin: 0 auto 30px; | |
| } | |
| .video-container { | |
| max-width: 800px; | |
| margin: 0 auto; | |
| background: rgba(0, 0, 0, 0.6); | |
| border-radius: 15px; | |
| overflow: hidden; | |
| box-shadow: 0 15px 35px rgba(0, 0, 0, 0.5); | |
| } | |
| .video-feed { | |
| width: 100%; | |
| display: block; | |
| } | |
| .status-bar { | |
| background: rgba(0, 0, 0, 0.8); | |
| padding: 15px; | |
| font-size: 1.1rem; | |
| } | |
| .online-status { | |
| color: #00ff00; | |
| font-weight: bold; | |
| } | |
| .connection-info { | |
| margin-top: 25px; | |
| padding: 15px; | |
| background: rgba(0, 0, 0, 0.3); | |
| border-radius: 10px; | |
| max-width: 800px; | |
| margin: 25px auto; | |
| font-size: 1rem; | |
| } | |
| .source-url { | |
| background: rgba(0, 0, 0, 0.5); | |
| padding: 8px 15px; | |
| border-radius: 5px; | |
| font-family: monospace; | |
| word-break: break-all; | |
| display: inline-block; | |
| margin: 10px 0; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="header"> | |
| <h1>HARSH DHANE CAMERA VIEWER</h1> | |
| <p class="subtitle">Live surveillance feed from HarshDhane Camera System</p> | |
| </div> | |
| <div class="video-container"> | |
| <img class="video-feed" src="{{ camera_url }}/video_feed" alt="Live Camera Feed"> | |
| <div class="status-bar"> | |
| Connection Status: <span class="online-status">● LIVE</span> | Streaming from HarshDhane Camera | |
| </div> | |
| </div> | |
| <div class="connection-info"> | |
| <p>Connected to HarshDhane Camera System</p> | |
| <div class="source-url">{{ camera_url }}/video_feed</div> | |
| <p>Streaming at 30 FPS | Secure Connection 🔒</p> | |
| </div> | |
| <script> | |
| // Auto-reconnect if stream fails | |
| const videoFeed = document.querySelector('.video-feed'); | |
| const statusIndicator = document.querySelector('.online-status'); | |
| function checkStream() { | |
| if (videoFeed.complete && videoFeed.naturalHeight === 0) { | |
| statusIndicator.textContent = '● RECONNECTING'; | |
| statusIndicator.style.color = '#ffcc00'; | |
| console.log('Stream disconnected. Reconnecting...'); | |
| // Add timestamp to bypass cache | |
| videoFeed.src = "{{ camera_url }}/video_feed?" + new Date().getTime(); | |
| // Check again after 2 seconds | |
| setTimeout(() => { | |
| if (videoFeed.complete && videoFeed.naturalHeight > 0) { | |
| statusIndicator.textContent = '● LIVE'; | |
| statusIndicator.style.color = '#00ff00'; | |
| } else { | |
| statusIndicator.textContent = '● OFFLINE'; | |
| statusIndicator.style.color = '#ff0000'; | |
| } | |
| }, 2000); | |
| } | |
| } | |
| // Check stream every 5 seconds | |
| setInterval(checkStream, 5000); | |
| // Initial check | |
| window.addEventListener('load', () => { | |
| setTimeout(checkStream, 3000); | |
| }); | |
| </script> | |
| </body> | |
| </html> |