From 85d578874ab8007e5932d15b902c109421c42ab4 Mon Sep 17 00:00:00 2001 From: rene Date: Sat, 6 Jun 2026 20:24:35 +0200 Subject: [PATCH] =?UTF-8?q?Navi-Sounds:=20zurueck=20zu=20HTMLAudio=20mit?= =?UTF-8?q?=20Gesten-Priming=20=E2=80=94=20WebAudio=20war=20stummschalter-?= =?UTF-8?q?stumm?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prod-Befund Rene: kein Ton. Ursache: v1244-Umbau auf AudioBuffer/WebAudio — der respektiert den iOS-STUMMSCHALTER (= Gassi-Normalzustand) -> Stille. HTMLAudio spielt wie Medien trotz Stummschalter (deshalb klang Staging v1243 richtig). Den urspruenglichen Lazy-Load-Bug loest jetzt GESTEN-PRIMING: im unlock() stumm anspielen (play+pause, muted) = Wiedergabe-Erlaubnis fuer spaetere gestenlose Ansagen + erzwingt das Laden. readyState>=2-Check, Synthese bleibt Fallback. Bump v1248 --- VERSION | 2 +- backend/static/index.html | 24 ++++++------- backend/static/js/app.js | 2 +- backend/static/js/pages/routes.js | 57 +++++++++++++++++-------------- backend/static/landing.html | 2 +- backend/static/sw.js | 2 +- 6 files changed, 48 insertions(+), 41 deletions(-) diff --git a/VERSION b/VERSION index 1280674..f0b4b2f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1247 \ No newline at end of file +1248 \ No newline at end of file diff --git a/backend/static/index.html b/backend/static/index.html index 3227008..83cd111 100644 --- a/backend/static/index.html +++ b/backend/static/index.html @@ -86,14 +86,14 @@ Ban Yaro - + - - - - - + + + + + @@ -612,11 +612,11 @@ - - - - - + + + + + @@ -626,7 +626,7 @@ - + diff --git a/backend/static/js/app.js b/backend/static/js/app.js index 7f96416..a62d078 100644 --- a/backend/static/js/app.js +++ b/backend/static/js/app.js @@ -3,7 +3,7 @@ Router, State-Management, Navigation, Initialisierung. ============================================================ */ -const APP_VER = '1247'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen +const APP_VER = '1248'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen const APP_VERSION = '1.6.0'; // ← semantische Version, wird bei make release gesetzt window.APP_VER = APP_VER; // global verfügbar für andere Module (z.B. offline-indicator) window.APP_VERSION = APP_VERSION; diff --git a/backend/static/js/pages/routes.js b/backend/static/js/pages/routes.js index 844bcdf..747e61b 100644 --- a/backend/static/js/pages/routes.js +++ b/backend/static/js/pages/routes.js @@ -77,9 +77,13 @@ window.Page_routes = (() => { // ---------------------------------------------------------- const NavSound = (() => { let ctx = null; - let bufs = null; // { wuff, klaeffen } AudioBuffer | leer = Synthese. - // HTMLAudio+preload taugt NICHT (iOS lädt lazy, canplaythrough feuert nie → - // es blieb beim Game-Boy-Sound, René 2026-06-06) → fetch + decodeAudioData. + let files = null; // { wuff, klaeffen } HTMLAudio | leer = Synthese. + // WICHTIG — zwei iOS-Fallen (René 2026-06-06): + // 1. HTMLAudio mit preload lädt LAZY (canplaythrough feuert nie) → daher in der + // User-Geste STUMM ANSPIELEN: primt die Wiedergabe-Erlaubnis UND erzwingt das Laden. + // 2. WebAudio (AudioContext/decodeAudioData) respektiert den STUMMSCHALTER → auf + // lautlos (= Gassi-Normalzustand) kam NICHTS (Prod-Befund). HTMLAudio spielt wie + // Medien trotz Stummschalter → für ein Navi der richtige Kanal. Synthese = Fallback. const enabled = () => { try { return localStorage.getItem('by_nav_sound') !== '0'; } catch (e) { return true; } }; function _ctx() { @@ -87,17 +91,6 @@ window.Page_routes = (() => { if (ctx.state === 'suspended') ctx.resume().catch(() => {}); return ctx; } - function _loadBufs() { - if (bufs !== null) return; - bufs = {}; - ['wuff', 'klaeffen'].forEach(name => { - fetch(`/sounds/${name}.mp3`) - .then(r => { if (!r.ok) throw new Error(String(r.status)); return r.arrayBuffer(); }) - .then(ab => _ctx().decodeAudioData(ab)) - .then(b => { bufs[name] = b; }) - .catch(() => {}); // 404/Decode-Fehler → Synthese bleibt - }); - } // Ein synthetischer „Wuff": Sägezahn-Sweep durch Tiefpass, kurzer Attack, schneller Decay. function _wuff(at, pitch = 1) { const c = _ctx(), t = c.currentTime + at; @@ -115,18 +108,19 @@ window.Page_routes = (() => { function _barks(n, pitch, gap) { if (!enabled()) return; try { - const buf = bufs && (pitch > 1.3 ? bufs.klaeffen : bufs.wuff); - if (buf) { // echte Aufnahme (Schäferhund, /sounds/*.mp3) + const a = files && (pitch > 1.3 ? files.klaeffen : files.wuff); + if (a && a.readyState >= 2) { // echte Aufnahme geladen (Schäferhund, /sounds/*.mp3) // klaeffen.mp3 ist bereits eine ~2,8-s-Bell-SEQUENZ → nur 1× abspielen; // wuff.mp3 ist ein einzelner Beller → n-mal mit Pause. - const c = _ctx(); - const reps = buf === bufs.klaeffen ? 1 : n; - for (let i = 0; i < reps; i++) { - const s = c.createBufferSource(); - s.buffer = buf; - s.connect(c.destination); - s.start(c.currentTime + i * (buf.duration + 0.22)); - } + const reps = a === files.klaeffen ? 1 : n; + let i = 0; + const play = () => { + if (i++ >= reps) return; + a.currentTime = 0; + a.play().catch(() => {}); + setTimeout(play, (a.duration || 0.4) * 1000 + 220); + }; + play(); return; } for (let i = 0; i < n; i++) _wuff(i * gap, pitch); // Fallback: Synthese @@ -140,7 +134,20 @@ window.Page_routes = (() => { const b = c.createBuffer(1, 1, 22050), s = c.createBufferSource(); s.buffer = b; s.connect(c.destination); s.start(0); } catch (e) {} - _loadBufs(); // echte Samples laden (404 → Synthese bleibt) + if (files === null) { + files = {}; + ['wuff', 'klaeffen'].forEach(name => { + const a = new Audio(`/sounds/${name}.mp3`); + a.preload = 'auto'; + // IM GESTENKONTEXT stumm anspielen: primt iOS (spätere play() ohne Geste + // erlaubt) und erzwingt das tatsächliche Laden (preload allein reicht nicht). + a.muted = true; + a.play().then(() => { + a.pause(); a.currentTime = 0; a.muted = false; + }).catch(() => { a.muted = false; }); + files[name] = a; + }); + } }, links() { _barks(2, 1.0, 0.30); }, // 2× Wuff rechts() { _barks(1, 1.0, 0.30); }, // 1× Wuff diff --git a/backend/static/landing.html b/backend/static/landing.html index ab4d97c..05e1a20 100644 --- a/backend/static/landing.html +++ b/backend/static/landing.html @@ -4,7 +4,7 @@ - + Ban Yaro — Die Hunde-App für Deutschland, Österreich & Schweiz diff --git a/backend/static/sw.js b/backend/static/sw.js index a86b58c..8ba790e 100644 --- a/backend/static/sw.js +++ b/backend/static/sw.js @@ -4,7 +4,7 @@ ============================================================ */ // ← EINZIGE Stelle für die Version — STATIC_ASSETS und CACHE_VERSION leiten sich ab -const VER = '1247'; +const VER = '1248'; const CACHE_VERSION = `by-v${VER}`; const CACHE_STATIC = `${CACHE_VERSION}-static`; const CACHE_TILES = 'ban-yaro-tiles-v1'; // bleibt über SW-Updates erhalten