mirror of
https://github.com/Inside4ndroid/TMDB-Embed-API.git
synced 2026-10-22 17:45:11 +00:00
93 lines
3.2 KiB
JavaScript
93 lines
3.2 KiB
JavaScript
const axios = require('axios');
|
|
const { getTmdbApiKey } = require('../utils/tmdbKey');
|
|
|
|
const NOTORRENT_API = 'https://addon-osvh.onrender.com';
|
|
|
|
function cleanText(str) {
|
|
if (!str) return '';
|
|
return str.replace(/[\u{1F300}-\u{1F9FF}]|[\u{2600}-\u{26FF}]/gu, '').trim();
|
|
}
|
|
|
|
function extractQuality(titleText) {
|
|
const raw = titleText || '';
|
|
const match = raw.match(/(\d{3,4}p)/);
|
|
if (match) return match[0];
|
|
if (raw.toUpperCase().includes('FREE')) return 'Auto';
|
|
return 'Unknown';
|
|
}
|
|
|
|
async function getNotorrentStreams(tmdbId, mediaType = 'movie', seasonNum = null, episodeNum = null) {
|
|
console.log(`[NoTorrent] Searching for ${mediaType} ${tmdbId}`);
|
|
|
|
const tmdbKey = getTmdbApiKey();
|
|
if (!tmdbKey) {
|
|
console.error('[NoTorrent] No TMDB API key configured.');
|
|
return [];
|
|
}
|
|
|
|
// Step 1: TMDB → IMDB ID
|
|
let imdbId;
|
|
try {
|
|
const type = mediaType === 'tv' ? 'tv' : 'movie';
|
|
const { data } = await axios.get(
|
|
`https://api.themoviedb.org/3/${type}/${tmdbId}?api_key=${tmdbKey}&append_to_response=external_ids`,
|
|
{ timeout: 8000 }
|
|
);
|
|
imdbId = (data.external_ids && data.external_ids.imdb_id) || null;
|
|
} catch (err) {
|
|
console.error(`[NoTorrent] TMDB lookup failed: ${err.message}`);
|
|
return [];
|
|
}
|
|
|
|
if (!imdbId) {
|
|
console.warn('[NoTorrent] Failed to map IMDB ID from TMDB.');
|
|
return [];
|
|
}
|
|
|
|
// Step 2: Fetch streams from NoTorrent Stremio addon API
|
|
const apiUrl = (mediaType === 'tv' && seasonNum != null)
|
|
? `${NOTORRENT_API}/stream/series/${imdbId}:${seasonNum}:${episodeNum}.json`
|
|
: `${NOTORRENT_API}/stream/movie/${imdbId}.json`;
|
|
|
|
try {
|
|
const { data } = await axios.get(apiUrl, { timeout: 20000 });
|
|
const rawList = data.streams || [];
|
|
const streams = [];
|
|
|
|
for (const item of rawList) {
|
|
if (item.externalUrl || !item.url) continue;
|
|
if (item.url.includes('github.com') || item.url.includes('googleusercontent')) continue;
|
|
|
|
const cleanTitleStr = cleanText(item.title || '');
|
|
const quality = extractQuality(cleanTitleStr);
|
|
|
|
let language = 'Default';
|
|
const langMatch = cleanTitleStr.match(/\(([^)]+)\)/);
|
|
if (langMatch) {
|
|
language = langMatch[1].charAt(0).toUpperCase() + langMatch[1].slice(1).toLowerCase();
|
|
}
|
|
|
|
const proxyHeaders = (item.behaviorHints?.proxyHeaders?.request) || {};
|
|
const headers = { ...(item.behaviorHints?.headers || {}), ...proxyHeaders };
|
|
|
|
const nameParts = ['NoTorrent', language !== 'Default' ? language : ''].filter(p => p.trim() !== '');
|
|
streams.push({
|
|
name: nameParts.join(' \u2022 '),
|
|
title: quality,
|
|
url: item.url,
|
|
quality,
|
|
provider: 'NoTorrent',
|
|
headers: Object.keys(headers).length > 0 ? headers : undefined
|
|
});
|
|
}
|
|
|
|
console.log(`[NoTorrent] Total results found: ${streams.length}`);
|
|
return streams;
|
|
} catch (err) {
|
|
console.error(`[NoTorrent] Fetch failed: ${err.message}`);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
module.exports = { getNotorrentStreams };
|