mirror of
https://github.com/sussy-code/smov.git
synced 2024-12-30 16:17:41 +01:00
169 lines
5.2 KiB
JavaScript
169 lines
5.2 KiB
JavaScript
|
const cfg = {
|
||
|
base: "https://hidden-inlet-27205.herokuapp.com/https://lookmovie.io"
|
||
|
}
|
||
|
|
||
|
async function getVideoUrl(config) {
|
||
|
const accessToken = await getAccessToken(config);
|
||
|
const now = Math.floor(Date.now() / 1e3);
|
||
|
|
||
|
let url = null;
|
||
|
|
||
|
if (config.type === "tv") {
|
||
|
url = `${cfg.base}/manifests/shows/json/${accessToken}/${now}/${config.episodeId}/master.m3u8`;
|
||
|
} else if (config.type === "movie") {
|
||
|
url = `${cfg.base}/manifests/movies/json/${config.movieId}/${now}/${accessToken}/master.m3u8`;
|
||
|
}
|
||
|
|
||
|
if (url) {
|
||
|
const videoOpts = await fetch(url).then((d) => d.json());
|
||
|
|
||
|
// Find video URL and return it (with a check for a full url if needed)
|
||
|
const opts = ["1080p", "1080", "720p", "720", "480p", "480", "auto"]
|
||
|
|
||
|
let videoUrl = "";
|
||
|
for (let res of opts) {
|
||
|
if (videoOpts[res] && !videoOpts[res].includes('dummy') && !videoOpts[res].includes('earth-1984') && !videoUrl) {
|
||
|
videoUrl = videoOpts[res]
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return videoUrl.startsWith("/") ? `${cfg.base}${videoUrl}` : videoUrl;
|
||
|
}
|
||
|
|
||
|
return "Invalid type.";
|
||
|
}
|
||
|
|
||
|
async function getAccessToken(config) {
|
||
|
let url = "";
|
||
|
|
||
|
if (config.type === "tv") {
|
||
|
// 'mbQFYTR499c9vfDmAwOFrg' // Retrieved from: https://lookmovie.io/api/v1/security/show-access?slug=1839578-person-of-interest-2011&token=&step=2
|
||
|
url = `${cfg.base}/api/v1/security/show-access?slug=${config.slug}&token=&step=2`;
|
||
|
} else if (config.type === "movie") {
|
||
|
// https://lookmovie.io/api/v1/security/movie-access?id_movie=14358&token=1&sk=&step=1
|
||
|
url = `${cfg.base}/api/v1/security/movie-access?id_movie=${config.movieId}&token=1&sk=&step=1`;
|
||
|
}
|
||
|
|
||
|
const data = await fetch(url).then((d) => d.json());
|
||
|
|
||
|
const token = data?.data?.accessToken;
|
||
|
if (token) return token;
|
||
|
|
||
|
return "Invalid type provided in config";
|
||
|
}
|
||
|
|
||
|
async function findMovie() {
|
||
|
const searchTerm = document.getElementById('search').value;
|
||
|
|
||
|
const movieSearchRes = await fetch(
|
||
|
`https://hidden-inlet-27205.herokuapp.com/https://lookmovie.io/api/v1/movies/search/?q=${encodeURIComponent(
|
||
|
searchTerm
|
||
|
)}`
|
||
|
).then((d) => d.json());
|
||
|
const showSearchRes = await fetch(
|
||
|
`https://hidden-inlet-27205.herokuapp.com/https://lookmovie.io/api/v1/shows/search/?q=${encodeURIComponent(
|
||
|
searchTerm
|
||
|
)}`
|
||
|
).then((d) => d.json());
|
||
|
|
||
|
let results = [
|
||
|
...movieSearchRes.result.map((v) => ({ ...v, type: "movie" })),
|
||
|
...showSearchRes.result.map((v) => ({ ...v, type: "show" })),
|
||
|
];
|
||
|
|
||
|
const fuse = new Fuse(results, {
|
||
|
threshold: 0.3,
|
||
|
distance: 200,
|
||
|
keys: ["title"],
|
||
|
});
|
||
|
const matchedResults = fuse
|
||
|
.search(searchTerm.toString())
|
||
|
.map((result) => result.item);
|
||
|
|
||
|
let toShow;
|
||
|
if (matchedResults.length > 1) {
|
||
|
const response = window.prompt(`Pick a movie from:\n${matchedResults.map((i, v) => `${v}) ${i.title}`).join('\n')}`, 'Enter number');
|
||
|
toShow = matchedResults[response];
|
||
|
} else {
|
||
|
toShow = matchedResults[0];
|
||
|
}
|
||
|
|
||
|
if (!toShow) {
|
||
|
document.getElementById('error').innerHTML = 'Unable to find that, sorry!'
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
console.log(`Scraping the ${toShow.type} "${toShow.title}"`);
|
||
|
|
||
|
// ! Now we get the ID and stuff we need
|
||
|
const url = `https://hidden-inlet-27205.herokuapp.com/https://lookmovie.io/${toShow.type}s/view/${toShow.slug}`;
|
||
|
const pageReq = await fetch(url).then((d) => d.text());
|
||
|
|
||
|
// Extract and parse JSON
|
||
|
let scriptJson =
|
||
|
"{" +
|
||
|
pageReq
|
||
|
.slice(pageReq.indexOf(`${toShow.type}_storage`))
|
||
|
.split("};")[0]
|
||
|
.split("= {")[1]
|
||
|
.trim() +
|
||
|
"}";
|
||
|
|
||
|
const data = JSON5.parse(scriptJson);
|
||
|
|
||
|
// Find the relevant id
|
||
|
let id = null;
|
||
|
let relevantEpisode;
|
||
|
if (toShow.type === "movie") {
|
||
|
id = data.id_movie;
|
||
|
} else if (toShow.type === "show") {
|
||
|
const episodeObj = data.seasons.find((v) => {
|
||
|
return v.season == season && v.episode == episode;
|
||
|
});
|
||
|
if (episodeObj) {
|
||
|
console.log(
|
||
|
`Finding streams for ${toShow.title} ${season}x${episode}: ${episodeObj.title}`
|
||
|
);
|
||
|
id = episodeObj.id_episode;
|
||
|
relevantEpisode = episodeObj;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Check ID
|
||
|
if (id === null) {
|
||
|
console.error(`Not found: S${season} E${episode}`);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Generate object to send over to scraper
|
||
|
let reqObj = null;
|
||
|
if (toShow.type === "show") {
|
||
|
reqObj = {
|
||
|
slug: toShow.slug,
|
||
|
episodeId: id,
|
||
|
type: "tv",
|
||
|
};
|
||
|
} else if (toShow.type === "movie") {
|
||
|
reqObj = {
|
||
|
slug: toShow.slug,
|
||
|
movieId: id,
|
||
|
type: "movie",
|
||
|
};
|
||
|
}
|
||
|
|
||
|
if (!reqObj) {
|
||
|
document.getElementById('error').innerHTML = 'Invalid type!'
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
const videoUrl = await getVideoUrl(reqObj);
|
||
|
|
||
|
var video = document.getElementById('video');
|
||
|
var videoSrc = `https://hidden-inlet-27205.herokuapp.com/${videoUrl}`;
|
||
|
if (Hls.isSupported()) {
|
||
|
var video = document.getElementById('video');
|
||
|
var hls = new Hls();
|
||
|
hls.attachMedia(video);
|
||
|
hls.loadSource(videoSrc);
|
||
|
}
|
||
|
}
|