Files
abdulive/apps/overlay-web/public/pult.html
T
ZeasyAlexandClaude Opus 5.5 8be195d938
Paket bauen und veroeffentlichen / paket (push) Failing after 1m21s
Pult: Handy als Stream Deck mit Soundboard und Szenenwechsel
- /pult als installierbare Web-App (Manifest, Service Worker, Symbole)
- Soundboard: Sounds vom Handy hochladen, bearbeiten, im Stream spielen
  ueber die neue Browser-Source /sounds
- Szenen, Clip und Stummschalter: der Stream-PC waehlt sich mit eigenem
  Schluessel beim Hub ein (fern:verbinden), Befehle warten auf OBS
- Browser-Sources melden, welche Seite sie sind

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 11:51:48 +01:00

196 lines
8.9 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<meta name="theme-color" content="#0d0b14">
<meta name="color-scheme" content="dark">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="apple-mobile-web-app-title" content="Pult">
<title>Pult · abdulive</title>
<link rel="manifest" href="/manifest.webmanifest">
<link rel="icon" href="/icons/pult-192.png" type="image/png">
<link rel="apple-touch-icon" href="/icons/apple-touch-icon.png">
<link rel="stylesheet" href="/pult.css">
</head>
<body>
<header class="kopf">
<div class="kanal">
<span class="marke">abdu<b>live</b></span>
<span id="live" class="live aus"><i></i><span id="live-text">offline</span></span>
</div>
<div class="kopf-rechts">
<button id="wach" class="rund" type="button" aria-pressed="false" title="Bildschirm anlassen">
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 3v2M12 19v2M4.2 4.2l1.4 1.4M18.4 18.4l1.4 1.4M3 12h2M19 12h2M4.2 19.8l1.4-1.4M18.4 5.6l1.4-1.4"/><circle cx="12" cy="12" r="4"/></svg>
</button>
<span id="netz" class="netz" title="Verbindung zum Hub"><i></i></span>
</div>
</header>
<div id="banner" class="banner" hidden></div>
<main>
<!-- ======================================================== Sounds -->
<section id="tab-sounds" class="tab an" aria-labelledby="nav-sounds">
<div class="leiste">
<button id="stopp" class="knopf warnung" type="button">
<svg viewBox="0 0 24 24" aria-hidden="true"><rect x="6" y="6" width="12" height="12" rx="2"/></svg>
Stopp
</button>
<span class="luecke"></span>
<button id="bearbeiten" class="knopf" type="button" aria-pressed="false">Bearbeiten</button>
<label class="knopf primaer" for="datei">
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 5v14M5 12h14"/></svg>
Sound
</label>
<input id="datei" type="file" accept="audio/*,.mp3,.wav,.ogg,.m4a,.webm" multiple hidden>
</div>
<div id="quelle-fehlt" class="hinweis warn" hidden>
In OBS ist keine Sound-Quelle verbunden – die Zuschauer hören nichts. Browser-Source
<code>/sounds</code> anlegen, die Adresse steht auf der <a href="/">Übersicht</a>.
</div>
<div id="raster" class="raster" aria-live="polite"></div>
<div id="sounds-leer" class="leer" hidden>
<div class="leer-bild" aria-hidden="true">
<span></span><span></span><span></span><span></span><span></span><span></span>
</div>
<h2>Noch keine Sounds</h2>
<p>MP3, WAV, OGG oder M4A vom Handy hochladen. Jeder Sound wird eine Taste;
ein Druck spielt ihn im Stream.</p>
<label class="knopf primaer gross" for="datei">Ersten Sound hinzufügen</label>
</div>
</section>
<!-- ======================================================== Szenen -->
<section id="tab-szenen" class="tab" aria-labelledby="nav-szenen">
<div id="obs-fehlt" class="karte leer-karte" hidden>
<h2 id="obs-fehlt-titel">Stream-PC nicht verbunden</h2>
<p id="obs-fehlt-text"></p>
</div>
<div id="obs-da" hidden>
<h3 class="abschnitt">Szenen</h3>
<div id="szenen" class="szenen"></div>
<h3 class="abschnitt">Clip</h3>
<button id="clip" class="knopf clip" type="button">
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M4 7h3l2-3h6l2 3h3v12H4z"/><circle cx="12" cy="13" r="3.5"/></svg>
<span>Clip speichern</span>
</button>
<p id="clip-hinweis" class="klein"></p>
<h3 class="abschnitt">Ton</h3>
<div id="ton" class="ton"></div>
</div>
</section>
<!-- ======================================================== Stream -->
<section id="tab-stream" class="tab" aria-labelledby="nav-stream">
<div id="lz-karte" class="karte" hidden>
<h3 class="abschnitt">Liegestütze</h3>
<div class="lz-zahlen">
<div><b id="lz-offen">0</b><span>offen</span></div>
<div class="gemacht"><b id="lz-gemacht">0</b><span>gemacht</span></div>
</div>
<div class="lz-knoepfe">
<button class="knopf" data-um="-10" type="button">−10</button>
<button class="knopf" data-um="-5" type="button">−5</button>
<button class="knopf" data-um="-1" type="button">−1</button>
<button class="knopf" data-um="1" type="button">+1</button>
<button class="knopf" data-um="5" type="button">+5</button>
<button class="knopf" data-um="10" type="button">+10</button>
</div>
<p class="klein">Minus zählt als gemacht. Korrekturen ohne Zählung auf der <a href="/">Übersicht</a>.</p>
</div>
<div id="tts-karte" class="karte" hidden>
<h3 class="abschnitt">Vorlesen <span id="tts-anzahl" class="zaehler" hidden></span></h3>
<div id="wartend" class="wartend"></div>
<button id="alle-ablehnen" class="knopf" type="button">Alle ablehnen</button>
</div>
<button id="still" class="knopf panik" type="button">
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M11 5 6 9H3v6h3l5 4zM16 9l5 6M21 9l-5 6"/></svg>
Sofort still
</button>
<p class="klein mitte">Bricht Vorlesen und alle Sounds ab und leert die Warteschlange.</p>
</section>
<!-- ======================================================== Test -->
<section id="tab-test" class="tab" aria-labelledby="nav-test">
<div id="test-live" class="hinweis warn" hidden>Der Stream läuft. Was du hier auslöst, sehen die Zuschauer.</div>
<p class="klein">Erfundene Ereignisse, nur für die Browser-Sources. Nichts davon landet
in der Datenbank, auf Discord oder bei Twitch.</p>
<div id="test-gruppen"></div>
<h3 class="abschnitt">Dauerbetrieb</h3>
<button id="demo" class="knopf breit" type="button" data-art="demo-an">Vorführung starten</button>
<p class="klein"><a href="/">Übersicht und OBS-Adressen</a> · <a href="/setup">Einrichtung</a> · <a href="/logout">Abmelden</a></p>
</section>
</main>
<div id="meldung" class="meldung" role="status" aria-live="polite"></div>
<nav class="reiter" aria-label="Bereiche">
<button id="nav-sounds" data-tab="sounds" class="an" type="button">
<svg viewBox="0 0 24 24" aria-hidden="true"><rect x="3" y="3" width="7.5" height="7.5" rx="2"/><rect x="13.5" y="3" width="7.5" height="7.5" rx="2"/><rect x="3" y="13.5" width="7.5" height="7.5" rx="2"/><rect x="13.5" y="13.5" width="7.5" height="7.5" rx="2"/></svg>
Sounds
</button>
<button id="nav-szenen" data-tab="szenen" type="button">
<svg viewBox="0 0 24 24" aria-hidden="true"><rect x="2.5" y="5" width="19" height="13" rx="2"/><path d="M8 21h8"/></svg>
Szenen
</button>
<button id="nav-stream" data-tab="stream" type="button">
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M4 20V10M10 20V4M16 20v-7M22 20H2"/></svg>
Stream
<i id="nav-tts" class="punkt" hidden></i>
</button>
<button id="nav-test" data-tab="test" type="button">
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M9 3h6M10 3v6l-5 9a2 2 0 0 0 1.8 3h10.4a2 2 0 0 0 1.8-3l-5-9V3"/></svg>
Test
</button>
</nav>
<dialog id="blatt" class="blatt">
<form method="dialog" id="blatt-form">
<div class="griff" aria-hidden="true"></div>
<div class="blatt-kopf">
<input id="b-emoji" class="emoji-feld" maxlength="10" placeholder="🔊" aria-label="Emoji" autocomplete="off">
<input id="b-name" class="name-feld" maxlength="40" placeholder="Name" aria-label="Name" autocomplete="off">
</div>
<div id="b-schnell" class="schnell" aria-label="Emoji-Vorschläge"></div>
<div class="feld">
<span class="feld-name">Farbe</span>
<div id="b-farben" class="farben" role="radiogroup" aria-label="Farbe"></div>
</div>
<label class="feld">
<span class="feld-name">Lautstärke <b id="b-laut-zahl">80 %</b></span>
<input id="b-laut" type="range" min="0" max="100" step="5" value="80">
</label>
<div class="blatt-reihe">
<button type="button" id="b-hoeren" class="knopf">Am Handy anhören</button>
<button type="button" id="b-vor" class="knopf" aria-label="Nach vorn">◀</button>
<button type="button" id="b-zurueck" class="knopf" aria-label="Nach hinten">▶</button>
</div>
<div class="blatt-reihe">
<button type="button" id="b-loeschen" class="knopf warnung">Löschen</button>
<span class="luecke"></span>
<button type="button" id="b-abbrechen" class="knopf">Abbrechen</button>
<button type="submit" id="b-speichern" class="knopf primaer">Speichern</button>
</div>
</form>
</dialog>
<div id="abgemeldet" class="abgemeldet" hidden>
<div>
<h2>Abgemeldet</h2>
<p>Die Anmeldung ist abgelaufen oder das Passwort wurde geändert.</p>
<a class="knopf primaer gross" href="/pult">Neu anmelden</a>
</div>
</div>
<script src="/pult.js"></script>
</body>
</html>