From 980682cd28e40f84caf1c8f1072fd79ec49ac62b Mon Sep 17 00:00:00 2001 From: Viren070 Date: Sun, 8 Jun 2025 14:36:06 +0100 Subject: [PATCH] feat: implement pre-caching of the next episode --- packages/core/src/main.ts | 69 +++++++++++++++++-- packages/core/src/wrapper.ts | 9 +++ .../src/components/menu/miscellaneous.tsx | 16 +++++ 3 files changed, 89 insertions(+), 5 deletions(-) diff --git a/packages/core/src/main.ts b/packages/core/src/main.ts index 454cceba..5f1dc73f 100644 --- a/packages/core/src/main.ts +++ b/packages/core/src/main.ts @@ -12,6 +12,7 @@ import { Env, getSimpleTextHash, getTimeTakenSincePoint, + makeRequest, StreamType, TYPES, VISUAL_TAGS, @@ -94,7 +95,8 @@ export class AIOStreams { public async getStreams( id: string, - type: string + type: string, + preCaching: boolean = false ): Promise> { logger.info(`Handling stream request`, { type, id }); @@ -155,6 +157,17 @@ export class AIOStreams { // step 8 // if this.userData.precacheNextEpisode is true, start a new thread to request the next episode, check if // all provider streams are uncached, and only if so, then send a request to the first uncached stream in the list. + if (this.userData.precacheNextEpisode && !preCaching) { + setImmediate(() => { + this.precacheNextEpisode(type, id).catch((error) => { + logger.error('Error during precaching:', { + error: error instanceof Error ? error.message : String(error), + type, + id, + }); + }); + }); + } // step 9 // return the final list of streams, followed by the error streams. @@ -164,13 +177,59 @@ export class AIOStreams { return { success: true, data: proxifiedStreams, - errors: errors.map((error) => ({ - title: error.title, - description: error.description, - })), + errors: errors, }; } + private async precacheNextEpisode(type: string, id: string) { + const seasonEpisodeRegex = /:(\d+):(\d+)$/; + const match = id.match(seasonEpisodeRegex); + if (!match) { + return; + } + const season = match[1]; + const episode = match[2]; + const titleId = id.replace(seasonEpisodeRegex, ''); + const nextEpisodeId = `${titleId}:${season}:${Number(episode) + 1}`; + logger.info(`Pre-caching next episode of ${titleId}`, { + season, + episode, + nextEpisode: Number(episode) + 1, + nextEpisodeId, + }); + const nextStreamsResponse = await this.getStreams( + nextEpisodeId, + type, + true + ); + if (nextStreamsResponse.success) { + const nextStreams = nextStreamsResponse.data; + const serviceStreams = nextStreams.filter((stream) => stream.service); + if (serviceStreams.every((stream) => stream.service?.cached === false)) { + const firstUncachedStream = serviceStreams.find( + (stream) => stream.service?.cached === false + ); + if (firstUncachedStream && firstUncachedStream.url) { + try { + const wrapper = new Wrapper(firstUncachedStream.addon); + logger.debug( + `The following stream was selected for precaching:\n${firstUncachedStream.originalDescription}` + ); + const response = await wrapper.makeRequest(firstUncachedStream.url); + if (!response.ok) { + throw new Error(`${response.status} ${response.statusText}`); + } + logger.debug(`Response: ${response.status} ${response.statusText}`); + } catch (error) { + logger.error(`Error pinging url of first uncached stream`, { + error: error instanceof Error ? error.message : String(error), + }); + } + } + } + } + } + public async getCatalog( type: string, id: string, diff --git a/packages/core/src/wrapper.ts b/packages/core/src/wrapper.ts index 6aa9ae1c..c321787d 100644 --- a/packages/core/src/wrapper.ts +++ b/packages/core/src/wrapper.ts @@ -232,6 +232,15 @@ export class Wrapper { ); } + async makeRequest(url: string) { + return await makeRequest( + url, + this.addon.timeout, + this.addon.headers, + this.addon.ip + ); + } + private async makeResourceRequest( resource: Resource, params: ResourceParams, diff --git a/packages/frontend/src/components/menu/miscellaneous.tsx b/packages/frontend/src/components/menu/miscellaneous.tsx index 0ce8dc26..472b1dae 100644 --- a/packages/frontend/src/components/menu/miscellaneous.tsx +++ b/packages/frontend/src/components/menu/miscellaneous.tsx @@ -64,6 +64,22 @@ function Content() { }} /> + + { + setUserData({ + ...userData, + precacheNextEpisode: value, + }); + }} + /> + );