Reject Viaplay Don't go fallback and restore live play-live query.
This commit is contained in:
parent
e4714a7d09
commit
98c38826e1
2 changed files with 34 additions and 49 deletions
|
|
@ -766,8 +766,12 @@ function extractProducts(json: unknown): ViaplayEpgProduct[] {
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** HAR: Don't go-placeholder (live soft-fail). Clips mogen dit pad wél hebben. */
|
/**
|
||||||
export const VIAPLAY_DONT_GO_MEDIA_RE = /\/7c4cd64\/88000100-1778484912807\.ism\b/i;
|
* Don't go is Viaplay's soft-fail (200 + promo-VOD) i.p.v. 403.
|
||||||
|
* Titel/guid van het event kloppen vaak wél; alleen de media is fout.
|
||||||
|
*/
|
||||||
|
const VIAPLAY_DONT_GO_MEDIA_RE =
|
||||||
|
/88000100-1778484912807|\b7c4cd64\b|\/dont[-_]?go/i;
|
||||||
|
|
||||||
export function isDontGoPlaceholder(mpdUrl: string | null | undefined): boolean {
|
export function isDontGoPlaceholder(mpdUrl: string | null | undefined): boolean {
|
||||||
return !!mpdUrl && VIAPLAY_DONT_GO_MEDIA_RE.test(mpdUrl);
|
return !!mpdUrl && VIAPLAY_DONT_GO_MEDIA_RE.test(mpdUrl);
|
||||||
|
|
@ -777,31 +781,18 @@ export function isLiveDashMpd(mpdUrl: string | null | undefined): boolean {
|
||||||
return !!mpdUrl && /live-dash/i.test(mpdUrl);
|
return !!mpdUrl && /live-dash/i.test(mpdUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
function sportContentUrls(
|
function assertLivePlayNotSoftFail(played: ViaplayPlayResult): void {
|
||||||
pageUrl: string | null | undefined,
|
if (isPromoVodTitle(played.title)) {
|
||||||
deviceKey: string,
|
throw new Error(`Viaplay gaf promo-stream (“${played.title}”)`);
|
||||||
mediaGuid: string
|
|
||||||
): { productUrl: string; contextualUrl: string; contextualv2Url: string } {
|
|
||||||
const guidPath = mediaGuid.replace(/-NL$/i, "").toLowerCase();
|
|
||||||
let clean = "";
|
|
||||||
const raw = (pageUrl || "").trim();
|
|
||||||
if (raw) {
|
|
||||||
try {
|
|
||||||
const u = new URL(raw);
|
|
||||||
u.search = "";
|
|
||||||
clean = u.toString().replace(/\/$/, "");
|
|
||||||
} catch {
|
|
||||||
clean = "";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (!clean) {
|
if (isDontGoPlaceholder(played.mpdUrl)) {
|
||||||
clean = `https://content.viaplay.com/${deviceKey}/sport/${guidPath}`;
|
throw new Error("Viaplay gaf Don't go-placeholder i.p.v. de wedstrijdstream");
|
||||||
|
}
|
||||||
|
if (!isLiveDashMpd(played.mpdUrl)) {
|
||||||
|
throw new Error(
|
||||||
|
"Viaplay gaf geen live-dash stream (Don't go/VOD-fallback — sessie of rechten)"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return {
|
|
||||||
productUrl: `${clean}?partial=true`,
|
|
||||||
contextualUrl: `${clean}?contextual=true`,
|
|
||||||
contextualv2Url: `${clean}?contextualV2=true&productType=sport`,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function playByMediaGuid(
|
export async function playByMediaGuid(
|
||||||
|
|
@ -810,11 +801,8 @@ export async function playByMediaGuid(
|
||||||
opts: { deviceKey: string; timeoutMs: number; pageUrl?: string | null }
|
opts: { deviceKey: string; timeoutMs: number; pageUrl?: string | null }
|
||||||
): Promise<ViaplayPlayResult> {
|
): Promise<ViaplayPlayResult> {
|
||||||
const mediaGuid = toMediaGuid(mediaGuidRaw);
|
const mediaGuid = toMediaGuid(mediaGuidRaw);
|
||||||
const pages = sportContentUrls(opts.pageUrl, opts.deviceKey, mediaGuid);
|
// Zelfde query als het werkende live-script. Extra HAR-svod/producturl
|
||||||
const returnUrl = new URL(`https://content.viaplay.com/${opts.deviceKey}`);
|
// triggert bij terugkijken de Don't go-VOD-fallback.
|
||||||
returnUrl.searchParams.set("language", "nl");
|
|
||||||
if (creds.profileId) returnUrl.searchParams.set("profileId", creds.profileId);
|
|
||||||
|
|
||||||
const u = new URL("https://play-live.viaplay.com/api/stream/bymediaguid");
|
const u = new URL("https://play-live.viaplay.com/api/stream/bymediaguid");
|
||||||
u.searchParams.set("deviceId", creds.deviceId || randomUUID());
|
u.searchParams.set("deviceId", creds.deviceId || randomUUID());
|
||||||
u.searchParams.set("deviceName", "web");
|
u.searchParams.set("deviceName", "web");
|
||||||
|
|
@ -822,19 +810,7 @@ export async function playByMediaGuid(
|
||||||
u.searchParams.set("userAgent", VIAPLAY_USER_AGENT);
|
u.searchParams.set("userAgent", VIAPLAY_USER_AGENT);
|
||||||
u.searchParams.set("deviceKey", opts.deviceKey);
|
u.searchParams.set("deviceKey", opts.deviceKey);
|
||||||
u.searchParams.set("mediaGuid", mediaGuid);
|
u.searchParams.set("mediaGuid", mediaGuid);
|
||||||
u.searchParams.set("cse", "true");
|
|
||||||
u.searchParams.set("nocc", "autoplayer");
|
u.searchParams.set("nocc", "autoplayer");
|
||||||
u.searchParams.set(
|
|
||||||
"splitIOFlagIds",
|
|
||||||
"all_sports_beyondLiveBeacon_on,web_player_pause_ads_on"
|
|
||||||
);
|
|
||||||
u.searchParams.set("returnurl", returnUrl.toString());
|
|
||||||
u.searchParams.set("producturl", pages.productUrl);
|
|
||||||
u.searchParams.set("contextualurl", pages.contextualUrl);
|
|
||||||
u.searchParams.set("contextualv2url", pages.contextualv2Url);
|
|
||||||
u.searchParams.set("sectionPath", "/sport");
|
|
||||||
u.searchParams.set("defaultAvailabilityContext", "svod");
|
|
||||||
u.searchParams.set("win10edge", "true");
|
|
||||||
if (creds.profileId) u.searchParams.set("profileId", creds.profileId);
|
if (creds.profileId) u.searchParams.set("profileId", creds.profileId);
|
||||||
|
|
||||||
const res = await fetchJson(u.toString(), {
|
const res = await fetchJson(u.toString(), {
|
||||||
|
|
@ -849,11 +825,7 @@ export async function playByMediaGuid(
|
||||||
throw new Error(msg);
|
throw new Error(msg);
|
||||||
}
|
}
|
||||||
const played = parsePlayStreamBody(body, mediaGuid);
|
const played = parsePlayStreamBody(body, mediaGuid);
|
||||||
if (isDontGoPlaceholder(played.mpdUrl)) {
|
assertLivePlayNotSoftFail(played);
|
||||||
throw new Error(
|
|
||||||
"Viaplay play-live gaf Don't go-placeholder i.p.v. de wedstrijdstream"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return played;
|
return played;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -969,8 +941,7 @@ function playBodyGuid(body: Record<string, unknown>): string | null {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HAR afspelen.har: web speelt clip als guid+titel kloppen, ook zonder DRM
|
* Soft-fail: 200 met juiste product-metadata maar Don't go / promo-MPD.
|
||||||
* en met cse mediaGuid=unknown. Alleen een promo-titel is een echte soft-fail.
|
|
||||||
*/
|
*/
|
||||||
function assertVodPlayMatchesGuid(
|
function assertVodPlayMatchesGuid(
|
||||||
body: Record<string, unknown>,
|
body: Record<string, unknown>,
|
||||||
|
|
@ -991,6 +962,11 @@ function assertVodPlayMatchesGuid(
|
||||||
if (isPromoVodTitle(played.title)) {
|
if (isPromoVodTitle(played.title)) {
|
||||||
throw new Error(`Viaplay gaf promo-stream (“${played.title}”)`);
|
throw new Error(`Viaplay gaf promo-stream (“${played.title}”)`);
|
||||||
}
|
}
|
||||||
|
if (isDontGoPlaceholder(played.mpdUrl)) {
|
||||||
|
throw new Error(
|
||||||
|
"Viaplay gaf Don't go-placeholder i.p.v. de gevraagde stream"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const links = asRecord(body._links);
|
const links = asRecord(body._links);
|
||||||
const productHref = asRecord(links?.["viaplay:product"])?.href;
|
const productHref = asRecord(links?.["viaplay:product"])?.href;
|
||||||
|
|
|
||||||
|
|
@ -368,6 +368,12 @@ export async function ensureViaplayEventReady(
|
||||||
if (play.licenseUrl && !keys.length) {
|
if (play.licenseUrl && !keys.length) {
|
||||||
throw new Error("Viaplay-licentie aanwezig maar geen keys");
|
throw new Error("Viaplay-licentie aanwezig maar geen keys");
|
||||||
}
|
}
|
||||||
|
if (isDontGoPlaceholder(play.mpdUrl) || isDontGoPlaceholder(kap.mpdUrl)) {
|
||||||
|
throw new Error("Viaplay gaf Don't go-placeholder i.p.v. de wedstrijdstream");
|
||||||
|
}
|
||||||
|
if (!isLiveDashMpd(play.mpdUrl)) {
|
||||||
|
throw new Error("Viaplay gaf geen live-dash stream (Don't go/VOD-fallback)");
|
||||||
|
}
|
||||||
|
|
||||||
await patchViaplayEventCache(mediaGuid, {
|
await patchViaplayEventCache(mediaGuid, {
|
||||||
mpdUrl: kap.mpdUrl,
|
mpdUrl: kap.mpdUrl,
|
||||||
|
|
@ -576,6 +582,9 @@ async function resolveViaplayGuidPlayInner(
|
||||||
throw new Error("Viaplay-licentie aanwezig maar geen VOD-keys");
|
throw new Error("Viaplay-licentie aanwezig maar geen VOD-keys");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (isDontGoPlaceholder(mpdUrl)) {
|
||||||
|
throw new Error("Viaplay gaf Don't go-placeholder i.p.v. de gevraagde stream");
|
||||||
|
}
|
||||||
|
|
||||||
recordVodPlay({
|
recordVodPlay({
|
||||||
guid,
|
guid,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue