From b141f8dd79b9abe4947c131754566cf8ac44c7af Mon Sep 17 00:00:00 2001 From: Adrian Castro <22133246+castdrian@users.noreply.github.com> Date: Tue, 20 Feb 2024 16:28:51 +0100 Subject: [PATCH] feat: source timeout --- packages/provider-utils/src/video.ts | 81 +++++++++++++++++++--------- 1 file changed, 57 insertions(+), 24 deletions(-) diff --git a/packages/provider-utils/src/video.ts b/packages/provider-utils/src/video.ts index 44117fe..a353842 100644 --- a/packages/provider-utils/src/video.ts +++ b/packages/provider-utils/src/video.ts @@ -55,6 +55,20 @@ export const providers = makeProviders({ consistentIpForRequests: true, }); +async function withTimeout( + promise: Promise, + timeoutMs: number, +): Promise { + let timeoutHandle: NodeJS.Timeout; + const timeoutPromise = new Promise((_, reject) => { + timeoutHandle = setTimeout(() => reject(new Error("Timeout")), timeoutMs); + }); + + return Promise.race([promise, timeoutPromise]).finally(() => + clearTimeout(timeoutHandle), + ); +} + export async function getVideoStream({ media, forceVTT, @@ -64,20 +78,25 @@ export async function getVideoStream({ forceVTT?: boolean; events?: FullScraperEvents; }): Promise { - const options: RunnerOptions = { - media, - events, - }; + try { + const options: RunnerOptions = { + media, + events, + }; - const stream = await providers.runAll(options); + const stream = await withTimeout(providers.runAll(options), 10000); - if (!stream) return null; + if (!stream) return null; - if (forceVTT) { - const streamResult = await convertStreamCaptionsToWebVTT(stream.stream); - return { ...stream, stream: streamResult }; + if (forceVTT) { + const streamResult = await convertStreamCaptionsToWebVTT(stream.stream); + return { ...stream, stream: streamResult }; + } + + return stream; + } catch (error) { + return null; } - return stream; } export async function getVideoStreamFromSource({ @@ -88,14 +107,21 @@ export async function getVideoStreamFromSource({ sourceId: string; media: ScrapeMedia; events?: SourceRunnerOptions["events"]; -}): Promise { - const sourceResult = await providers.runSourceScraper({ - id: sourceId, - media, - events, - }); +}): Promise { + try { + const sourceResult = await withTimeout( + providers.runSourceScraper({ + id: sourceId, + media, + events, + }), + 10000, + ); - return sourceResult; + return sourceResult; + } catch (error) { + return null; + } } export async function getVideoStreamFromEmbed({ @@ -106,14 +132,21 @@ export async function getVideoStreamFromEmbed({ embedId: string; url: string; events?: EmbedRunnerOptions["events"]; -}): Promise { - const embedResult = await providers.runEmbedScraper({ - id: embedId, - url, - events, - }); +}): Promise { + try { + const embedResult = await withTimeout( + providers.runEmbedScraper({ + id: embedId, + url, + events, + }), + 10000, + ); - return embedResult; + return embedResult; + } catch (error) { + return null; + } } export function findHighestQuality(