Update vidfast/vidfast.js

This commit is contained in:
aka paul 2025-10-24 20:08:38 +00:00
parent 44a16bf8ec
commit 5b9a21310c

View file

@ -16,7 +16,6 @@ async function searchResults(keyword) {
const shouldFilter = !matchesKeyword(keyword, skipTitleFilter);
// --- TMDB Section ---
const encodedKeyword = encodeURIComponent(keyword);
let baseUrl = null;
@ -184,6 +183,8 @@ async function extractEpisodes(url) {
}
async function extractStreamUrl(ID) {
const startTime = Date.now();
if (ID.includes('movie')) {
const tmdbID = ID.replace('/movie/', '');
const headersOne = {
@ -202,14 +203,26 @@ async function extractStreamUrl(ID) {
const streams = [];
if (streamResponse) {
streams.push("Default", streamResponse.url);
};
if (streamResponse && streamResponse.defaultUrl) {
streams.push("1080p", streamResponse.defaultUrl);
}
if (streamResponse && streamResponse.vFastUrl) {
const fourKResult = await ilovearmpits(streamResponse.vFastUrl);
if (fourKResult.available && fourKResult.url) {
streams.push("4K", fourKResult.url);
}
}
const final = {
streams,
subtitles: streamResponse.subtitles || "None"
};
const endTime = Date.now();
const elapsed = ((endTime - startTime) / 1000).toFixed(2);
console.log(`Stream fetched in ${elapsed}s`);
console.log(JSON.stringify(final));
return JSON.stringify(final);
} else if (ID.includes('tv')) {
@ -231,18 +244,29 @@ async function extractStreamUrl(ID) {
const imdbID = tmdbData.external_ids.imdb_id;
const streamResponse = await ilovefeet(imdbID, true, seasonNumber, episodeNumber, 'm3u8');
const stream = streamResponse.url;
const streams = [];
if (stream) {
streams.push("Default", stream);
};
if (streamResponse && streamResponse.defaultUrl) {
streams.push("1080p", streamResponse.defaultUrl);
}
if (streamResponse && streamResponse.vFastUrl) {
const fourKResult = await ilovearmpits(streamResponse.vFastUrl);
if (fourKResult.available && fourKResult.url) {
streams.push("4K", fourKResult.url);
}
}
const final = {
streams,
subtitles: streamResponse.subtitles || "None"
};
const endTime = Date.now();
const elapsed = ((endTime - startTime) / 1000).toFixed(2);
console.log(`Stream fetched in ${elapsed}s`);
console.log(JSON.stringify(final));
return JSON.stringify(final);
}
@ -267,6 +291,76 @@ async function soraFetch(url, options = { headers: {}, method: 'GET', body: null
}
}
async function ilovearmpits(m3u8Url) {
try {
const headers = {
"Accept": "*/*",
"User-Agent": "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Mobile Safari/537.36",
"Referer": "https://vidfast.pro/"
};
const response = await fetchv2(m3u8Url, headers);
const playlistContent = await response.text();
const has4K = playlistContent.includes('RESOLUTION=3840x2160');
if (!has4K) {
console.log(`4K Check for ${m3u8Url}: NO`);
return { available: false, url: null };
}
const lines = playlistContent.split('\n');
let fourKPath = null;
let fourKCount = 0;
for (let i = 0; i < lines.length; i++) {
if (lines[i].includes('RESOLUTION=3840x2160')) {
fourKCount++;
if (fourKCount === 2 && i + 1 < lines.length) {
fourKPath = lines[i + 1].trim();
break;
}
}
}
if (!fourKPath && fourKCount === 1) {
for (let i = 0; i < lines.length; i++) {
if (lines[i].includes('RESOLUTION=3840x2160')) {
if (i + 1 < lines.length) {
fourKPath = lines[i + 1].trim();
break;
}
}
}
}
if (!fourKPath) {
console.log('4K resolution found but could not extract path');
return { available: false, url: null };
}
let baseUrl = '';
if (m3u8Url.startsWith('https://')) {
const afterProtocol = m3u8Url.substring(8);
const hostEnd = afterProtocol.indexOf('/');
const host = hostEnd !== -1 ? afterProtocol.substring(0, hostEnd) : afterProtocol;
baseUrl = 'https://' + host;
} else if (m3u8Url.startsWith('http://')) {
const afterProtocol = m3u8Url.substring(7);
const hostEnd = afterProtocol.indexOf('/');
const host = hostEnd !== -1 ? afterProtocol.substring(0, hostEnd) : afterProtocol;
baseUrl = 'http://' + host;
}
const full4KUrl = fourKPath.startsWith('http') ? fourKPath : `${baseUrl}${fourKPath}`;
return { available: true, url: full4KUrl };
} catch (error) {
console.log('Error checking 4K availability: ' + error);
return { available: false, url: null };
}
}
async function ilovefeet(imdbId, isSeries = false, season = null, episode = null, preferredFormat = null) {
const configUrl = 'https://raw.githubusercontent.com/yogesh-hacker/MediaVanced/refs/heads/main/sites/vidfast.py';
const configResponse = await fetchv2(configUrl);
@ -421,11 +515,24 @@ async function ilovefeet(imdbId, isSeries = false, season = null, episode = null
};
let selectedServer = null;
let vFastServer = null;
try {
if (preferredFormat === 'm3u8') {
const serverPromises = serverList.map((serverObj, index) => testServer(serverObj, index));
const vFastServerObj = serverList.find(server => server.name === 'vFast');
if (vFastServerObj) {
const vFastIndex = serverList.indexOf(vFastServerObj);
try {
vFastServer = await testServer(vFastServerObj, vFastIndex);
} catch (error) {
console.log('vFast server failed: ' + error.message);
}
} else {
console.log('vFast server not found in server list');
}
const raceForSubtitles = new Promise((resolve, reject) => {
let completedCount = 0;
let firstWorkingServer = null;
@ -508,17 +615,19 @@ async function ilovefeet(imdbId, isSeries = false, season = null, episode = null
}
return {
url: selectedServer.data.url,
originalUrl: selectedServer.data.url,
defaultUrl: selectedServer.data.url,
vFastUrl: vFastServer ? vFastServer.data.url : null,
referer: "https://vidfast.pro/",
format: selectedServer.format,
subtitles: englishSubtitles,
fullData: selectedServer.data,
vFastData: vFastServer ? vFastServer.data : null,
serverStats: {
total: serverList.length,
working: 1,
failed: serverList.length - 1,
selectedServerIndex: selectedServer.index
working: vFastServer ? 2 : 1,
failed: serverList.length - (vFastServer ? 2 : 1),
selectedServerIndex: selectedServer.index,
vFastServerIndex: vFastServer ? vFastServer.index : null
}
};
}