mirror of
https://github.com/sussy-code/providers.git
synced 2026-01-11 20:10:17 +00:00
Add vidsrc.su
This commit is contained in:
parent
f5a8df4c01
commit
ef7a4c8bde
5 changed files with 712 additions and 534 deletions
|
|
@ -76,7 +76,7 @@
|
||||||
"spinnies": "^0.5.1",
|
"spinnies": "^0.5.1",
|
||||||
"tsc-alias": "^1.8.10",
|
"tsc-alias": "^1.8.10",
|
||||||
"tsconfig-paths": "^4.2.0",
|
"tsconfig-paths": "^4.2.0",
|
||||||
"typescript": "^5.7.2",
|
"typescript": "^5.7.3",
|
||||||
"vite": "^5.4.11",
|
"vite": "^5.4.11",
|
||||||
"vite-node": "^1.6.0",
|
"vite-node": "^1.6.0",
|
||||||
"vite-plugin-dts": "^3.9.1",
|
"vite-plugin-dts": "^3.9.1",
|
||||||
|
|
@ -87,8 +87,9 @@
|
||||||
"cookie": "^0.6.0",
|
"cookie": "^0.6.0",
|
||||||
"crypto-js": "^4.2.0",
|
"crypto-js": "^4.2.0",
|
||||||
"form-data": "^4.0.1",
|
"form-data": "^4.0.1",
|
||||||
"hls-parser": "^0.13.3",
|
"hls-parser": "^0.13.5",
|
||||||
"iso-639-1": "^3.1.3",
|
"iso-639-1": "^3.1.3",
|
||||||
|
"json5": "^2.2.3",
|
||||||
"nanoid": "^3.3.8",
|
"nanoid": "^3.3.8",
|
||||||
"node-fetch": "^3.3.2",
|
"node-fetch": "^3.3.2",
|
||||||
"set-cookie-parser": "^2.7.1",
|
"set-cookie-parser": "^2.7.1",
|
||||||
|
|
|
||||||
1178
pnpm-lock.yaml
1178
pnpm-lock.yaml
File diff suppressed because it is too large
Load diff
|
|
@ -95,6 +95,7 @@ async function runActualScraping(
|
||||||
|
|
||||||
if (source.type === 'embed') {
|
if (source.type === 'embed') {
|
||||||
return providers.runEmbedScraper({
|
return providers.runEmbedScraper({
|
||||||
|
disableOpensubtitles: true,
|
||||||
url: options.url,
|
url: options.url,
|
||||||
id: source.id,
|
id: source.id,
|
||||||
});
|
});
|
||||||
|
|
@ -110,6 +111,7 @@ async function runActualScraping(
|
||||||
}
|
}
|
||||||
|
|
||||||
return providers.runSourceScraper({
|
return providers.runSourceScraper({
|
||||||
|
disableOpensubtitles: true,
|
||||||
media,
|
media,
|
||||||
id: source.id,
|
id: source.id,
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ import { remotestreamScraper } from '@/providers/sources/remotestream';
|
||||||
import { showboxScraper } from '@/providers/sources/showbox/index';
|
import { showboxScraper } from '@/providers/sources/showbox/index';
|
||||||
import { tugaflixScraper } from '@/providers/sources/tugaflix';
|
import { tugaflixScraper } from '@/providers/sources/tugaflix';
|
||||||
import { vidsrcScraper } from '@/providers/sources/vidsrc/index';
|
import { vidsrcScraper } from '@/providers/sources/vidsrc/index';
|
||||||
|
import { vidsrcsuScraper } from '@/providers/sources/vidsrcsu';
|
||||||
import { whvxScraper } from '@/providers/sources/whvx';
|
import { whvxScraper } from '@/providers/sources/whvx';
|
||||||
import { zoechipScraper } from '@/providers/sources/zoechip';
|
import { zoechipScraper } from '@/providers/sources/zoechip';
|
||||||
|
|
||||||
|
|
@ -104,6 +105,7 @@ export function gatherAllSources(): Array<Sourcerer> {
|
||||||
fsharetvScraper,
|
fsharetvScraper,
|
||||||
redStarScraper,
|
redStarScraper,
|
||||||
bombtheirishScraper,
|
bombtheirishScraper,
|
||||||
|
vidsrcsuScraper,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
59
src/providers/sources/vidsrcsu.ts
Normal file
59
src/providers/sources/vidsrcsu.ts
Normal file
|
|
@ -0,0 +1,59 @@
|
||||||
|
import JSON5 from 'json5';
|
||||||
|
|
||||||
|
import { flags } from '@/entrypoint/utils/targets';
|
||||||
|
import { SourcererOutput, makeSourcerer } from '@/providers/base';
|
||||||
|
import { Caption, labelToLanguageCode } from '@/providers/captions';
|
||||||
|
import { MovieScrapeContext, ShowScrapeContext } from '@/utils/context';
|
||||||
|
import { NotFoundError } from '@/utils/errors';
|
||||||
|
|
||||||
|
async function comboScraper(ctx: ShowScrapeContext | MovieScrapeContext): Promise<SourcererOutput> {
|
||||||
|
const embedPage = await ctx.proxiedFetcher(
|
||||||
|
`https://vidsrc.su/embed/${ctx.media.type === 'movie' ? `movie/${ctx.media.tmdbId}` : `tv/${ctx.media.tmdbId}/${ctx.media.season.number}/${ctx.media.episode.number}`}`,
|
||||||
|
);
|
||||||
|
const serverDataMatch = embedPage.match(/const fixedServers = +(\[.*?\])/s);
|
||||||
|
if (!serverDataMatch[1]) throw new NotFoundError('No data found');
|
||||||
|
// const servers: { label: string; url: string }[] = JSON.parse(serverDataMatch[1].replace(/([a-zA-Z0-9_]+): /g, '"$1":').replace(/'/g, '"').replace(/,\s*\]$/, ']'))
|
||||||
|
const servers: { label: string; url: string }[] = JSON5.parse(serverDataMatch[1]);
|
||||||
|
let playlist;
|
||||||
|
// we only want flixhq which is server 1 and server 2
|
||||||
|
servers.forEach((server) => {
|
||||||
|
if (['Server 1', 'Server 2'].includes(server.label) && server.url) playlist = server.url;
|
||||||
|
});
|
||||||
|
if (!playlist) throw new NotFoundError('No flixhq playlist found');
|
||||||
|
const captionsDataMatch = embedPage.match(/const subtitles = +(\[.*?\])/s);
|
||||||
|
const captions: Caption[] = [];
|
||||||
|
if (captionsDataMatch[1]) {
|
||||||
|
const captionsData: { label: string; file: string }[] = JSON5.parse(captionsDataMatch[1]);
|
||||||
|
for (const caption of captionsData) {
|
||||||
|
const language = labelToLanguageCode(caption.label);
|
||||||
|
if (!language) continue;
|
||||||
|
captions.push({
|
||||||
|
id: caption.file,
|
||||||
|
url: caption.file,
|
||||||
|
type: 'vtt',
|
||||||
|
hasCorsRestrictions: false,
|
||||||
|
language,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
embeds: [],
|
||||||
|
stream: [
|
||||||
|
{
|
||||||
|
id: 'primary',
|
||||||
|
playlist,
|
||||||
|
type: 'hls',
|
||||||
|
flags: [flags.CORS_ALLOWED],
|
||||||
|
captions,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
export const vidsrcsuScraper = makeSourcerer({
|
||||||
|
id: 'vidsrcsu',
|
||||||
|
name: 'vidsrc.su (FlixHQ)',
|
||||||
|
rank: 229,
|
||||||
|
flags: [flags.CORS_ALLOWED],
|
||||||
|
scrapeMovie: comboScraper,
|
||||||
|
scrapeShow: comboScraper,
|
||||||
|
});
|
||||||
Loading…
Reference in a new issue