mirror of
https://github.com/movie-web/providers.git
synced 2025-09-13 12:43:25 +00:00
fix vidsrc
This commit is contained in:
@@ -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,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
@@ -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> = {
|
||||
|
@@ -91,6 +91,7 @@ export const streambucketScraper = makeEmbed({
|
||||
type: 'hls',
|
||||
playlist: regexResult[1],
|
||||
flags: [flags.NO_CORS],
|
||||
captions: [],
|
||||
},
|
||||
};
|
||||
},
|
||||
|
@@ -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: [],
|
||||
},
|
||||
};
|
||||
},
|
||||
|
@@ -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;
|
||||
};
|
||||
|
@@ -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),
|
||||
};
|
||||
|
@@ -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),
|
||||
};
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user