fix vidsrc

This commit is contained in:
Jorrin
2023-12-25 22:51:55 +01:00
parent 82034b91ed
commit 64050df350
8 changed files with 27 additions and 58 deletions

View File

@@ -34,7 +34,7 @@ export function makeFullFetcher(fetcher: Fetcher): UseableFetcher {
query: ops?.query ?? {},
baseUrl: ops?.baseUrl ?? '',
body: ops?.body,
returnRaw: ops?.returnRaw,
returnRaw: ops?.returnRaw ?? false,
});
};
}

View File

@@ -15,7 +15,7 @@ export type DefaultedFetcherOptions = {
headers: Record<string, string>;
query: Record<string, string>;
method: 'HEAD' | 'GET' | 'POST';
returnRaw?: boolean;
returnRaw: boolean;
};
export type Fetcher<T = any> = {

View File

@@ -91,6 +91,7 @@ export const streambucketScraper = makeEmbed({
type: 'hls',
playlist: regexResult[1],
flags: [flags.NO_CORS],
captions: [],
},
};
},

View File

@@ -1,8 +1,6 @@
import { flags } from '@/main/targets';
import { makeEmbed } from '@/providers/base';
const hlsURLRegex = /var hls_url = "(.*?)";/;
const setPassRegex = /var path = "(.*set_pass\.php.*)";/;
const hlsURLRegex = /file:"(.*?)"/;
export const vidsrcembedScraper = makeEmbed({
id: 'vidsrcembed', // VidSrc is both a source and an embed host
@@ -16,34 +14,21 @@ export const vidsrcembedScraper = makeEmbed({
headers: ctx.headers,
});
let regexResult = html.match(setPassRegex);
if (!regexResult) {
throw new Error('Unable to find VidSrc set_pass.php link');
}
const match = html
.match(hlsURLRegex)?.[1]
?.replace(/(\/\/\S+?=)/g, '')
.replace('#2', '');
if (!match) throw new Error('Unable to find HLS playlist');
const finalUrl = atob(match);
let setPassLink = regexResult[1];
if (setPassLink.startsWith('//')) {
setPassLink = `https:${setPassLink}`;
}
regexResult = html.match(hlsURLRegex);
if (!regexResult) {
throw new Error('Unable to find VidSrc HLS stream');
}
// Must call set_pass.php BEFORE using the stream
await fetch(setPassLink, {
headers: {
referer: ctx.url,
},
});
if (!finalUrl.includes('.m3u8')) throw new Error('Unable to find HLS playlist');
return {
stream: {
type: 'hls',
playlist: regexResult[1],
flags: [flags.NO_CORS],
playlist: finalUrl,
flags: [],
captions: [],
},
};
},

View File

@@ -1,13 +1,2 @@
import { MovieMedia, ShowMedia } from '@/main/media';
import { ScrapeContext } from '@/utils/context';
export const vidsrcBase = 'https://vidsrc.me';
export const vidsrcRCPBase = 'https://rcp.vidsrc.me';
export type MovieContext = ScrapeContext & {
media: MovieMedia;
};
export type ShowContext = ScrapeContext & {
media: ShowMedia;
};

View File

@@ -1,7 +1,7 @@
import { MovieContext } from '@/providers/sources/vidsrc/common';
import { getVidSrcMovieSources } from '@/providers/sources/vidsrc/scrape';
import { MovieScrapeContext } from '@/utils/context';
export async function scrapeMovie(ctx: MovieContext) {
export async function scrapeMovie(ctx: MovieScrapeContext) {
return {
embeds: await getVidSrcMovieSources(ctx),
};

View File

@@ -1,7 +1,7 @@
import { ShowContext } from '@/providers/sources/vidsrc/common';
import { getVidSrcShowSources } from '@/providers/sources/vidsrc/scrape';
import { ShowScrapeContext } from '@/utils/context';
export async function scrapeShow(ctx: ShowContext) {
export async function scrapeShow(ctx: ShowScrapeContext) {
return {
embeds: await getVidSrcShowSources(ctx),
};

View File

@@ -1,9 +1,11 @@
import { load } from 'cheerio';
import { FetchReply } from '@/fetchers/fetch';
import { SourcererEmbed } from '@/providers/base';
import { streambucketScraper } from '@/providers/embeds/streambucket';
import { vidsrcembedScraper } from '@/providers/embeds/vidsrc';
import { MovieContext, ShowContext, vidsrcBase, vidsrcRCPBase } from '@/providers/sources/vidsrc/common';
import { vidsrcBase, vidsrcRCPBase } from '@/providers/sources/vidsrc/common';
import { MovieScrapeContext, ShowScrapeContext } from '@/utils/context';
function decodeSrc(encoded: string, seed: string) {
const encodedBuffer = Buffer.from(encoded, 'hex');
@@ -16,7 +18,7 @@ function decodeSrc(encoded: string, seed: string) {
return decoded;
}
async function getVidSrcEmbeds(ctx: MovieContext | ShowContext, startingURL: string) {
async function getVidSrcEmbeds(ctx: MovieScrapeContext | ShowScrapeContext, startingURL: string) {
// VidSrc works by using hashes and a redirect system.
// The hashes are stored in the html, and VidSrc will
// make requests to their servers with the hash. This
@@ -25,11 +27,7 @@ async function getVidSrcEmbeds(ctx: MovieContext | ShowContext, startingURL: str
// real embed links, we must do the same. Slow, but
// required
const embeds: {
embedId: string;
url: string;
headers?: Record<string, string>;
}[] = [];
const embeds: SourcererEmbed[] = [];
let html = await ctx.proxiedFetcher<string>(startingURL, {
baseUrl: vidsrcBase,
@@ -37,7 +35,7 @@ async function getVidSrcEmbeds(ctx: MovieContext | ShowContext, startingURL: str
let $ = load(html);
const sourceHashes = $('.source[data-hash]')
const sourceHashes = $('.server[data-hash]')
.toArray()
.map((el) => $(el).attr('data-hash'))
.filter((hash) => hash !== undefined);
@@ -76,11 +74,7 @@ async function getVidSrcEmbeds(ctx: MovieContext | ShowContext, startingURL: str
},
});
const embed: {
embedId: string;
url: string;
headers?: Record<string, string>;
} = {
const embed: SourcererEmbed = {
embedId: '',
url: embedURL,
};
@@ -117,11 +111,11 @@ async function getVidSrcEmbeds(ctx: MovieContext | ShowContext, startingURL: str
return embeds;
}
export async function getVidSrcMovieSources(ctx: MovieContext) {
export async function getVidSrcMovieSources(ctx: MovieScrapeContext) {
return getVidSrcEmbeds(ctx, `/embed/${ctx.media.tmdbId}`);
}
export async function getVidSrcShowSources(ctx: ShowContext) {
export async function getVidSrcShowSources(ctx: ShowScrapeContext) {
// VidSrc will always default to season 1 episode 1
// no matter what embed URL is used. It sends back
// a list of ALL the shows episodes, in order, for