From 367aa4c67bff63abc39d4560bc1a44bc4d8dca88 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 10 Jan 2026 10:08:17 +0000 Subject: [PATCH] Add Aurora Livecam video player enhancements - Add SettingsManager class for admin settings (settings.json) - Add timelapse controls with slider, speed (1x/10x/100x), and reverse playback - Add daily video player to play videos in main player window - Add admin settings panel for viewer display and video mode configuration - Add CSS styles for new player controls - Include integration guide for existing index.php --- aurora-livecam/INTEGRATION.md | 240 +++++++++++++++++++++ aurora-livecam/SettingsManager.php | 121 +++++++++++ aurora-livecam/css/player-controls.css | 274 ++++++++++++++++++++++++ aurora-livecam/js/admin-settings.js | 140 ++++++++++++ aurora-livecam/js/timelapse-controls.js | 167 +++++++++++++++ aurora-livecam/js/video-player.js | 108 ++++++++++ aurora-livecam/settings.json | 16 ++ 7 files changed, 1066 insertions(+) create mode 100644 aurora-livecam/INTEGRATION.md create mode 100644 aurora-livecam/SettingsManager.php create mode 100644 aurora-livecam/css/player-controls.css create mode 100644 aurora-livecam/js/admin-settings.js create mode 100644 aurora-livecam/js/timelapse-controls.js create mode 100644 aurora-livecam/js/video-player.js create mode 100644 aurora-livecam/settings.json diff --git a/aurora-livecam/INTEGRATION.md b/aurora-livecam/INTEGRATION.md new file mode 100644 index 0000000..92566e4 --- /dev/null +++ b/aurora-livecam/INTEGRATION.md @@ -0,0 +1,240 @@ +# Integration Guide für Aurora Livecam Erweiterungen + +## Übersicht der neuen Dateien + +``` +aurora-livecam/ +├── SettingsManager.php # Admin-Einstellungen Klasse +├── settings.json # Einstellungen Datei +├── js/ +│ ├── timelapse-controls.js # Timelapse mit Slider +│ ├── video-player.js # Tagesvideos im Player +│ └── admin-settings.js # Admin AJAX +├── css/ +│ └── player-controls.css # Styles für Controls +└── INTEGRATION.md # Diese Anleitung +``` + +## Änderungen in index.php + +### 1. Am Anfang der Datei (nach den requires) + +```php +handleAjax(); +``` + +### 2. Im HEAD-Bereich (CSS einbinden) + +```html + +``` + +### 3. Vor (JavaScript einbinden) + +```html + + +isAdmin()): ?> + + +``` + +### 4. Video-Container anpassen + +Ersetze den bestehenden video-container: + +```html +
+ displayWebcam(); ?> + + + + + +
+ + +
+``` + +### 5. Zuschauer-Anzeige konditionell machen + +Ersetze die Viewer-Stat Anzeige: + +```php +getInitialCount(); +$showViewers = $settingsManager->shouldShowViewers($viewerCount); +?> + + +
+ + + Zuschauer +
+ +``` + +### 6. Kalender Links anpassen + +In der `VisualCalendarManager::displayVisualCalendar()` Methode: + +```php +// Für Tagesvideos +$playInPlayer = $settingsManager->shouldPlayInPlayer(); +$allowDownload = $settingsManager->shouldAllowDownload(); + +if ($playInPlayer) { + // Im Player abspielen + $output .= ''; + $output .= '▶️ Abspielen'; + $output .= ''; +} + +if ($allowDownload) { + // Download Link + $output .= '⬇️ Download'; +} +``` + +### 7. Admin-Panel erweitern + +Füge im Admin-Bereich hinzu: + +```php +isAdmin()): ?> +
+
+

Admin-Bereich

+ + +
+

⚙️ Anzeige-Einstellungen

+ +
+

👥 Zuschauer-Anzeige

