mirror of
https://github.com/Inside4ndroid/TMDB-Embed-API.git
synced 2026-10-22 09:35:11 +00:00
added filemoon extractor
This commit is contained in:
@@ -1,5 +1,7 @@
|
|||||||
import express from "express";
|
import express from "express";
|
||||||
import { getmovie, getserie } from "./src/vidsrcto.js";
|
import { getvmovie, getvserie } from "./src/vidsrcto.js";
|
||||||
|
import { getfmovie, getfserie } from "./src/filemoon.js";
|
||||||
|
|
||||||
|
|
||||||
const port = 3000;
|
const port = 3000;
|
||||||
|
|
||||||
@@ -12,7 +14,7 @@ app.get('/', (req, res) => {
|
|||||||
movie: "/vidsrc/:movieTMDBid",
|
movie: "/vidsrc/:movieTMDBid",
|
||||||
show: "/vidsrc/:showTMDBid?s=seasonNumber&e=episodeNumber"
|
show: "/vidsrc/:showTMDBid?s=seasonNumber&e=episodeNumber"
|
||||||
},
|
},
|
||||||
author: "This api is developed and created by AijaZ"
|
author: "This api is developed and created by Inside4ndroid Studios"
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -21,29 +23,22 @@ app.get('/vidsrc/:tmdbId', async (req, res) => {
|
|||||||
const season = req.query.s;
|
const season = req.query.s;
|
||||||
const episode = req.query.e;
|
const episode = req.query.e;
|
||||||
|
|
||||||
if (season && episode) {
|
try {
|
||||||
const response = await getserie(id, season, episode);
|
if (season && episode) {
|
||||||
if (!response) {
|
const vidsrcresponse = await getvserie(id, season, episode);
|
||||||
res.status(404).send({
|
const filemoonresponse = await getfserie(id, season, episode);
|
||||||
status: 404,
|
const combinedResponse = { ...filemoonresponse, ...vidsrcresponse };
|
||||||
return: "Oops reached rate limit of this api"
|
res.status(200).json(combinedResponse);
|
||||||
})
|
|
||||||
} else {
|
} else {
|
||||||
res.status(200).json([response]);
|
const vidsrcresponse = await getvmovie(id);
|
||||||
}
|
const filemoonresponse = await getfmovie(id);
|
||||||
} else {
|
const combinedResponse = { ...filemoonresponse, ...vidsrcresponse };
|
||||||
const response = await getmovie(id);
|
res.status(200).json(combinedResponse);
|
||||||
|
|
||||||
if (!response) {
|
|
||||||
res.status(404).send({
|
|
||||||
status: 404,
|
|
||||||
return: "Oops reached rate limit of this api"
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
res.status(200).json([response]);
|
|
||||||
}
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error fetching data:', error);
|
||||||
|
res.status(500).json({ error: 'Failed to fetch data' });
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
app.listen(port, () => {
|
app.listen(port, () => {
|
||||||
|
|||||||
+3
-3
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "vidsrc-api-v2",
|
"name": "vidsrc-api-v2",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "An api that scrapes vidsrc.to and vidsrc.me",
|
"description": "An api that scrapes vidsrc (f2cloud, filemoon) plus subtitles",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
"author": "Inside4ndroid Studios Ltd",
|
"author": "Inside4ndroid Studios Ltd",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"express": "^4.18.2"
|
"express": "^4.18.2",
|
||||||
|
"unpacker": "^1.0.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+137
@@ -0,0 +1,137 @@
|
|||||||
|
import { getKeys } from './getKeys.js';
|
||||||
|
import { unpack } from 'unpacker';
|
||||||
|
|
||||||
|
const keys = await getKeys();
|
||||||
|
|
||||||
|
function rc4(key, inp) {
|
||||||
|
let e = [];
|
||||||
|
e[4] = [];
|
||||||
|
e[3] = 0;
|
||||||
|
let i = 0;
|
||||||
|
e[8] = '';
|
||||||
|
for (i = 0; i < 256; i++) {
|
||||||
|
e[4][i] = i;
|
||||||
|
}
|
||||||
|
for (i = 0; i < 256; i++) {
|
||||||
|
e[3] = (e[3] + e[4][i] + key.charCodeAt(i % key.length)) % 256;
|
||||||
|
e[2] = e[4][i];
|
||||||
|
e[4][i] = e[4][e[3]];
|
||||||
|
e[4][e[3]] = e[2];
|
||||||
|
}
|
||||||
|
i = 0;
|
||||||
|
e[3] = 0;
|
||||||
|
let j = 0;
|
||||||
|
for (j = 0; j < inp.length; j++) {
|
||||||
|
i = (i + 1) % 256;
|
||||||
|
e[3] = (e[3] + e[4][i]) % 256;
|
||||||
|
e[2] = e[4][i];
|
||||||
|
e[4][i] = e[4][e[3]];
|
||||||
|
e[4][e[3]] = e[2];
|
||||||
|
e[8] += String.fromCharCode(inp.charCodeAt(j) ^ e[4][(e[4][i] + e[4][e[3]]) % 256]);
|
||||||
|
}
|
||||||
|
return e[8];
|
||||||
|
}
|
||||||
|
|
||||||
|
function enc(inp) {
|
||||||
|
inp = encodeURIComponent(inp);
|
||||||
|
const e = rc4(keys[0], inp);
|
||||||
|
const out = btoa(e).replace(/\//g, '_').replace(/\+/g, '-');
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
function dec(inp) {
|
||||||
|
const i = atob(inp.replace(/_/g, '/').replace(/-/g, '+'));
|
||||||
|
let e = rc4(keys[3], i);
|
||||||
|
e = decodeURIComponent(e);
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function episode(data_id) {
|
||||||
|
let url = `https://vidsrc.to/ajax/embed/episode/${data_id}/sources?token=${encodeURIComponent(enc(data_id))}`;
|
||||||
|
let resp = await fetch(url);
|
||||||
|
resp = await resp.json();
|
||||||
|
|
||||||
|
let filemoon_id = resp.result[1].id;
|
||||||
|
url = `https://vidsrc.to/ajax/embed/source/${filemoon_id}?token=${encodeURIComponent(enc(filemoon_id))}`;
|
||||||
|
resp = await fetch(url);
|
||||||
|
resp = await resp.json();
|
||||||
|
|
||||||
|
let filemoon_url = resp.result.url;
|
||||||
|
let filemoon_url_dec = dec(filemoon_url);
|
||||||
|
const parsedUrl = new URL(filemoon_url_dec);
|
||||||
|
|
||||||
|
const SRC_URL = parsedUrl.origin + parsedUrl.pathname;
|
||||||
|
const queryParams = parsedUrl.search.substring(1);
|
||||||
|
const params = new URLSearchParams(queryParams);
|
||||||
|
const subtitleLink = params.get('sub.info');
|
||||||
|
|
||||||
|
console.log(SRC_URL);
|
||||||
|
console.log(subtitleLink);
|
||||||
|
|
||||||
|
const data = await fetch(SRC_URL);
|
||||||
|
const dataText = await data.text();
|
||||||
|
const match = /eval\(function\(p,a,c,k,e,d\).+\)\)\)/g.exec(dataText);
|
||||||
|
|
||||||
|
if (match) {
|
||||||
|
const packed = match[0];
|
||||||
|
const unpacked = unpack(packed);
|
||||||
|
const hlsMatch = /sources:\[\s*{\s*file:"([^"]*)"/g.exec(unpacked);
|
||||||
|
const subs = await getSubtitles(subtitleLink);
|
||||||
|
const sources = hlsMatch[1];
|
||||||
|
|
||||||
|
if (!sources) {
|
||||||
|
const data = {
|
||||||
|
source: null,
|
||||||
|
subtitles: null
|
||||||
|
};
|
||||||
|
return { filemoon: data };
|
||||||
|
} else {
|
||||||
|
const data = {
|
||||||
|
source: sources,
|
||||||
|
subtitles: subs
|
||||||
|
};
|
||||||
|
return { filemoon: data };
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.error('Packed data not found');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getSubtitles(subtitleLink) {
|
||||||
|
if (subtitleLink) {
|
||||||
|
const subtitlesFetch = await fetch(subtitleLink);
|
||||||
|
const subtitles = await subtitlesFetch.json();
|
||||||
|
|
||||||
|
return subtitles.map(subtitle => ({
|
||||||
|
file: subtitle.file,
|
||||||
|
lang: subtitle.label,
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
console.error('Subtitle link not found in params');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getfmovie(id) {
|
||||||
|
let resp = await fetch(`https://vidsrc.to/embed/movie/${id}`);
|
||||||
|
let respText = await resp.text();
|
||||||
|
const match = /data-id="(.*?)"/g.exec(respText);
|
||||||
|
|
||||||
|
if (match) {
|
||||||
|
let data_id = match[1];
|
||||||
|
return episode(data_id);
|
||||||
|
} else {
|
||||||
|
console.error('Data ID not found');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getfserie(id, s, e) {
|
||||||
|
let resp = await (await fetch(`https://vidsrc.to/embed/tv/${id}/${s}/${e}`)).text();
|
||||||
|
let match = (/data-id="(.*?)"/g).exec(resp)[1];
|
||||||
|
if (match) {
|
||||||
|
let data_id = match[1];
|
||||||
|
return episode(data_id);
|
||||||
|
} else {
|
||||||
|
console.error('Data ID not found');
|
||||||
|
}
|
||||||
|
}
|
||||||
+16
-11
@@ -71,14 +71,19 @@ async function episode(data_id) {
|
|||||||
let url = `https://vidsrc.to/ajax/embed/episode/${data_id}/sources?token=${encodeURIComponent(enc(data_id))}`;
|
let url = `https://vidsrc.to/ajax/embed/episode/${data_id}/sources?token=${encodeURIComponent(enc(data_id))}`;
|
||||||
let resp = await (await fetch(url)).json();
|
let resp = await (await fetch(url)).json();
|
||||||
|
|
||||||
|
console.log(resp);
|
||||||
|
|
||||||
let f2cloud_id = resp['result'][0]['id'];
|
let f2cloud_id = resp['result'][0]['id'];
|
||||||
|
|
||||||
|
console.log(f2cloud_id);
|
||||||
|
|
||||||
url = `https://vidsrc.to/ajax/embed/source/${f2cloud_id}?token=${encodeURIComponent(enc(f2cloud_id))}`;
|
url = `https://vidsrc.to/ajax/embed/source/${f2cloud_id}?token=${encodeURIComponent(enc(f2cloud_id))}`;
|
||||||
resp = await (await fetch(url)).json();
|
resp = await (await fetch(url)).json();
|
||||||
|
|
||||||
let f2cloud_url = resp['result']['url'];
|
let f2cloud_url = resp['result']['url'];
|
||||||
let f2cloud_url_dec = dec(f2cloud_url);
|
let f2cloud_url_dec = dec(f2cloud_url);
|
||||||
|
|
||||||
const subtitles = await getSubtitles(f2cloud_url_dec);
|
const subs = await getSubtitles(f2cloud_url_dec);
|
||||||
|
|
||||||
url = new URL(f2cloud_url_dec);
|
url = new URL(f2cloud_url_dec);
|
||||||
let embed_id = url.pathname.split("/")[2];
|
let embed_id = url.pathname.split("/")[2];
|
||||||
@@ -91,24 +96,24 @@ async function episode(data_id) {
|
|||||||
playlist = JSON.parse(playlist);
|
playlist = JSON.parse(playlist);
|
||||||
}
|
}
|
||||||
|
|
||||||
const source = playlist.sources?.[0]?.file;
|
const sources = playlist.sources?.[0]?.file;
|
||||||
|
|
||||||
if (!source) {
|
if (!sources) {
|
||||||
const data = {
|
const data = {
|
||||||
file: null,
|
source: null,
|
||||||
sub: subtitles
|
subtitles: null
|
||||||
};
|
};
|
||||||
return { data: data };
|
return { vidsrc: data };
|
||||||
} else {
|
} else {
|
||||||
const data = {
|
const data = {
|
||||||
file: source,
|
source: sources,
|
||||||
sub: subtitles
|
subtitles: subs
|
||||||
};
|
};
|
||||||
return { data: data };
|
return { vidsrc: data };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getmovie(id) {
|
export async function getvmovie(id) {
|
||||||
|
|
||||||
let resp = await (await fetch(`https://vidsrc.to/embed/movie/${id}`)).text();
|
let resp = await (await fetch(`https://vidsrc.to/embed/movie/${id}`)).text();
|
||||||
const match = (/data-id="(.*?)"/g).exec(resp);
|
const match = (/data-id="(.*?)"/g).exec(resp);
|
||||||
@@ -116,7 +121,7 @@ export async function getmovie(id) {
|
|||||||
return episode(data_id);
|
return episode(data_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getserie(id, s, e) {
|
export async function getvserie(id, s, e) {
|
||||||
let resp = await (await fetch(`https://vidsrc.to/embed/tv/${id}/${s}/${e}`)).text();
|
let resp = await (await fetch(`https://vidsrc.to/embed/tv/${id}/${s}/${e}`)).text();
|
||||||
let data_id = (/data-id="(.*?)"/g).exec(resp)[1];
|
let data_id = (/data-id="(.*?)"/g).exec(resp)[1];
|
||||||
return episode(data_id);
|
return episode(data_id);
|
||||||
|
|||||||
Reference in New Issue
Block a user