|
|
@ -1,18 +1,12 @@ |
|
|
|
const cfg = { |
|
|
|
function getCorsUrl(url) { |
|
|
|
base: "https://hidden-inlet-27205.herokuapp.com/https://lookmovie.io" |
|
|
|
return `https://hidden-inlet-27205.herokuapp.com/${url}`; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
async function getVideoUrl(config) { |
|
|
|
async function getVideoUrl(config) { |
|
|
|
const accessToken = await getAccessToken(config); |
|
|
|
const accessToken = await getAccessToken(config); |
|
|
|
const now = Math.floor(Date.now() / 1e3); |
|
|
|
const now = Math.floor(Date.now() / 1e3); |
|
|
|
|
|
|
|
|
|
|
|
let url = null; |
|
|
|
let url = getCorsUrl(`https://lookmovie.io/manifests/movies/json/${config.movieId}/${now}/${accessToken}/master.m3u8`); |
|
|
|
|
|
|
|
|
|
|
|
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) { |
|
|
|
if (url) { |
|
|
|
const videoOpts = await fetch(url).then((d) => d.json()); |
|
|
|
const videoOpts = await fetch(url).then((d) => d.json()); |
|
|
@ -27,22 +21,14 @@ async function getVideoUrl(config) { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return videoUrl.startsWith("/") ? `${cfg.base}${videoUrl}` : videoUrl; |
|
|
|
return videoUrl.startsWith("/") ? getCorsUrl(`https://lookmovie.io/${videoUrl}`) : getCorsUrl(videoUrl); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return "Invalid type."; |
|
|
|
return "Invalid type."; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
async function getAccessToken(config) { |
|
|
|
async function getAccessToken(config) { |
|
|
|
let url = ""; |
|
|
|
let url = getCorsUrl(`https://lookmovie.io/api/v1/security/movie-access?id_movie=${config.movieId}&token=1&sk=&step=1`); |
|
|
|
|
|
|
|
|
|
|
|
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 data = await fetch(url).then((d) => d.json()); |
|
|
|
|
|
|
|
|
|
|
@ -55,27 +41,13 @@ async function getAccessToken(config) { |
|
|
|
async function findMovie() { |
|
|
|
async function findMovie() { |
|
|
|
const searchTerm = document.getElementById('search').value; |
|
|
|
const searchTerm = document.getElementById('search').value; |
|
|
|
|
|
|
|
|
|
|
|
const movieSearchRes = await fetch( |
|
|
|
sendMessage('info', `Searching for "${searchTerm}"`) |
|
|
|
`https://hidden-inlet-27205.herokuapp.com/https://lookmovie.io/api/v1/movies/search/?q=${encodeURIComponent( |
|
|
|
|
|
|
|
searchTerm |
|
|
|
const searchUrl = getCorsUrl(`https://lookmovie.io/api/v1/movies/search/?q=${encodeURIComponent(searchTerm)}`); |
|
|
|
)}` |
|
|
|
const searchRes = await fetch(searchUrl).then((d) => d.json()); |
|
|
|
).then((d) => d.json()); |
|
|
|
let results = [ ...searchRes.result.map((v) => ({ ...v, type: "movie" })) ]; |
|
|
|
const showSearchRes = await fetch( |
|
|
|
|
|
|
|
`https://hidden-inlet-27205.herokuapp.com/https://lookmovie.io/api/v1/shows/search/?q=${encodeURIComponent( |
|
|
|
const fuse = new Fuse(results, { threshold: 0.3, distance: 200, keys: ["title"] }); |
|
|
|
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 |
|
|
|
const matchedResults = fuse |
|
|
|
.search(searchTerm.toString()) |
|
|
|
.search(searchTerm.toString()) |
|
|
|
.map((result) => result.item); |
|
|
|
.map((result) => result.item); |
|
|
@ -89,81 +61,46 @@ async function findMovie() { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (!toShow) { |
|
|
|
if (!toShow) { |
|
|
|
document.getElementById('error').innerHTML = 'Unable to find that, sorry!' |
|
|
|
sendMessage('error', 'Unable to find that, sorry!') |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
console.log(`Scraping the ${toShow.type} "${toShow.title}"`); |
|
|
|
sendMessage('info', `Scraping the ${toShow.type} "${toShow.title}"`) |
|
|
|
|
|
|
|
|
|
|
|
// ! Now we get the ID and stuff we need
|
|
|
|
const url = getCorsUrl(`https://lookmovie.io/${toShow.type}s/view/${toShow.slug}`); |
|
|
|
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()); |
|
|
|
const pageReq = await fetch(url).then((d) => d.text()); |
|
|
|
|
|
|
|
|
|
|
|
// Extract and parse JSON
|
|
|
|
const data = JSON5.parse("{" + |
|
|
|
let scriptJson = |
|
|
|
|
|
|
|
"{" + |
|
|
|
|
|
|
|
pageReq |
|
|
|
pageReq |
|
|
|
.slice(pageReq.indexOf(`${toShow.type}_storage`)) |
|
|
|
.slice(pageReq.indexOf(`${toShow.type}_storage`)) |
|
|
|
.split("};")[0] |
|
|
|
.split("};")[0] |
|
|
|
.split("= {")[1] |
|
|
|
.split("= {")[1] |
|
|
|
.trim() + |
|
|
|
.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
|
|
|
|
const videoUrl = await getVideoUrl({ |
|
|
|
let reqObj = null; |
|
|
|
slug: toShow.slug, |
|
|
|
if (toShow.type === "show") { |
|
|
|
movieId: data.id_movie, |
|
|
|
reqObj = { |
|
|
|
type: "movie", |
|
|
|
slug: toShow.slug, |
|
|
|
}); |
|
|
|
episodeId: id, |
|
|
|
|
|
|
|
type: "tv", |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
} else if (toShow.type === "movie") { |
|
|
|
|
|
|
|
reqObj = { |
|
|
|
|
|
|
|
slug: toShow.slug, |
|
|
|
|
|
|
|
movieId: id, |
|
|
|
|
|
|
|
type: "movie", |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!reqObj) { |
|
|
|
sendMessage('info', `Streaming "${toShow.title}"`) |
|
|
|
document.getElementById('error').innerHTML = 'Invalid type!' |
|
|
|
streamVideo(videoUrl) |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const videoUrl = await getVideoUrl(reqObj); |
|
|
|
function sendMessage(type, message) { |
|
|
|
|
|
|
|
if (!['info', 'error'].includes(type)) return; |
|
|
|
|
|
|
|
document.getElementById(type).innerHTML += `${message}<br>`; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function streamVideo(url) { |
|
|
|
var video = document.getElementById('video'); |
|
|
|
var video = document.getElementById('video'); |
|
|
|
var videoSrc = `https://hidden-inlet-27205.herokuapp.com/${videoUrl}`; |
|
|
|
|
|
|
|
if (Hls.isSupported()) { |
|
|
|
if (Hls.isSupported()) { |
|
|
|
var video = document.getElementById('video'); |
|
|
|
var video = document.getElementById('video'); |
|
|
|
var hls = new Hls(); |
|
|
|
var hls = new Hls(); |
|
|
|
hls.attachMedia(video); |
|
|
|
hls.attachMedia(video); |
|
|
|
hls.loadSource(videoSrc); |
|
|
|
hls.loadSource(url); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |