From 298fad54138cdf405c8eb9db4133cfe1e44332d2 Mon Sep 17 00:00:00 2001 From: Pas <74743263+Pasithea0@users.noreply.github.com> Date: Wed, 21 May 2025 20:45:37 -0600 Subject: [PATCH] add hollymoviehd Update hollymoviehd.ts Update hollymoviehd.ts --- src/providers/all.ts | 2 + src/providers/sources/hollymoviehd.ts | 59 +++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 src/providers/sources/hollymoviehd.ts diff --git a/src/providers/all.ts b/src/providers/all.ts index d1cf886..5c251b7 100644 --- a/src/providers/all.ts +++ b/src/providers/all.ts @@ -96,6 +96,7 @@ import { cuevana3Scraper } from './sources/cuevana3'; import { embedsuScraper } from './sources/embedsu'; import { FedAPIScraper } from './sources/fedapi'; import { hdRezkaScraper } from './sources/hdrezka'; +import { hollymoviehdScraper } from './sources/hollymoviehd'; import { iosmirrorScraper } from './sources/iosmirror'; import { iosmirrorPVScraper } from './sources/iosmirrorpv'; import { nunflixScraper } from './sources/nunflix'; @@ -145,6 +146,7 @@ export function gatherAllSources(): Array { wecimaScraper, animeflvScraper, cinemaosScraper, + hollymoviehdScraper, ]; } diff --git a/src/providers/sources/hollymoviehd.ts b/src/providers/sources/hollymoviehd.ts new file mode 100644 index 0000000..6f3c666 --- /dev/null +++ b/src/providers/sources/hollymoviehd.ts @@ -0,0 +1,59 @@ +import CryptoJS from 'crypto-js'; + +import { flags } from '@/entrypoint/utils/targets'; +import { SourcererOutput, makeSourcerer } from '@/providers/base'; +import { MovieScrapeContext, ShowScrapeContext } from '@/utils/context'; +import { NotFoundError } from '@/utils/errors'; +import { convertPlaylistsToDataUrls } from '@/utils/playlist'; + +const VRF_SECRET_KEY = atob('c3VwZXJzZWNyZXRrZXk='); +const apiBase = 'https://reyna.bludclart.com/api/source/hollymoviehd'; + +function generateVrf(tmdbId: string | number, season: string | number = '', episode: string | number = ''): string { + const msg = `${tmdbId}:${season}:${episode}`; + const hash = CryptoJS.HmacSHA256(msg, VRF_SECRET_KEY); + return hash.toString(CryptoJS.enc.Hex); +} + +async function comboScraper(ctx: ShowScrapeContext | MovieScrapeContext): Promise { + let url = `${apiBase}/${ctx.media.tmdbId}`; + let season = ''; + let episode = ''; + if (ctx.media.type === 'show') { + season = ctx.media.season.number.toString(); + episode = ctx.media.episode.number.toString(); + url += `/${season}/${episode}`; + } + const vrf = generateVrf(ctx.media.tmdbId, season, episode); + url += `?vrf=${vrf}`; + + const data = await ctx.proxiedFetcher(url); + const firstUrl = data?.sources?.[0]?.file; + if (!firstUrl) throw new NotFoundError('Sources not found.'); + ctx.progress(50); + + ctx.progress(90); + return { + embeds: [], + stream: [ + { + id: 'primary', + type: 'hls', + playlist: await convertPlaylistsToDataUrls(ctx.proxiedFetcher, firstUrl), + proxyDepth: 2, + flags: [flags.CORS_ALLOWED], + captions: [], + }, + ], + }; +} + +export const hollymoviehdScraper = makeSourcerer({ + id: 'hollymoviehd', + name: 'HollyMovieHD', + rank: 180, + disabled: false, + flags: [flags.CORS_ALLOWED], + scrapeMovie: comboScraper, + scrapeShow: comboScraper, +});