From f9ec3be09e59d4d2c3c6ae6bfdeab36b75f7fad1 Mon Sep 17 00:00:00 2001 From: Jos Vooges | STH Date: Wed, 23 Sep 2026 02:38:26 +0200 Subject: [PATCH] Fix Viaplay VOD live-edge seek and slow Token Tray typing. Clips no longer use DASH live configuration (was jumping to end). Tray 0.1.2 types slower; no inter-account pause. --- apps/android-tv/app/build.gradle.kts | 4 ++-- .../vonas/mediacluster/tv/playback/PlayerFactory.kt | 10 +++++++--- .../nl/vonas/mediacluster/tv/ui/EventPlayerScreen.kt | 4 +++- apps/token-tray/package.json | 2 +- apps/token-tray/src/jobs.ts | 7 ------- apps/token-tray/src/login/f1tv.ts | 2 +- apps/token-tray/src/login/human.ts | 8 ++++---- apps/token-tray/src/login/viaplay.ts | 3 ++- deploy/agent/token-tray.json | 11 +++++------ 9 files changed, 25 insertions(+), 26 deletions(-) diff --git a/apps/android-tv/app/build.gradle.kts b/apps/android-tv/app/build.gradle.kts index aebe621..5b8f769 100644 --- a/apps/android-tv/app/build.gradle.kts +++ b/apps/android-tv/app/build.gradle.kts @@ -20,8 +20,8 @@ android { applicationId = "nl.vonas.mediacluster.tv" minSdk = 24 targetSdk = 36 - versionCode = 147 - versionName = "0.14.84" + versionCode = 148 + versionName = "0.14.85" buildConfigField("String", "DEFAULT_API_BASE", "\"https://master.vonas.nl\"") ndk { abiFilters += listOf("arm64-v8a", "armeabi-v7a") diff --git a/apps/android-tv/app/src/main/java/nl/vonas/mediacluster/tv/playback/PlayerFactory.kt b/apps/android-tv/app/src/main/java/nl/vonas/mediacluster/tv/playback/PlayerFactory.kt index 7898d44..aa9d16f 100644 --- a/apps/android-tv/app/src/main/java/nl/vonas/mediacluster/tv/playback/PlayerFactory.kt +++ b/apps/android-tv/app/src/main/java/nl/vonas/mediacluster/tv/playback/PlayerFactory.kt @@ -340,12 +340,16 @@ private fun bytesToUuid(bytes: ByteArray): UUID { return UUID(buf.long, buf.long) } -/** TS / HLS / DASH(+ClearKey). */ +/** TS / HLS / DASH(+ClearKey). + * @param live live-edge seek (IPTV/events). Zet false voor VOD/clips — anders landt + * ExoPlayer op het einde van een static/VOD-DASH (lijkt op “afgelopen”-scherm). + */ @OptIn(UnstableApi::class) fun liveMediaItem( url: String, format: String, drm: DrmInfo? = null, + live: Boolean = true, ): MediaItem { // URL wint: ESPN/FAAB levert .m3u8 terwijl de API soms format=dash hardcodet. val isHls = url.contains("m3u8", ignoreCase = true) || @@ -359,7 +363,7 @@ fun liveMediaItem( else -> MimeTypes.VIDEO_MP2T } val builder = MediaItem.Builder().setUri(url).setMimeType(mime) - if (isHls) { + if (live && isHls) { builder.setLiveConfiguration( MediaItem.LiveConfiguration.Builder() .setTargetOffsetMs(2_000) @@ -368,7 +372,7 @@ fun liveMediaItem( .build(), ) } - if (isDash) { + if (live && isDash) { builder.setLiveConfiguration( MediaItem.LiveConfiguration.Builder() .setTargetOffsetMs(3_000) diff --git a/apps/android-tv/app/src/main/java/nl/vonas/mediacluster/tv/ui/EventPlayerScreen.kt b/apps/android-tv/app/src/main/java/nl/vonas/mediacluster/tv/ui/EventPlayerScreen.kt index cc4a38d..ad69adf 100644 --- a/apps/android-tv/app/src/main/java/nl/vonas/mediacluster/tv/ui/EventPlayerScreen.kt +++ b/apps/android-tv/app/src/main/java/nl/vonas/mediacluster/tv/ui/EventPlayerScreen.kt @@ -168,8 +168,10 @@ fun EventPlayerScreen( return@LaunchedEffect } // ClearKey optioneel: F1TV plain HLS heeft drm=null. + // VOD/clips: geen live-config — anders seek naar “live edge” = eindscherm. + val asVod = hubPlay && eventId.startsWith("viaplay-content:", ignoreCase = true) val item = try { - liveMediaItem(url, play.format, play.drm) + liveMediaItem(url, play.format, play.drm, live = !asVod) } catch (e: Exception) { error = e.message ?: "Kon mediastream niet openen" return@LaunchedEffect diff --git a/apps/token-tray/package.json b/apps/token-tray/package.json index 28e3795..8e332c4 100644 --- a/apps/token-tray/package.json +++ b/apps/token-tray/package.json @@ -1,6 +1,6 @@ { "name": "@media-cluster/token-tray", - "version": "0.1.1", + "version": "0.1.2", "private": true, "description": "Windows system tray helper to refresh Viaplay/F1TV session tokens", "author": "Vonas Media Cluster", diff --git a/apps/token-tray/src/jobs.ts b/apps/token-tray/src/jobs.ts index 34834ce..b728930 100644 --- a/apps/token-tray/src/jobs.ts +++ b/apps/token-tray/src/jobs.ts @@ -3,7 +3,6 @@ import type { TrayConfig } from "./config"; import { saveConfig } from "./config"; import { loginViaplayUi } from "./login/viaplay"; import { loginF1tvUi } from "./login/f1tv"; -import { betweenAccounts } from "./login/human"; export type AgentAccount = { provider: "viaplay" | "f1tv"; @@ -145,17 +144,11 @@ export async function refreshAccountsSilent( const notify = opts?.notify !== false; const summary: RefreshSummary = { ok: 0, failed: 0, skipped: 0, errors: [] }; - let attempted = 0; for (const acc of accounts) { if (!acc.password?.trim()) { summary.skipped += 1; continue; } - if (attempted > 0) { - // Captcha-vriendelijk: niet back-to-back inloggen op meerdere accounts - await betweenAccounts(); - } - attempted += 1; try { await refreshOne(cfg, acc, headless); summary.ok += 1; diff --git a/apps/token-tray/src/login/f1tv.ts b/apps/token-tray/src/login/f1tv.ts index 360e9f5..5963035 100644 --- a/apps/token-tray/src/login/f1tv.ts +++ b/apps/token-tray/src/login/f1tv.ts @@ -84,7 +84,7 @@ async function launchProfile(userDataDir: string, headless: boolean) { headless, viewport: { width: 1280, height: 900 } as const, args: ["--disable-blink-features=AutomationControlled"], - slowMo: 40 + Math.floor(Math.random() * 50), + slowMo: 15 + Math.floor(Math.random() * 25), }; for (const channel of ["chrome", "msedge"] as const) { try { diff --git a/apps/token-tray/src/login/human.ts b/apps/token-tray/src/login/human.ts index fe60a5a..f2df66a 100644 --- a/apps/token-tray/src/login/human.ts +++ b/apps/token-tray/src/login/human.ts @@ -18,7 +18,7 @@ export function afterNavigate(): Promise { return humanDelay(1800, 4200); } -/** Pauze tussen accounts bij batch-refresh (captcha-vriendelijk). */ +/** Pauze tussen accounts bij batch-refresh (optioneel; standaard niet gebruikt). */ export function betweenAccounts(): Promise { return humanDelay(12_000, 28_000); } @@ -46,11 +46,11 @@ export async function humanType( delay: 60 + Math.floor(Math.random() * 100), }); await humanDelay(200, 550); - // Per-character delay; geen instant fill() + // Per-character delay; geen instant fill() — expres traag tegen CAPTCHA await locator.pressSequentially(text, { - delay: 55 + Math.floor(Math.random() * 90), + delay: 110 + Math.floor(Math.random() * 160), }); - await humanDelay(280, 800); + await humanDelay(400, 1100); } /** Wacht tot password zichtbaar is, met menselijke poll i.p.v. agressief spammen. */ diff --git a/apps/token-tray/src/login/viaplay.ts b/apps/token-tray/src/login/viaplay.ts index 3d3761b..cad877c 100644 --- a/apps/token-tray/src/login/viaplay.ts +++ b/apps/token-tray/src/login/viaplay.ts @@ -105,7 +105,8 @@ async function launchProfile(userDataDir: string, headless: boolean) { headless, viewport: { width: 1280, height: 900 } as const, args: ["--disable-blink-features=AutomationControlled"], - slowMo: 40 + Math.floor(Math.random() * 50), + // Lichte slowMo; echte CAPTCHA-fix zit in humanType (toetsaanslagen) + slowMo: 15 + Math.floor(Math.random() * 25), }; for (const channel of ["chrome", "msedge"] as const) { try { diff --git a/deploy/agent/token-tray.json b/deploy/agent/token-tray.json index 13d334d..3a15191 100644 --- a/deploy/agent/token-tray.json +++ b/deploy/agent/token-tray.json @@ -1,9 +1,8 @@ { - "version": "0.0.0", + "version": "0.1.2", "filename": "token-tray-setup.exe", - "sizeBytes": 0, - "builtAt": null, + "sizeBytes": 84309324, + "builtAt": "2026-09-23T00:37:43.088Z", "productName": "Media Cluster Token Tray", - "available": false, - "note": "Run apps/token-tray pack:win + publish:installer on Windows, copy token-tray-setup.exe into the Dokploy agent_install volume (/app/install/agent/), then refresh /agent." -} + "available": true +} \ No newline at end of file