Files
tesla-cam-view/templates/index.html
T
zwitschi d12d5e5414 Refactor video player and camera angle switching
- Removed inline JSON data for video clips; replaced with API endpoint to fetch video data.
- Simplified camera angle switching UI with a 3-column button grid around a Model Y graphic.
- Updated camera view mapping to use 'back' instead of 'rear'.
- Enhanced noise canvas handling during video loading.
- Streamlined clip playback logic and added auto-play for next clips in the same camera.
- Improved search and sorting functionality by removing unnecessary elements.
- Updated HTML structure for better accessibility and user experience.
2026-07-25 00:43:43 +02:00

208 lines
6.3 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>TeslaCam Video Player</title>
<link
rel="stylesheet"
href="{{ url_for('static', filename='css/style.css') }}"
/>
</head>
<body>
<!-- Header -->
<header>
<div class="brand">
<span class="logo" aria-hidden="true">
<svg viewBox="0 0 24 24">
<path
d="M12 3C7 3 3.2 4.4 3.2 4.4l.9 1.7s3.1-1 5-.9l.7 1.3C7.9 7.7 6 9 6 9s.6 2.4 3 4.6c2.5-2.2 3-4.6 3-4.6s-1.9-1.3-3.7-1.5l.6-1.3c1.9-.1 5 .9 5 .9l.9-1.7S17 3 12 3z"
/>
</svg>
</span>
<div>
TeslaCam Player
<small>Dashcam &amp; Sentry Archive</small>
</div>
</div>
</header>
<!-- Main Layout: single column, centered -->
<div class="layout">
<!-- Video Player -->
<section class="player-panel">
<div class="video-stage">
{% set src = "src='" ~ default_url ~ "'" if default_url else '' %} {%
set hidden = 'hidden' if not default_url else '' %}
<video
id="player"
controls
preload="metadata"
playsinline
{{src}}
></video>
<canvas id="noiseCanvas" class="noise-canvas"></canvas>
<div class="video-badge" id="videoBadge">
<span class="dot"></span><span id="badgeText">Front</span>
</div>
<div class="video-placeholder" id="videoPlaceholder" {{hidden}}>
<svg
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="1.5"
>
<rect x="2" y="6" width="14" height="12" rx="2" />
<path d="M16 10l6-3v10l-6-3" />
</svg>
<div>No front camera footage found</div>
</div>
</div>
{% set phidden = 'hidden' if not default_url else '' %}
<div class="now-playing" id="nowPlaying" {{phidden}}>
<span
>Now Playing:
<strong id="npName"
>{% if default_url %}Front — oldest clip{% else %}—{% endif
%}</strong
></span
>
<span class="ts" id="npTime">—</span>
</div>
</section>
<!-- Camera Angle Selector: 3-column grid around Model Y graphic -->
<section class="cam-selector">
<h2 class="cs-heading">Camera Angles</h2>
<div class="cs-grid">
{% for col in camera_list %}
<div class="cs-col">
{% for cam in col %} {% set disabled = 'disabled' if not
cam.first_url else '' %}
<button
class="cs-btn{% if cam.key == 'front' %} active{% endif %}"
data-cam="{{ cam.key }}"
data-url="{{ cam.first_url or '' }}"
{{
disabled
}}
title="{{ cam.display }}{% if not cam.first_url %} — no footage{% endif %}"
>
<span class="cs-btn-label">{{ cam.display }}</span>
<span class="cs-btn-count">{{ cam.count }}</span>
</button>
{% endfor %}
</div>
{% endfor %}
</div>
<!-- Model Y Top-Down SVG -->
<div class="car-graphic" aria-hidden="true">
<svg viewBox="0 0 200 400" class="car-svg">
<!-- Car body -->
<rect
x="55"
y="80"
width="90"
height="240"
rx="30"
ry="30"
fill="none"
stroke="var(--text-muted)"
stroke-width="2"
/>
<!-- Windshield -->
<line
x1="65"
y1="110"
x2="135"
y2="110"
stroke="var(--text-muted)"
stroke-width="1.5"
/>
<!-- Back view -->
<line
x1="65"
y1="290"
x2="135"
y2="290"
stroke="var(--text-muted)"
stroke-width="1.5"
/>
<!-- Front view camera dot -->
<circle cx="100" cy="78" r="5" fill="var(--accent)" />
<!-- Back view camera dot -->
<circle cx="100" cy="322" r="5" fill="var(--accent)" />
<!-- Left repeater dot -->
<circle cx="53" cy="130" r="4" fill="var(--accent)" />
<!-- Right repeater dot -->
<circle cx="147" cy="130" r="4" fill="var(--accent)" />
<!-- Left pillar dot -->
<circle cx="53" cy="200" r="4" fill="var(--accent)" />
<!-- Right pillar dot -->
<circle cx="147" cy="200" r="4" fill="var(--accent)" />
<!-- Labels -->
<text
x="100"
y="68"
text-anchor="middle"
fill="var(--text-muted)"
font-size="9"
>
Front
</text>
<text
x="100"
y="342"
text-anchor="middle"
fill="var(--text-muted)"
font-size="9"
>
Back
</text>
<text
x="42"
y="134"
text-anchor="end"
fill="var(--text-muted)"
font-size="8"
>
L Rep
</text>
<text
x="158"
y="134"
text-anchor="start"
fill="var(--text-muted)"
font-size="8"
>
R Rep
</text>
<text
x="42"
y="204"
text-anchor="end"
fill="var(--text-muted)"
font-size="8"
>
L Pil
</text>
<text
x="158"
y="204"
text-anchor="start"
fill="var(--text-muted)"
font-size="8"
>
R Pil
</text>
</svg>
</div>
</section>
</div>
<!-- Camera metadata loaded via /api/videos by app.js -->
<script src="{{ url_for('static', filename='js/app.js') }}"></script>
</body>
</html>