$latestTime) {
$latestTime = $mtime;
$latestVideo = $video;
}
}
if ($latestVideo) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($latestVideo).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($latestVideo));
readfile($latestVideo);
exit;
} else {
echo "Kein Video zum Herunterladen gefunden.";
exit;
}
}
// Funktion zur sicheren Umleitung
function safeRedirect($url) {
if (!headers_sent()) {
header("HTTP/1.1 301 Moved Permanently");
header("Location: " . $url);
} else {
echo '';
}
exit();
}
// Hauptlogik
$oldDomains = [
'www.aurora-wetter-lifecam.ch',
'www.aurora-wetter-livecam.ch'
];
$newDomain = 'www.aurora-weather-livecam.com';
if (in_array($_SERVER['HTTP_HOST'], $oldDomains)) {
$protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http';
$newUrl = $protocol . '://' . $newDomain . $_SERVER['REQUEST_URI'];
// Logging für Debugging
error_log("Umleitung von {$_SERVER['HTTP_HOST']} nach $newUrl");
if (!headers_sent()) {
header("HTTP/1.1 301 Moved Permanently");
header("Location: " . $newUrl);
} else {
echo '';
}
exit();
}
session_start();
error_reporting(E_ALL);
ini_set('display_errors', 1);
$imageDir = "./image"; // Angepasst an das Ausgabeverzeichnis des Bash-Skripts
$imageFiles = glob("$imageDir/screenshot_*.jpg");
rsort($imageFiles); // Sortiert die Dateien in umgekehrter Reihenfolge (neueste zuerst)
$imageFilesJson = json_encode($imageFiles);
class WebcamManager {
private $videoSrc = 'test_video.m3u8';
private $logoPath = 'logo.png';
public function displayWebcam() {
return '
';
}
public function captureSnapshot() {
$outputFile = 'snapshot_' . date('YmdHis') . '.jpg';
$command = "ffmpeg -i {$this->videoSrc} -i {$this->logoPath} -filter_complex 'overlay=main_w-overlay_w-10:10' -vframes 1 -q:v 2 {$outputFile}";
exec($command, $output, $returnVar);
if ($returnVar !== 0) {
return "Fehler beim Erstellen des Snapshots.";
}
// Kopieren des Snapshots in den Uploads-Ordner
$uploadDir = "uploads/";
if (!file_exists($uploadDir)) {
mkdir($uploadDir, 0777, true);
}
$uploadFile = $uploadDir . $outputFile;
if (copy($outputFile, $uploadFile)) {
} else {
}
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $outputFile . '"');
readfile($outputFile);
unlink($outputFile);
exit;
}
// public function getImageFiles() {
// // Nur JPG-Dateien aus uploads/, KEINE MP4-Dateien
// $imageFiles = glob("uploads/*.{jpg,jpeg,png,gif}", GLOB_BRACE);
// // Filtere unerwünschte Dateien aus
// $imageFiles = array_filter($imageFiles, function($file) {
// $basename = basename($file);
// // Blockiere sequence_*.mp4 und andere unerwünschte Dateien
// return pathinfo($file, PATHINFO_EXTENSION) !== 'mp4' &&
// strpos($basename, 'sequence_') !== 0;
// });
// return json_encode(array_values($imageFiles));
// }
public function getImageFiles() {
// Screenshots aus dem image/ Ordner holen
$imageFiles = glob("image/screenshot_*.jpg");
sort($imageFiles); // Neueste zuerst
return json_encode($imageFiles);
}
public function captureVideoSequence($duration = 10) {
$outputFile = 'sequence_' . date('YmdHis') . '.mp4';
$command = "ffmpeg -i {$this->videoSrc} -i {$this->logoPath} -filter_complex 'overlay=10:10' -t {$duration} -c:v libx264 -preset fast -crf 23 {$outputFile}";
exec($command, $output, $returnVar);
if ($returnVar !== 0) {
return "Fehler beim Erstellen der Video-Sequenz.";
}
// Kopieren des Videoclips in den Uploads-Ordner
$uploadDir = "uploads/";
if (!file_exists($uploadDir)) {
mkdir($uploadDir, 0777, true);
echo "Uploads-Ordner erstellt. ";
}
$uploadFile = $uploadDir . $outputFile;
if (copy($outputFile, $uploadFile)) {
} else {
echo "Fehler beim Kopieren des Videoclips in den Uploads-Ordner. ";
}
header('Content-Type: video/mp4');
header('Content-Disposition: attachment; filename="' . $outputFile . '"');
readfile($outputFile);
unlink($outputFile);
exit;
}
public function getJavaScript() {
return "
document.addEventListener('DOMContentLoaded', function () {
var video = document.getElementById('webcam-player');
var videoSrc = '{$this->videoSrc}';
// Mobile Detection
var isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
var isIOS = /iPhone|iPad|iPod/i.test(navigator.userAgent);
// Controls NUR auf Desktop verstecken
video.controls = false;
if (isIOS) {
// iOS native HLS
video.src = videoSrc;
video.setAttribute('playsinline', '');
video.setAttribute('webkit-playsinline', '');
video.muted = true;
video.addEventListener('loadedmetadata', function() {
video.play().catch(function(e) {
console.log('iOS Autoplay blockiert');
});
});
} else if (Hls.isSupported()) {
var hls = new Hls({
// Mobile-optimierte Einstellungen
liveSyncDurationCount: isMobile ? 2 : 3,
liveMaxLatencyDurationCount: isMobile ? 5 : 10,
liveDurationInfinity: true,
enableWorker: !isMobile,
lowLatencyMode: false,
backBufferLength: isMobile ? 30 : 90,
maxBufferLength: isMobile ? 30 : 60,
maxMaxBufferLength: isMobile ? 60 : 120,
maxBufferSize: isMobile ? 60*1000*1000 : 120*1000*1000,
// Mobile-spezifische Timeouts
manifestLoadingTimeOut: isMobile ? 20000 : 10000,
manifestLoadingMaxRetry: 8,
levelLoadingTimeOut: isMobile ? 20000 : 10000,
levelLoadingMaxRetry: 8,
fragLoadingTimeOut: isMobile ? 20000 : 10000,
fragLoadingMaxRetry: 8,
// Qualität für Mobile
startLevel: isMobile ? 0 : -1,
abrEwmaDefaultEstimate: isMobile ? 500000 : 1000000
});
hls.loadSource(videoSrc);
hls.attachMedia(video);
hls.on(Hls.Events.MANIFEST_PARSED, function () {
console.log('Stream geladen');
if (isMobile) {
video.muted = true;
}
// Live-Position anpassen
if (hls.liveSyncPosition !== null) {
var targetPosition = hls.liveSyncPosition - 60;
console.log('Setze Position auf: ' + targetPosition);
video.currentTime = targetPosition;
}
video.play().catch(function(e) {
console.log('Autoplay blockiert');
});
});
// Fehlerbehandlung
hls.on(Hls.Events.ERROR, function(event, data) {
if (data.fatal) {
switch(data.type) {
case Hls.ErrorTypes.NETWORK_ERROR:
console.log('Netzwerkfehler - versuche erneut...');
setTimeout(function() {
hls.startLoad();
}, 3000);
break;
case Hls.ErrorTypes.MEDIA_ERROR:
console.log('Media-Fehler - Recovery...');
hls.recoverMediaError();
break;
default:
console.log('Kritischer Fehler - Neustart...');
hls.destroy();
location.reload();
break;
}
}
});
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {
// Fallback für andere Browser
video.src = videoSrc;
video.muted = true;
video.addEventListener('loadedmetadata', function () {
video.currentTime = Math.max(0, video.duration - 60);
video.play();
});
}
});
";
}
public function setVideoSrc($src) {
$this->videoSrc = $src;
}
}
class VisualCalendarManager {
private $videoDir;
private $monthNames;
public function __construct($videoDir = './videos/') {
$this->videoDir = $videoDir;
$this->monthNames = [
1 => ['de' => 'Januar', 'en' => 'January', 'it' => 'Gennaio', 'fr' => 'Janvier', 'zh' => '一月'],
2 => ['de' => 'Februar', 'en' => 'February', 'it' => 'Febbraio', 'fr' => 'Février', 'zh' => '二月'],
3 => ['de' => 'März', 'en' => 'March', 'it' => 'Marzo', 'fr' => 'Mars', 'zh' => '三月'],
4 => ['de' => 'April', 'en' => 'April', 'it' => 'Aprile', 'fr' => 'Avril', 'zh' => '四月'],
5 => ['de' => 'Mai', 'en' => 'May', 'it' => 'Maggio', 'fr' => 'Mai', 'zh' => '五月'],
6 => ['de' => 'Juni', 'en' => 'June', 'it' => 'Giugno', 'fr' => 'Juin', 'zh' => '六月'],
7 => ['de' => 'Juli', 'en' => 'July', 'it' => 'Luglio', 'fr' => 'Juillet', 'zh' => '七月'],
8 => ['de' => 'August', 'en' => 'August', 'it' => 'Agosto', 'fr' => 'Août', 'zh' => '八月'],
9 => ['de' => 'September', 'en' => 'September', 'it' => 'Settembre', 'fr' => 'Septembre', 'zh' => '九月'],
10 => ['de' => 'Oktober', 'en' => 'October', 'it' => 'Ottobre', 'fr' => 'Octobre', 'zh' => '十月'],
11 => ['de' => 'November', 'en' => 'November', 'it' => 'Novembre', 'fr' => 'Novembre', 'zh' => '十一月'],
12 => ['de' => 'Dezember', 'en' => 'December', 'it' => 'Dicembre', 'fr' => 'Décembre', 'zh' => '十二月']
];
}
public function getVideosForDate($year, $month, $day) {
$videos = [];
$dateStr = sprintf('%04d%02d%02d', $year, $month, $day);
foreach (glob($this->videoDir . "daily_video_{$dateStr}_*.mp4") as $video) {
$videos[] = [
'path' => $video,
'filename' => basename($video),
'filesize' => filesize($video),
'time' => date('H:i', filemtime($video))
];
}
return $videos;
}
public function hasVideosForDate($year, $month, $day) {
$dateStr = sprintf('%04d%02d%02d', $year, $month, $day);
$pattern = $this->videoDir . "daily_video_{$dateStr}_*.mp4";
return count(glob($pattern)) > 0;
}
public function displayVisualCalendar() {
$currentYear = isset($_GET['cal_year']) ? intval($_GET['cal_year']) : date('Y');
$currentMonth = isset($_GET['cal_month']) ? intval($_GET['cal_month']) : date('n');
$selectedDay = isset($_GET['cal_day']) ? intval($_GET['cal_day']) : null;
$output = '
';
// Navigation
$output .= '
';
$output .= '◀ ';
$output .= '
' . $this->monthNames[$currentMonth]['de'] . ' ' . $currentYear . ' ';
$output .= '▶ ';
$output .= '';
// Kalender-Grid
$output .= '
';
// Wochentage Header
$weekdays = ['Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa', 'So'];
foreach ($weekdays as $day) {
$output .= '
' . $day . '
';
}
// Tage des Monats
$firstDay = mktime(0, 0, 0, $currentMonth, 1, $currentYear);
$daysInMonth = date('t', $firstDay);
$dayOfWeek = date('N', $firstDay) - 1; // 0 = Montag
// Leere Zellen vor dem ersten Tag
for ($i = 0; $i < $dayOfWeek; $i++) {
$output .= '
';
}
// Tage mit Videos markieren
for ($day = 1; $day <= $daysInMonth; $day++) {
$hasVideos = $this->hasVideosForDate($currentYear, $currentMonth, $day);
$isSelected = ($selectedDay == $day);
$isToday = ($currentYear == date('Y') && $currentMonth == date('n') && $day == date('j'));
$classes = 'calendar-day';
if ($hasVideos) $classes .= ' has-video';
if ($isSelected) $classes .= ' selected';
if ($isToday) $classes .= ' today';
$output .= '
';
$output .= '' . $day . ' ';
if ($hasVideos) {
$output .= '📹 ';
}
$output .= '
';
}
$output .= '
'; // calendar-grid
// Video-Liste für ausgewählten Tag
if ($selectedDay) {
$videos = $this->getVideosForDate($currentYear, $currentMonth, $selectedDay);
if (!empty($videos)) {
$output .= '
';
$output .= '
Videos vom ' . sprintf('%02d.%02d.%04d', $selectedDay, $currentMonth, $currentYear) . ' ';
$output .= '
';
foreach ($videos as $video) {
$sizeInMb = round($video['filesize'] / (1024 * 1024), 2);
$token = hash_hmac('sha256', $video['path'], session_id());
$output .= '';
$output .= '🕐 ' . $video['time'] . ' Uhr ';
$output .= '' . $sizeInMb . ' MB ';
$output .= '';
$output .= '⬇️ Download';
$output .= ' ';
$output .= ' ';
}
$output .= ' ';
$output .= '
';
} else {
$output .= '
Keine Videos für diesen Tag verfügbar.
';
}
}
$output .= '
'; // visual-calendar-container
return $output;
}
}
class GuestbookManager {
private $entries = [];
private $dbFile = 'guestbook.json';
public function __construct() {
if (file_exists($this->dbFile)) {
$this->entries = json_decode(file_get_contents($this->dbFile), true);
}
}
public function handleFormSubmission() {
if (isset($_POST['guestbook'], $_POST['guest-name'], $_POST['guest-message'])) {
$this->addEntry($_POST['guest-name'], $_POST['guest-message']);
$this->saveEntries();
}
}
private function addEntry($name, $message) {
$this->entries[] = [
'name' => $name,
'message' => $message,
'date' => date('Y-m-d H:i:s')
];
}
public function deleteEntry($index) {
if (isset($this->entries[$index])) {
unset($this->entries[$index]);
$this->entries = array_values($this->entries); // Re-indizieren des Arrays
$this->saveEntries();
return true;
}
return false;
}
private function saveEntries() {
file_put_contents($this->dbFile, json_encode($this->entries));
}
public function displayForm() {
return '
';
}
public function displayEntries($isAdmin = false) {
$output = '';
foreach ($this->entries as $index => $entry) {
$output .= "
{$entry['name']}
{$entry['message']}
{$entry['date']}";
if ($isAdmin) {
$output .= "
Löschen
";
}
}
$output .= '
';
return $output;
}
}
class ContactManager {
//private $adminEmail = 'ingo.kohler.zh@gmail.com'; // ← Empfänger
private $adminEmail = 'metacube@gmail.com'; // ← Empfänger
private $feedbackFile = 'feedbacks.json';
private $gmailUser = 'metacube@gmail.com'; // ← DEINE GMAIL-ADRESSE
private $gmailAppPassword = 'qggk hsxz fdkq jgxa'; // ← APP-PASSWORT VON GMAIL
public function displayForm() {
return '
Name:
E-Mail:
Nachricht:
Nachricht senden
';
}
public function handleSubmission($name, $email, $message) {
// Validierung
if (empty($name) || empty($email) || empty($message)) {
return [
'success' => false,
'message' => 'Alle Felder sind erforderlich'
];
}
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
return [
'success' => false,
'message' => 'Ungültige E-Mail-Adresse'
];
}
if (strlen($message) < 10) {
return [
'success' => false,
'message' => 'Nachricht zu kurz (mindestens 10 Zeichen)'
];
}
// Sanitize
$name = htmlspecialchars(trim($name), ENT_QUOTES, 'UTF-8');
$email = filter_var(trim($email), FILTER_SANITIZE_EMAIL);
$message = htmlspecialchars(trim($message), ENT_QUOTES, 'UTF-8');
// Feedback speichern
$feedback = [
'name' => $name,
'email' => $email,
'message' => $message,
'date' => date('Y-m-d H:i:s'),
'ip' => $_SERVER['REMOTE_ADDR'] ?? 'unknown',
'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? 'unknown'
];
$feedbacks = file_exists($this->feedbackFile)
? json_decode(file_get_contents($this->feedbackFile), true)
: [];
if (!is_array($feedbacks)) {
$feedbacks = [];
}
$feedbacks[] = $feedback;
file_put_contents($this->feedbackFile, json_encode($feedbacks, JSON_PRETTY_PRINT));
// E-MAIL SENDEN MIT GMAIL SMTP
$mailSent = $this->sendEmailViaGmail($name, $email, $message, $feedback['date'], $feedback['ip']);
if ($mailSent) {
return [
'success' => true,
'message' => 'Vielen Dank! Ihre Nachricht wurde gesendet.'
];
} else {
error_log("Mail-Fehler: Nachricht von {$email} konnte nicht gesendet werden");
return [
'success' => false,
'message' => 'Nachricht wurde gespeichert, aber E-Mail konnte nicht gesendet werden.'
];
}
}
private function sendEmailViaGmail($name, $email, $message, $date, $ip) {
$mail = new PHPMailer(true);
try {
// DEBUG-MODUS AKTIVIEREN
$mail->SMTPDebug = 2;
$mail->Debugoutput = function($str, $level) {
error_log("PHPMailer Debug: $str");
};
// SMTP Konfiguration
$mail->isSMTP();
$mail->Host = 'smtp.gmail.com';
$mail->SMTPAuth = true;
$mail->Username = $this->gmailUser; // metacube@gmail.com
$mail->Password = $this->gmailAppPassword; // qggk hsxz fdkq jgxa
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
$mail->Port = 587;
// Absender & Empfänger
$mail->setFrom($this->gmailUser, 'Aurora Livecam');
$mail->addAddress($this->adminEmail); // admin@aurora-live-weathercam.com
$mail->addReplyTo($email, $name);
// Inhalt
$mail->isHTML(true);
$mail->CharSet = 'UTF-8';
$mail->Subject = '🔔 Neue Kontaktanfrage von ' . $name;
$mail->Body = $this->getEmailTemplate($name, $email, $message, $date, $ip);
$mail->send();
return true;
} catch (Exception $e) {
error_log("PHPMailer Error: {$mail->ErrorInfo}");
return false;
}
}
private function getEmailTemplate($name, $email, $message, $date, $ip) {
return "
👤 Name:
{$name}
💬 Nachricht:
" . nl2br($message) . "
";
}
}
class AdminManager {
public function isAdmin() {
return isset($_SESSION['admin']) && $_SESSION['admin'] === true;
}
public function handleLogin($username, $password) {
echo "Login-Versuch: Username = $username, Passwort = $password"; // Debugging
if ($username === 'admin' && $password === 'sonne4000$$$$Q') {
$_SESSION['admin'] = true;
return true;
}
return false;
}
public function handleImageUpload($file) {
if (!$this->isAdmin()) {
return false; // Nur Admins dürfen Bilder hochladen
}
if (!isset($file['tmp_name']) || empty($file['tmp_name'])) {
echo "Keine Datei hochgeladen.";
return false;
}
$target_dir = "uploads/";
if (!file_exists($target_dir)) {
mkdir($target_dir, 0777, true);
}
$target_file = $target_dir . basename($file["name"]);
$uploadOk = 1;
$imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));
$check = @getimagesize($file["tmp_name"]);
if($check === false) {
echo "Die Datei ist kein Bild.";
return false;
}
if ($file["size"] > 5000000) { // 5MB Limit
echo "Die Datei ist zu groß.";
return false;
}
// Erlauben Sie nur bestimmte Dateiformate
if($imageFileType != "jpg" && $imageFileType != "png" && $imageFileType != "jpeg"
&& $imageFileType != "gif" ) {
echo "Nur JPG, JPEG, PNG & GIF Dateien sind erlaubt.";
return false;
}
// Wenn alles in Ordnung ist, versuchen Sie, die Datei hochzuladen
if (move_uploaded_file($file["tmp_name"], $target_file)) {
echo "Die Datei ". basename( $file["name"]). " wurde hochgeladen.";
return true;
} else {
echo "Es gab einen Fehler beim Hochladen der Datei.";
return false;
}
}
public function displayLoginForm() {
return '
Benutzername:
Passwort:
Einloggen
';
}
public function displayAdminContent() {
$feedbacks = json_decode(file_get_contents('feedbacks.json') ?: '[]', true);
$output = '
Admin-Bereich ';
foreach ($feedbacks as $feedback) {
$output .= "
";
$output .= "
{$feedback['name']} ({$feedback['email']}) ";
$output .= "
{$feedback['message']}
";
$output .= "
{$feedback['date']} ";
$output .= "
";
}
$output .= '
';
$output .= '
Social Media Links verwalten
Facebook
Instagram
TikTok
Aktualisieren
';
$output .= '
Bild hochladen
';
return $output;
}
public function displayGalleryImages() {
$output = '
';
$files = glob("uploads/*.*");
foreach($files as $file) {
$filename = basename($file);
$extension = pathinfo($file, PATHINFO_EXTENSION);
// NUR Bilddateien anzeigen, KEINE Videos
if (in_array(strtolower($extension), ['jpg', 'jpeg', 'png', 'gif'])) {
$output .= '
';
}
}
$output .= '
';
return $output;
}
public function handleSocialMediaUpdate($platform, $url) {
$socialLinks = json_decode(file_get_contents('social_links.json') ?: '{}', true);
$socialLinks[$platform] = $url;
file_put_contents('social_links.json', json_encode($socialLinks));
}
}
// Weather Bingo Manager
//require_once 'weather_bingo.php';
//$weatherBingo = new WeatherBingo();
// Neue VideoArchiveManager Klasse
class VideoArchiveManager {
private $videoDir;
private $monthNames;
public function __construct($videoDir = './videos/') {
$this->videoDir = $videoDir;
$this->monthNames = [
'01' => 'Januar',
'02' => 'Februar',
'03' => 'März',
'04' => 'April',
'05' => 'Mai',
'06' => 'Juni',
'07' => 'Juli',
'08' => 'August',
'09' => 'September',
'10' => 'Oktober',
'11' => 'November',
'12' => 'Dezember'
];
}
public function getVideosGroupedByDate() {
$videos = [];
foreach (glob($this->videoDir . 'daily_video_*.mp4') as $video) {
// Dateinamenformat: daily_video_YYYYMMDD_HHMMSS.mp4
if (preg_match('/daily_video_(\d{8})_\d{6}\.mp4/', basename($video), $matches)) {
$dateStr = $matches[1]; // YYYYMMDD
$year = substr($dateStr, 0, 4);
$month = substr($dateStr, 4, 2);
$day = substr($dateStr, 6, 2);
// Gruppiere nach Jahr und Monat
$videos[$year][$month][] = [
'path' => $video,
'filename' => basename($video),
'day' => $day,
'filesize' => filesize($video),
'modified' => filemtime($video)
];
}
}
// Nach Tag sortieren
foreach ($videos as $year => $months) {
foreach ($months as $month => $days) {
usort($videos[$year][$month], function($a, $b) {
return $b['day'] - $a['day']; // Absteigend sortieren (neueste zuerst)
});
}
}
return $videos;
}
public function getAvailableYearsAndMonths() {
$videos = $this->getVideosGroupedByDate();
$result = [];
foreach ($videos as $year => $months) {
$result[$year] = array_keys($months);
}
return $result;
}
public function getVideosForYearAndMonth($year, $month) {
$videos = $this->getVideosGroupedByDate();
return isset($videos[$year][$month]) ? $videos[$year][$month] : [];
}
public function displayCalendarInterface() {
$yearsAndMonths = $this->getAvailableYearsAndMonths();
$output = '
';
$output .= '
Video-Archiv ';
if (empty($yearsAndMonths)) {
$output .= '
Keine Videos verfügbar.
';
} else {
$output .= '
';
$output .= '
';
// Jahr-Auswahl
$output .= 'Jahr: ';
$output .= '';
foreach ($yearsAndMonths as $year => $months) {
$selected = (isset($_GET['calendar_year']) && $_GET['calendar_year'] == $year) ? 'selected' : '';
$output .= "$year ";
}
$output .= ' ';
// Monats-Auswahl
$output .= 'Monat: ';
$output .= '';
// Wenn ein Jahr ausgewählt wurde, zeige die verfügbaren Monate
if (isset($_GET['calendar_year']) && isset($yearsAndMonths[$_GET['calendar_year']])) {
foreach ($yearsAndMonths[$_GET['calendar_year']] as $month) {
$selected = (isset($_GET['calendar_month']) && $_GET['calendar_month'] == $month) ? 'selected' : '';
$output .= "{$this->monthNames[$month]} ";
}
}
$output .= ' ';
$output .= 'Anzeigen ';
$output .= ' ';
$output .= '';
// Wenn Jahr und Monat ausgewählt wurden, zeige die Videos
if (isset($_GET['calendar_year']) && isset($_GET['calendar_month'])) {
$year = $_GET['calendar_year'];
$month = $_GET['calendar_month'];
$videos = $this->getVideosForYearAndMonth($year, $month);
if (!empty($videos)) {
$output .= '
';
$output .= "
Videos für {$this->monthNames[$month]} $year ";
$output .= '
';
$output .= '
';
} else {
$output .= "
Keine Videos für {$this->monthNames[$month]} $year gefunden.
";
}
}
}
$output .= '
';
return $output;
}
public function handleSpecificVideoDownload() {
if (isset($_GET['download_specific_video']) && isset($_GET['token'])) {
$videoPath = $_GET['download_specific_video'];
$token = $_GET['token'];
// Token-Validierung
$expectedToken = hash_hmac('sha256', $videoPath, session_id());
if (!hash_equals($expectedToken, $token)) {
echo "Ungültiger Token. Zugriff verweigert.";
exit;
}
// Sicherheitsüberprüfung: Stelle sicher, dass das Video im erlaubten Verzeichnis liegt
$videoDir = realpath($this->videoDir);
$requestedPath = realpath($videoPath);
if ($requestedPath && strpos($requestedPath, $videoDir) === 0 && file_exists($requestedPath)) {
// Nur MP4-Dateien erlauben
$extension = pathinfo($requestedPath, PATHINFO_EXTENSION);
if (strtolower($extension) !== 'mp4') {
echo "Nur MP4-Dateien können heruntergeladen werden.";
exit;
}
header('Content-Description: File Transfer');
header('Content-Type: video/mp4');
header('Content-Disposition: attachment; filename="'.basename($requestedPath).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($requestedPath));
readfile($requestedPath);
exit;
} else {
echo "Datei nicht gefunden oder ungültiger Dateipfad.";
exit;
}
}
}
}
$webcamManager = new WebcamManager();
$imageFilesJson = $webcamManager->getImageFiles();
$guestbookManager = new GuestbookManager();
$contactManager = new ContactManager();
$adminManager = new AdminManager();
// Nach den anderen Manager-Instanzen hinzufügen
$videoArchiveManager = new VideoArchiveManager('./videos/');
// Video-Download-Handler nach dem existierenden Download-Handler hinzufügen
$videoArchiveManager->handleSpecificVideoDownload();
if (isset($_GET['action'])) {
switch ($_GET['action']) {
case 'snapshot':
$webcamManager->captureSnapshot();
break;
case 'sequence':
$webcamManager->captureVideoSequence();
break;
}
}
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'delete_guestbook') {
if ($adminManager->isAdmin() && isset($_POST['delete_entry'])) {
$index = $_POST['delete_entry'];
if ($guestbookManager->deleteEntry($index)) {
$_SESSION['message'] = "Eintrag erfolgreich gelöscht.";
} else {
$_SESSION['error'] = "Fehler beim Löschen des Eintrags.";
}
// Umleitung zur gleichen Seite, um Neuladen des Formulars zu verhindern
header("Location: " . $_SERVER['PHP_SELF'] . "#guestbook");
exit();
}
}
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (isset($_POST['guestbook'])) {
$guestbookManager->handleFormSubmission();
} elseif (isset($_POST['contact'])) {
$result = $contactManager->handleSubmission($_POST['name'], $_POST['email'], $_POST['message']);
// JSON-Response für AJAX
if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) &&
strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest') {
header('Content-Type: application/json');
echo json_encode($result);
exit;
}
// Normale Formular-Submission
$_SESSION['contact_result'] = $result;
header('Location: ' . $_SERVER['PHP_SELF'] . '#kontakt');
exit;
} elseif (isset($_POST['admin-login'])) {
$adminManager->handleLogin($_POST['username'], $_POST['password']);
} elseif (isset($_POST['update-social-media'])) {
$adminManager->handleSocialMediaUpdate($_POST['social-platform'], $_POST['social-url']);
} elseif (isset($_FILES["fileToUpload"]) && $adminManager->isAdmin()) {
$adminManager->handleImageUpload($_FILES["fileToUpload"]);
}}
?>
Aurora Livecam - Einzigartige Live-Webcam und Wetter>
Willkommen bei Aurora Wetter Livecam
Erleben Sie faszinierende Ausblicke der Züricher Region - in Echtzeit!
Videoarchiv Tagesvideos
displayVisualCalendar();
?>
Folge uns und kopiere den Code und sende es deinen Freunden in Tiktok, Facebook, Instagram usw.
Klicke auf den QR-Code, um die URL zu kopieren
📋 Nutzungsbedingungen & Chat-Regeln
⚠️ Wichtige Verhaltensregeln:
Keine sexuellen, pornografischen oder anzüglichen Inhalte
Keine Gewaltdarstellungen oder -androhungen
Kein Rassismus, Diskriminierung oder Hassrede
Keine persönlichen Daten (Telefonnummern, Adressen) teilen
Keine Werbung oder Spam
Respektvoller Umgang miteinander
Keine illegalen Aktivitäten oder Inhalte
📸 Webcam-Nutzung:
Die Webcam zeigt öffentlichen Raum. Es werden keine Personen gezielt aufgenommen. Die Nutzung erfolgt auf eigene Verantwortung.
💬 Chat-Nutzung:
Mit der Nutzung des Chats akzeptieren Sie diese Regeln. Verstöße führen zur sofortigen Sperrung. Chat-Nachrichten werden 24 Stunden gespeichert.
⚖️ Rechtliches:
Haftungsausschluss: Der Betreiber übernimmt keine Haftung für Inhalte von Nutzern. Jeder Nutzer ist für seine Beiträge selbst verantwortlich.
Datenschutz: Es werden nur technisch notwendige Daten gespeichert (IP-Adresse für 24h zur Missbrauchsprävention).
Ich akzeptiere die Nutzungsbedingungen
Akzeptieren & Chat nutzen
Ablehnen
Gästebuch
{$_SESSION['message'][$currentLang]}";
unset($_SESSION['message']);
}
if (isset($_SESSION['error'])) {
echo "
{$_SESSION['error'][$currentLang]}
";
unset($_SESSION['error']);
}
echo $guestbookManager->displayForm();
echo $guestbookManager->displayEntries($adminManager->isAdmin());
?>
Kontakt
Haben Sie Fragen, Anregungen oder möchten uns unterstützen? Wir freuen uns auf Ihre Nachricht!
displayForm(); ?>
displayGalleryImages(); ?>
Aurora Wetter Livecam ist ein Herzensprojekt von Wetterbegeisterten. Wir möchten Ihnen die Schönheit der Natur und Faszination des Wetters näher bringen.
Dazu betreiben wir seit 2010 rund um die Uhr hochauflösende Webcams. Besonders stolz sind wir auf einzigartige Einblicke, wie z.B. die Trainingsflüge der Patrouille Suisse jeden Montagmorgen.
isAdmin()): ?>
Admin-Bereich
displayAdminContent(); ?>
Admin Login
displayLoginForm(); ?>
Impressum
Aurora Wetter Livecam
M. Kessler
Dürnten
Schweiz
Anfragen per Kontaktformular