+ +
+ Zuschauer-Anzahl anzeigen +
+ +
+
+ +
+ Mindestanzahl für Anzeige +
+ +
+
+
+ +
+

🎬 Video-Modus

+ +
+ Videos im Player abspielen +
+ +
+
+ +
+ Download erlauben +
+ +
+
+
+
+ + + displayAdminContent(); ?> +
+
+ +``` + +### 8. Timelapse Button Event anpassen + +Im bestehenden JavaScript: + +```javascript +timelapseButton.addEventListener('click', function(e) { + e.preventDefault(); + + if (timelapseViewer.style.display === 'none') { + // NEU: TimelapseController verwenden + TimelapseController.init(imageFiles); + TimelapseController.show(); + timelapseButton.textContent = 'Zurück zur Live-Webcam'; + } else { + TimelapseController.backToLive(); + } +}); +``` + +### 9. Viewer Heartbeat anpassen + +Im JavaScript für den Viewer-Counter: + +```javascript +function updateViewerCount() { + fetch(window.location.href, { + method: 'POST', + body: new URLSearchParams({action: 'viewer_heartbeat'}) + }) + .then(r => r.json()) + .then(data => { + const display = document.getElementById('viewer-count-display'); + const container = document.querySelector('.viewer-stat'); + + if (data.count && display) { + display.textContent = data.count; + + // Mindestanzahl prüfen (aus Settings) + const minViewers = window.minViewersToShow || 1; + if (container) { + container.style.display = data.count >= minViewers ? 'inline-flex' : 'none'; + } + } + }); +} +``` + +## Fertig! + +Nach diesen Änderungen hast du: +- ✅ Timelapse mit Slider und 1x/10x/100x Geschwindigkeit +- ✅ Rückwärts-Spulen im Timelapse +- ✅ Tagesvideos im Player abspielen statt nur Download +- ✅ "Zurück zu Live" Button +- ✅ Admin-Einstellungen für Zuschauer-Anzeige +- ✅ Mindestanzahl für Zuschauer-Anzeige +- ✅ Video-Modus wählbar (Player/Download) +- ✅ Alles ohne Seiten-Reload diff --git a/aurora-livecam/SettingsManager.php b/aurora-livecam/SettingsManager.php new file mode 100644 index 0000000..58c29da --- /dev/null +++ b/aurora-livecam/SettingsManager.php @@ -0,0 +1,121 @@ +settingsFile = $file; + $this->load(); + } + + private function load() { + if (file_exists($this->settingsFile)) { + $content = file_get_contents($this->settingsFile); + $this->settings = json_decode($content, true) ?? $this->getDefaults(); + } else { + $this->settings = $this->getDefaults(); + $this->save(); + } + } + + private function getDefaults() { + return [ + 'viewer_display' => [ + 'enabled' => true, + 'min_viewers' => 1 + ], + 'video_mode' => [ + 'play_in_player' => true, + 'allow_download' => true + ], + 'timelapse' => [ + 'default_speed' => 1, + 'available_speeds' => [1, 10, 100] + ], + 'last_updated' => null, + 'updated_by' => null + ]; + } + + public function get($key = null) { + if ($key === null) return $this->settings; + $keys = explode('.', $key); + $value = $this->settings; + foreach ($keys as $k) { + if (!isset($value[$k])) return null; + $value = $value[$k]; + } + return $value; + } + + public function set($key, $value) { + $keys = explode('.', $key); + $ref = &$this->settings; + foreach ($keys as $i => $k) { + if ($i === count($keys) - 1) { + $ref[$k] = $value; + } else { + if (!isset($ref[$k])) $ref[$k] = []; + $ref = &$ref[$k]; + } + } + $this->settings['last_updated'] = date('Y-m-d H:i:s'); + return $this->save(); + } + + private function save() { + return file_put_contents( + $this->settingsFile, + json_encode($this->settings, JSON_PRETTY_PRINT) + ) !== false; + } + + // Für AJAX-Anfragen + public function handleAjax() { + if ($_SERVER['REQUEST_METHOD'] !== 'POST') return; + if (!isset($_POST['settings_action'])) return; + + header('Content-Type: application/json'); + + switch ($_POST['settings_action']) { + case 'get': + echo json_encode(['success' => true, 'settings' => $this->settings]); + exit; + + case 'update': + $key = $_POST['key'] ?? null; + $value = $_POST['value'] ?? null; + + // Boolean-Werte konvertieren + if ($value === 'true') $value = true; + if ($value === 'false') $value = false; + if (is_numeric($value)) $value = intval($value); + + if ($key && $this->set($key, $value)) { + echo json_encode(['success' => true, 'message' => 'Einstellung gespeichert']); + } else { + echo json_encode(['success' => false, 'message' => 'Fehler beim Speichern']); + } + exit; + } + } + + // Viewer-Anzeige prüfen + public function shouldShowViewers($currentCount) { + if (!$this->get('viewer_display.enabled')) return false; + return $currentCount >= $this->get('viewer_display.min_viewers'); + } + + // Video-Modus prüfen + public function shouldPlayInPlayer() { + return $this->get('video_mode.play_in_player') === true; + } + + public function shouldAllowDownload() { + return $this->get('video_mode.allow_download') === true; + } +} diff --git a/aurora-livecam/css/player-controls.css b/aurora-livecam/css/player-controls.css new file mode 100644 index 0000000..7ce94b0 --- /dev/null +++ b/aurora-livecam/css/player-controls.css @@ -0,0 +1,274 @@ +/* ========== TIMELAPSE CONTROLS ========== */ +#timelapse-controls { + display: none; + margin-top: 15px; +} + +.timelapse-control-bar { + display: flex; + align-items: center; + gap: 10px; + background: rgba(255, 255, 255, 0.95); + padding: 12px 20px; + border-radius: 50px; + box-shadow: 0 4px 15px rgba(0,0,0,0.1); + flex-wrap: wrap; + justify-content: center; +} + +.tl-btn { + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + color: white; + border: none; + width: 44px; + height: 44px; + border-radius: 50%; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + font-size: 16px; + transition: all 0.3s ease; + box-shadow: 0 2px 8px rgba(102, 126, 234, 0.3); +} + +.tl-btn:hover { + transform: scale(1.1); + box-shadow: 0 4px 12px rgba(102, 126, 234, 0.5); +} + +.tl-btn.active { + background: linear-gradient(135deg, #4CAF50 0%, #45a049 100%); +} + +.tl-slider-container { + flex: 1; + min-width: 200px; + max-width: 400px; + display: flex; + align-items: center; + gap: 15px; +} + +#tl-slider { + flex: 1; + height: 8px; + border-radius: 4px; + background: #e0e0e0; + outline: none; + -webkit-appearance: none; +} + +#tl-slider::-webkit-slider-thumb { + -webkit-appearance: none; + width: 20px; + height: 20px; + border-radius: 50%; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + cursor: pointer; + box-shadow: 0 2px 6px rgba(0,0,0,0.2); +} + +#tl-slider::-moz-range-thumb { + width: 20px; + height: 20px; + border-radius: 50%; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + cursor: pointer; + border: none; +} + +#tl-time-display { + font-family: monospace; + font-size: 14px; + color: #333; + background: #f5f5f5; + padding: 6px 12px; + border-radius: 20px; + min-width: 140px; + text-align: center; +} + +.tl-speed-btn { + width: auto !important; + padding: 0 20px !important; + border-radius: 22px !important; + font-weight: bold; + font-size: 14px; +} + +.tl-back-btn { + width: auto !important; + padding: 0 20px !important; + border-radius: 22px !important; + background: linear-gradient(135deg, #4CAF50 0%, #45a049 100%) !important; + gap: 8px; +} + +/* ========== DAILY VIDEO PLAYER ========== */ +#daily-video-player { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: #000; + z-index: 50; +} + +#daily-video { + width: 100%; + height: 100%; + object-fit: contain; +} + +.video-player-controls { + position: absolute; + bottom: 20px; + left: 50%; + transform: translateX(-50%); + display: flex; + gap: 15px; + z-index: 60; +} + +/* ========== ADMIN SETTINGS PANEL ========== */ +#admin-settings-panel { + background: white; + padding: 25px; + border-radius: 12px; + margin-bottom: 30px; + box-shadow: 0 4px 15px rgba(0,0,0,0.1); +} + +#admin-settings-panel h3 { + color: #667eea; + border-bottom: 2px solid #667eea; + padding-bottom: 10px; + margin-bottom: 20px; +} + +.settings-group { + margin-bottom: 25px; + padding: 20px; + background: #f9f9f9; + border-radius: 8px; +} + +.settings-group h4 { + margin-bottom: 15px; + color: #333; +} + +.setting-row { + display: flex; + align-items: center; + justify-content: space-between; + padding: 12px 0; + border-bottom: 1px solid #eee; +} + +.setting-row:last-child { + border-bottom: none; +} + +.setting-label { + font-weight: 500; + color: #555; +} + +.setting-input { + display: flex; + align-items: center; + gap: 10px; +} + +/* Toggle Switch */ +.toggle-switch { + position: relative; + width: 50px; + height: 26px; +} + +.toggle-switch input { + opacity: 0; + width: 0; + height: 0; +} + +.toggle-slider { + position: absolute; + cursor: pointer; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: #ccc; + transition: 0.3s; + border-radius: 26px; +} + +.toggle-slider:before { + position: absolute; + content: ""; + height: 20px; + width: 20px; + left: 3px; + bottom: 3px; + background-color: white; + transition: 0.3s; + border-radius: 50%; +} + +input:checked + .toggle-slider { + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); +} + +input:checked + .toggle-slider:before { + transform: translateX(24px); +} + +/* Number Input */ +.number-input { + width: 70px; + padding: 8px; + border: 2px solid #ddd; + border-radius: 8px; + font-size: 16px; + text-align: center; +} + +.number-input:focus { + border-color: #667eea; + outline: none; +} + +/* ========== MOBILE RESPONSIVE ========== */ +@media (max-width: 600px) { + .timelapse-control-bar { + padding: 10px 15px; + gap: 8px; + } + + .tl-btn { + width: 38px; + height: 38px; + font-size: 14px; + } + + .tl-slider-container { + width: 100%; + order: 10; + margin-top: 10px; + } + + #tl-time-display { + font-size: 12px; + min-width: 120px; + } + + .video-player-controls { + flex-direction: column; + bottom: 10px; + } +} diff --git a/aurora-livecam/js/admin-settings.js b/aurora-livecam/js/admin-settings.js new file mode 100644 index 0000000..d6168aa --- /dev/null +++ b/aurora-livecam/js/admin-settings.js @@ -0,0 +1,140 @@ +/** + * Admin Settings Manager - AJAX ohne Reload + */ +const AdminSettings = { + settings: {}, + + init: function() { + this.loadSettings(); + this.setupEventListeners(); + }, + + loadSettings: function() { + fetch(window.location.href, { + method: 'POST', + headers: {'Content-Type': 'application/x-www-form-urlencoded'}, + body: 'settings_action=get' + }) + .then(r => r.json()) + .then(data => { + if (data.success) { + this.settings = data.settings; + this.updateUI(); + } + }) + .catch(err => console.error('Settings load error:', err)); + }, + + updateSetting: function(key, value) { + fetch(window.location.href, { + method: 'POST', + headers: {'Content-Type': 'application/x-www-form-urlencoded'}, + body: `settings_action=update&key=${encodeURIComponent(key)}&value=${encodeURIComponent(value)}` + }) + .then(r => r.json()) + .then(data => { + if (data.success) { + this.showNotification('✓ Einstellung gespeichert', 'success'); + // Sofort UI aktualisieren + this.applySettingImmediately(key, value); + } else { + this.showNotification('✗ Fehler beim Speichern', 'error'); + } + }) + .catch(err => { + console.error('Settings update error:', err); + this.showNotification('✗ Netzwerkfehler', 'error'); + }); + }, + + applySettingImmediately: function(key, value) { + // Sofortige Anwendung ohne Reload + switch(key) { + case 'viewer_display.enabled': + const viewerEl = document.querySelector('.viewer-stat'); + if (viewerEl) { + viewerEl.style.display = value === true || value === 'true' ? 'inline-flex' : 'none'; + } + break; + + case 'viewer_display.min_viewers': + // Wird beim nächsten Heartbeat angewendet + window.minViewersToShow = parseInt(value); + break; + } + }, + + updateUI: function() { + // Checkbox für Zuschauer-Anzeige + const viewerEnabled = document.getElementById('setting-viewer-enabled'); + if (viewerEnabled) { + viewerEnabled.checked = this.settings.viewer_display?.enabled ?? true; + } + + // Mindestanzahl + const minViewers = document.getElementById('setting-min-viewers'); + if (minViewers) { + minViewers.value = this.settings.viewer_display?.min_viewers ?? 1; + } + + // Video-Modus + const playInPlayer = document.getElementById('setting-play-in-player'); + if (playInPlayer) { + playInPlayer.checked = this.settings.video_mode?.play_in_player ?? true; + } + + const allowDownload = document.getElementById('setting-allow-download'); + if (allowDownload) { + allowDownload.checked = this.settings.video_mode?.allow_download ?? true; + } + }, + + setupEventListeners: function() { + // Zuschauer-Anzeige Toggle + document.getElementById('setting-viewer-enabled')?.addEventListener('change', (e) => { + this.updateSetting('viewer_display.enabled', e.target.checked); + }); + + // Mindestanzahl Zuschauer + document.getElementById('setting-min-viewers')?.addEventListener('change', (e) => { + this.updateSetting('viewer_display.min_viewers', e.target.value); + }); + + // Video im Player abspielen + document.getElementById('setting-play-in-player')?.addEventListener('change', (e) => { + this.updateSetting('video_mode.play_in_player', e.target.checked); + }); + + // Download erlauben + document.getElementById('setting-allow-download')?.addEventListener('change', (e) => { + this.updateSetting('video_mode.allow_download', e.target.checked); + }); + }, + + showNotification: function(message, type) { + const notification = document.createElement('div'); + notification.className = `admin-notification ${type}`; + notification.textContent = message; + notification.style.cssText = ` + position: fixed; + top: 20px; + right: 20px; + padding: 15px 25px; + border-radius: 8px; + background: ${type === 'success' ? '#4CAF50' : '#f44336'}; + color: white; + font-weight: bold; + z-index: 10000; + animation: slideIn 0.3s ease; + `; + document.body.appendChild(notification); + setTimeout(() => notification.remove(), 3000); + } +}; + +// Initialisierung nur im Admin-Bereich +document.addEventListener('DOMContentLoaded', function() { + if (document.getElementById('admin-settings-panel')) { + AdminSettings.init(); + } +}); diff --git a/aurora-livecam/js/timelapse-controls.js b/aurora-livecam/js/timelapse-controls.js new file mode 100644 index 0000000..95d7f16 --- /dev/null +++ b/aurora-livecam/js/timelapse-controls.js @@ -0,0 +1,167 @@ +/** + * Timelapse Controller mit Slider, Geschwindigkeit und Rückwärts + */ +const TimelapseController = { + imageFiles: [], + currentIndex: 0, + isPlaying: false, + isReverse: false, + speed: 1, + availableSpeeds: [1, 10, 100], + intervalId: null, + baseInterval: 200, // ms bei 1x + + init: function(imageFilesArray) { + this.imageFiles = imageFilesArray; + this.setupControls(); + this.updateSlider(); + }, + + setupControls: function() { + const container = document.getElementById('timelapse-controls'); + if (!container) return; + + container.innerHTML = ` +
+ + +
+ + 00:00:00 +
+
+ +
+ +
+ `; + + // Event Listeners + document.getElementById('tl-play-pause').onclick = () => this.togglePlay(); + document.getElementById('tl-reverse').onclick = () => this.toggleReverse(); + document.getElementById('tl-speed').onclick = () => this.cycleSpeed(); + document.getElementById('tl-back-live').onclick = () => this.backToLive(); + + const slider = document.getElementById('tl-slider'); + slider.max = this.imageFiles.length - 1; + slider.oninput = (e) => this.seekTo(parseInt(e.target.value)); + }, + + togglePlay: function() { + this.isPlaying = !this.isPlaying; + const btn = document.getElementById('tl-play-pause'); + btn.innerHTML = this.isPlaying ? '' : ''; + + if (this.isPlaying) { + this.startPlayback(); + } else { + this.stopPlayback(); + } + }, + + toggleReverse: function() { + this.isReverse = !this.isReverse; + const btn = document.getElementById('tl-reverse'); + btn.classList.toggle('active', this.isReverse); + btn.innerHTML = this.isReverse ? + '' : + ''; + }, + + cycleSpeed: function() { + const idx = this.availableSpeeds.indexOf(this.speed); + this.speed = this.availableSpeeds[(idx + 1) % this.availableSpeeds.length]; + document.getElementById('tl-speed').textContent = this.speed + 'x'; + + if (this.isPlaying) { + this.stopPlayback(); + this.startPlayback(); + } + }, + + startPlayback: function() { + const interval = this.baseInterval / this.speed; + this.intervalId = setInterval(() => this.nextFrame(), interval); + }, + + stopPlayback: function() { + if (this.intervalId) { + clearInterval(this.intervalId); + this.intervalId = null; + } + }, + + nextFrame: function() { + if (this.isReverse) { + this.currentIndex--; + if (this.currentIndex < 0) this.currentIndex = this.imageFiles.length - 1; + } else { + this.currentIndex++; + if (this.currentIndex >= this.imageFiles.length) this.currentIndex = 0; + } + this.showFrame(this.currentIndex); + }, + + seekTo: function(index) { + this.currentIndex = index; + this.showFrame(index); + }, + + showFrame: function(index) { + const img = document.getElementById('timelapse-image'); + if (img && this.imageFiles[index]) { + img.src = this.imageFiles[index]; + } + this.updateSlider(); + this.updateTimeDisplay(); + }, + + updateSlider: function() { + const slider = document.getElementById('tl-slider'); + if (slider) slider.value = this.currentIndex; + }, + + updateTimeDisplay: function() { + const display = document.getElementById('tl-time-display'); + if (!display || !this.imageFiles[this.currentIndex]) return; + + const filename = this.imageFiles[this.currentIndex]; + const match = filename.match(/(\d{4})(\d{2})(\d{2})_(\d{2})(\d{2})(\d{2})/); + if (match) { + const [_, y, m, d, h, min, s] = match; + display.textContent = `${d}.${m}.${y} ${h}:${min}:${s}`; + } + }, + + backToLive: function() { + this.stopPlayback(); + this.isPlaying = false; + + // Live-Video wieder anzeigen + document.getElementById('timelapse-viewer').style.display = 'none'; + document.getElementById('webcam-player').style.display = 'block'; + document.getElementById('timelapse-button').textContent = 'Wochenzeitraffer'; + + // Controls verstecken + const controls = document.getElementById('timelapse-controls'); + if (controls) controls.style.display = 'none'; + }, + + show: function() { + document.getElementById('timelapse-viewer').style.display = 'block'; + document.getElementById('webcam-player').style.display = 'none'; + document.getElementById('daily-video-player').style.display = 'none'; + + const controls = document.getElementById('timelapse-controls'); + if (controls) controls.style.display = 'block'; + + this.currentIndex = 0; + this.showFrame(0); + } +}; diff --git a/aurora-livecam/js/video-player.js b/aurora-livecam/js/video-player.js new file mode 100644 index 0000000..b4b0389 --- /dev/null +++ b/aurora-livecam/js/video-player.js @@ -0,0 +1,108 @@ +/** + * Daily Video Player - Spielt Tagesvideos im Hauptfenster ab + */ +const DailyVideoPlayer = { + currentVideo: null, + videoElement: null, + + init: function() { + this.createPlayerElement(); + this.setupEventListeners(); + }, + + createPlayerElement: function() { + // Player-Container erstellen falls nicht vorhanden + if (document.getElementById('daily-video-player')) return; + + const container = document.createElement('div'); + container.id = 'daily-video-player'; + container.style.display = 'none'; + container.innerHTML = ` + +
+ + +
+ `; + + // Nach dem Webcam-Player einfügen + const videoContainer = document.querySelector('.video-container'); + if (videoContainer) { + videoContainer.appendChild(container); + } + + this.videoElement = document.getElementById('daily-video'); + }, + + setupEventListeners: function() { + document.getElementById('dvp-back-live')?.addEventListener('click', () => this.backToLive()); + + // Video-Ende Event + this.videoElement?.addEventListener('ended', () => { + // Optional: Automatisch zurück zu Live + }); + }, + + playVideo: function(videoPath, allowDownload = true) { + this.currentVideo = videoPath; + + // Andere Player verstecken + document.getElementById('webcam-player').style.display = 'none'; + document.getElementById('timelapse-viewer').style.display = 'none'; + document.getElementById('timelapse-controls')?.style.display = 'none'; + + // Diesen Player anzeigen + const player = document.getElementById('daily-video-player'); + player.style.display = 'block'; + + // Video laden + this.videoElement.src = videoPath; + this.videoElement.load(); + this.videoElement.play(); + + // Download-Button + const downloadBtn = document.getElementById('dvp-download'); + if (allowDownload && downloadBtn) { + downloadBtn.style.display = 'inline-block'; + downloadBtn.href = videoPath; + downloadBtn.download = videoPath.split('/').pop(); + } else if (downloadBtn) { + downloadBtn.style.display = 'none'; + } + }, + + backToLive: function() { + // Video stoppen + if (this.videoElement) { + this.videoElement.pause(); + this.videoElement.src = ''; + } + + // Player verstecken + document.getElementById('daily-video-player').style.display = 'none'; + + // Live-Stream anzeigen + document.getElementById('webcam-player').style.display = 'block'; + }, + + // Wird vom Kalender aufgerufen + handleCalendarClick: function(videoPath, playInPlayer, allowDownload) { + if (playInPlayer) { + this.playVideo(videoPath, allowDownload); + } else { + // Nur Download + window.location.href = videoPath; + } + } +}; + +// Initialisierung +document.addEventListener('DOMContentLoaded', function() { + DailyVideoPlayer.init(); +}); diff --git a/aurora-livecam/settings.json b/aurora-livecam/settings.json new file mode 100644 index 0000000..f11b81b --- /dev/null +++ b/aurora-livecam/settings.json @@ -0,0 +1,16 @@ +{ + "viewer_display": { + "enabled": true, + "min_viewers": 1 + }, + "video_mode": { + "play_in_player": true, + "allow_download": true + }, + "timelapse": { + "default_speed": 1, + "available_speeds": [1, 10, 100] + }, + "last_updated": null, + "updated_by": null +}