From 6b1fc3abd0573100844bb6febc1fd80a09a845a0 Mon Sep 17 00:00:00 2001 From: stratumadev Date: Sat, 2 Aug 2025 11:06:01 +0200 Subject: [PATCH] added total session death function --- @types/crunchyTypes.d.ts | 1 + crunchy.ts | 12 ++++++++++++ modules/module.api-urls.ts | 3 +++ modules/module.app-args.ts | 1 + modules/module.args.ts | 9 +++++++++ 5 files changed, 26 insertions(+) diff --git a/@types/crunchyTypes.d.ts b/@types/crunchyTypes.d.ts index 1c0ac35..5a64097 100644 --- a/@types/crunchyTypes.d.ts +++ b/@types/crunchyTypes.d.ts @@ -10,6 +10,7 @@ export type CrunchyDownloadOptions = { cstream: keyof typeof CrunchyPlayStreams, vstream: keyof typeof CrunchyPlayStreams, astream: keyof typeof CrunchyPlayStreams, + tsd?: boolean, novids?: boolean, noaudio?: boolean, x: number, diff --git a/crunchy.ts b/crunchy.ts index 7d6b8d7..f34f947 100644 --- a/crunchy.ts +++ b/crunchy.ts @@ -1620,6 +1620,18 @@ export default class Crunchy implements ServiceClass { let videoStream: CrunchyPlayStream | null = null; let audioStream: CrunchyPlayStream | null = null; + if (options.tsd) { + console.warn('Total Session Death Active'); + const activeStreamsReq = await this.req.getData(api.streaming, AuthHeaders); + if (activeStreamsReq.ok && activeStreamsReq.res){ + const data = await activeStreamsReq.res.json(); + for (const s of data.items) { + await this.req.getData(`https://www.crunchyroll.com/playback/v1/token/${s.contentId}/${s.token}`, {...{method: 'DELETE'}, ...AuthHeaders}); + } + console.warn(`Killed ${data.items?.length ?? 0} Sessions`); + } + } + const videoPlaybackReq = await this.req.getData(`https://www.crunchyroll.com/playback/v3/${currentVersion ? currentVersion.guid : currentMediaId}/${CrunchyPlayStreams[options.vstream]}/play`, AuthHeaders); if (!videoPlaybackReq.ok || !videoPlaybackReq.res) { console.warn('Request Video Stream URLs FAILED!'); diff --git a/modules/module.api-urls.ts b/modules/module.api-urls.ts index 2174670..535c38b 100644 --- a/modules/module.api-urls.ts +++ b/modules/module.api-urls.ts @@ -34,6 +34,7 @@ export type APIType = { drm: string; drm_widevine: string; drm_playready: string; + streaming: string; /** * Header */ @@ -81,6 +82,8 @@ const api: APIType = { drm_widevine: `${domain.www}/license/v1/license/widevine`, // playready endpoint currently broken drm_playready: `${domain.www}/license/v1/license/playReady`, + // endpoint to get active streaming sessions + streaming: `${domain.www}/playback/v1/sessions/streaming`, crunchyDefHeader: {}, crunchyAuthHeader: {}, //hidive API diff --git a/modules/module.app-args.ts b/modules/module.app-args.ts index b658b25..b291e8f 100644 --- a/modules/module.app-args.ts +++ b/modules/module.app-args.ts @@ -49,6 +49,7 @@ let argvC: { cstream: keyof typeof CrunchyPlayStreams; vstream: keyof typeof CrunchyPlayStreams; astream: keyof typeof CrunchyPlayStreams; + tsd: boolean | undefined; partsize: number; hslang: string; dlsubs: string[]; diff --git a/modules/module.args.ts b/modules/module.args.ts index 9cdcbd2..14f444c 100644 --- a/modules/module.args.ts +++ b/modules/module.args.ts @@ -364,6 +364,15 @@ const args: TAppArg[] = [ docDescribe: true, usage: '${device}' }, + { + name: 'tsd', + group: 'dl', + describe: '(Total Session Death) Kills all active Crunchyroll Streaming Sessions to prevent getting the "TOO_MANY_ACTIVE_STREAMS" error', + docDescribe: true, + service: ['crunchy'], + type: 'boolean', + usage: '' + }, { name: 'hslang', group: 'dl',