docker.videokonverter/video-konverter/app/static/tv/sw.js
data 93983cf6ee fix: Tizen-App iframe + Cookie-Fix für Cross-Origin
PROBLEME BEHOBEN:
- Schwarzes Bild beim Video-Abspielen (z-index & iframe-Overlap)
- Login-Cookie wurde nicht gesetzt (Third-Party-Cookie-Blocking)

ÄNDERUNGEN:

Tizen-App (tizen-app/index.html):
- z-index AVPlay von 0 auf 10 erhöht (über iframe)
- iframe wird beim AVPlay-Start ausgeblendet (opacity: 0, pointerEvents: none)
- iframe wird beim AVPlay-Stop wieder eingeblendet
- Fix: <object id="avplayer"> nur im Parent, NICHT im iframe

Player-Template (video-konverter/app/templates/tv/player.html):
- <object id="avplayer"> entfernt (existiert nur im Parent-Frame)
- AVPlay läuft ausschließlich im Tizen-App Parent-Frame

Cookie-Fix (video-konverter/app/routes/tv_api.py):
- SameSite=Lax → SameSite=None (4 Stellen)
- Ermöglicht Session-Cookies im Cross-Origin-iframe
- Login funktioniert jetzt in Tizen-App (tizen:// → http://)

Neue Features:
- VKNative Bridge (vknative-bridge.js): postMessage-Kommunikation iframe ↔ Parent
- AVPlay Bridge (avplay-bridge.js): Legacy Direct-Play Support
- Android-App Scaffolding (android-app/)

TESTERGEBNIS:
-  Login erfolgreich (SameSite=None Cookie)
-  AVPlay Direct-Play funktioniert (samsung-agent/1.1)
-  Bildqualität gut (Hardware-Decoding)
-  Keine Stream-Unterbrechungen
-  Watch-Progress-Tracking funktioniert

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-03-07 08:36:13 +01:00

70 lines
2.1 KiB
JavaScript

/**
* VideoKonverter TV - Service Worker (minimal)
* Ermoeglicht PWA-Installation auf Handys und Tablets
* Kein Offline-Caching noetig (Streaming braucht Netzwerk)
*/
const CACHE_NAME = "vk-tv-v11";
const STATIC_ASSETS = [
"/static/tv/css/tv.css",
"/static/tv/js/tv.js",
"/static/tv/js/player.js",
"/static/tv/js/vknative-bridge.js",
"/static/tv/icons/icon-192.png",
];
// Installation: Statische Assets cachen
self.addEventListener("install", (event) => {
event.waitUntil(
caches.open(CACHE_NAME)
.then(cache => cache.addAll(STATIC_ASSETS))
.then(() => self.skipWaiting())
);
});
// Aktivierung: Alte Caches aufraemen
self.addEventListener("activate", (event) => {
event.waitUntil(
caches.keys()
.then(keys => Promise.all(
keys.filter(k => k !== CACHE_NAME)
.map(k => caches.delete(k))
))
.then(() => self.clients.claim())
);
});
// Fetch: Network-First Strategie (Streaming braucht immer Netzwerk)
self.addEventListener("fetch", (event) => {
// Nur GET-Requests cachen
if (event.request.method !== "GET") return;
// API-Requests und Streaming nie cachen
const url = new URL(event.request.url);
if (url.pathname.startsWith("/api/") || url.pathname.startsWith("/tv/api/")
|| url.pathname.includes("/stream") || url.pathname.includes("/direct-stream")) {
return;
}
// Statische Assets: Cache-First
if (url.pathname.startsWith("/static/tv/")) {
event.respondWith(
caches.match(event.request)
.then(cached => cached || fetch(event.request)
.then(response => {
const clone = response.clone();
caches.open(CACHE_NAME)
.then(cache => cache.put(event.request, clone));
return response;
})
)
);
return;
}
// Alles andere: Network-First
event.respondWith(
fetch(event.request)
.catch(() => caches.match(event.request))
);
});