Fix Viaplay live and catch-up play.
Allow 48h catch-up instead of rejecting ended events, and fetch keys via bootstrap PSSH when the live MPD has none.
This commit is contained in:
parent
b783ba137f
commit
7cdff2bde4
4 changed files with 52 additions and 5 deletions
|
|
@ -24,8 +24,10 @@ def main():
|
|||
or "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/153.0.0.0 Safari/537.36",
|
||||
"Content-Type": "application/octet-stream",
|
||||
}
|
||||
lic_url = data.get("licUrl") or ""
|
||||
auth = (data.get("licAuth") or "").strip()
|
||||
if auth:
|
||||
# Token zit al in de URL — extra Authorization/Cookie geeft 431/403 (werkend script).
|
||||
if auth and "token=" not in lic_url and "auth=" not in lic_url:
|
||||
headers["Authorization"] = f"Basic {auth}"
|
||||
response = requests.post(
|
||||
data["licUrl"],
|
||||
|
|
|
|||
|
|
@ -1242,6 +1242,32 @@ export async function fetchMpdXml(
|
|||
return { status: response.status, xml, url };
|
||||
}
|
||||
|
||||
/**
|
||||
* Live MPD's zijn soms zonder PSSH. Het werkende Viaplay-script gebruikt
|
||||
* dan de Widevine-PSSH van een bekende Xtra-zender voor de license-challenge.
|
||||
*/
|
||||
const VIAPLAY_BOOTSTRAP_MPD =
|
||||
"https://live-dash-cdn7-cf-mp-v2.cdn.viaplay.tv/mediapkg-prod-eu-north-1/vp-xtra16/vp-xtra16-dashwv/index.mpd";
|
||||
|
||||
let bootstrapPsshCache: string | null = null;
|
||||
|
||||
export async function fetchViaplayBootstrapPssh(
|
||||
timeoutMs: number
|
||||
): Promise<string | null> {
|
||||
if (bootstrapPsshCache) return bootstrapPsshCache;
|
||||
try {
|
||||
const res = await fetchMpdXml(VIAPLAY_BOOTSTRAP_MPD, Math.min(timeoutMs, 15_000));
|
||||
const pssh = extractPsshFromMpd(res.xml);
|
||||
if (pssh) {
|
||||
bootstrapPsshCache = pssh;
|
||||
return pssh;
|
||||
}
|
||||
} catch {
|
||||
/* next play mag opnieuw proberen */
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export function extractPsshFromMpd(xml: string): string | null {
|
||||
const widevine = xml.match(
|
||||
/<ContentProtection\b[^>]*schemeIdUri=["']urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed["'][\s\S]*?<\/ContentProtection>/i
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import {
|
|||
resolveKapMpd,
|
||||
fetchMpdXml,
|
||||
extractPsshFromMpd,
|
||||
fetchViaplayBootstrapPssh,
|
||||
VIAPLAY_USER_AGENT,
|
||||
} from "./client";
|
||||
import {
|
||||
|
|
@ -243,10 +244,15 @@ export async function ensureViaplayEventReady(
|
|||
|
||||
let keys = cachedKeys;
|
||||
const wantKeys = opts?.fetchKeys ?? tweaks.fetchKeysIfMissing;
|
||||
if (wantKeys && kap.pssh && play.licenseUrl && !keys.length) {
|
||||
if (wantKeys && play.licenseUrl && !keys.length) {
|
||||
const pssh =
|
||||
kap.pssh || (await fetchViaplayBootstrapPssh(tweaks.httpTimeoutMs));
|
||||
if (!pssh) {
|
||||
throw new Error("Geen PSSH (MPD + bootstrap) — keys niet op te halen");
|
||||
}
|
||||
const extracted = await extractViaplayKeys({
|
||||
wvdPath: settings.wvdPath,
|
||||
pssh: kap.pssh,
|
||||
pssh,
|
||||
licUrl: play.licenseUrl,
|
||||
licAuth: play.licenseAuth,
|
||||
userAgent: VIAPLAY_USER_AGENT,
|
||||
|
|
@ -275,6 +281,10 @@ export async function ensureViaplayEventReady(
|
|||
}
|
||||
}
|
||||
|
||||
if (play.licenseUrl && !keys.length) {
|
||||
throw new Error("Viaplay-licentie aanwezig maar geen keys");
|
||||
}
|
||||
|
||||
await patchViaplayEventCache(mediaGuid, {
|
||||
mpdUrl: kap.mpdUrl,
|
||||
mpdCachedAt: new Date().toISOString(),
|
||||
|
|
@ -409,7 +419,13 @@ export async function resolveViaplayGuidPlay(
|
|||
// Clear VOD (HAR: geen license) — nooit stale ClearKey van eerdere plays plakken.
|
||||
if (!play.licenseUrl) {
|
||||
keys = [];
|
||||
} else if (wantKeys && pssh && !keys.length) {
|
||||
} else if (wantKeys && !keys.length) {
|
||||
if (!pssh) {
|
||||
pssh = await fetchViaplayBootstrapPssh(tweaks.httpTimeoutMs);
|
||||
}
|
||||
if (!pssh) {
|
||||
throw new Error("Geen PSSH (MPD + bootstrap) — VOD-keys niet op te halen");
|
||||
}
|
||||
const extracted = await extractViaplayKeys({
|
||||
wvdPath: settings.wvdPath,
|
||||
pssh,
|
||||
|
|
@ -442,6 +458,9 @@ export async function resolveViaplayGuidPlay(
|
|||
}
|
||||
}
|
||||
}
|
||||
if (!keys.length) {
|
||||
throw new Error("Viaplay-licentie aanwezig maar geen VOD-keys");
|
||||
}
|
||||
}
|
||||
|
||||
recordVodPlay({
|
||||
|
|
|
|||
|
|
@ -1116,7 +1116,7 @@ export async function getScheduleEventPlay(
|
|||
if (!providerAllowed(pub.provider, disabledGlobal, access?.allowedProviders ?? null)) {
|
||||
throw new AppError("NOT_FOUND", "Event niet gevonden", 404);
|
||||
}
|
||||
if (pub.phase === "ended") {
|
||||
if (pub.phase === "ended" && !pub.playable) {
|
||||
throw new AppError("GONE", "Dit event is afgelopen", 410);
|
||||
}
|
||||
if (pub.phase === "upcoming") {
|
||||
|
|
|
|||
Loading…
Reference in a new issue