diff --git a/assets/css/style.css b/assets/css/style.css
index e69de29b..7801a75c 100644
--- a/assets/css/style.css
+++ b/assets/css/style.css
@@ -0,0 +1,59 @@
+@font-face {
+ font-family: 'JetBrainsMono';
+ src: url(../fonts/JetBrainsMono-Regular.woff2);
+ font-weight: 400;
+ font-style: normal;
+}
+
+html, body {
+ height: 1vh;
+}
+
+body {
+ margin: 0;
+ color: #95979F;
+ background-color: #0c0e14;
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='40' viewBox='0 0 40 40'%3E%3Cg fill-rule='evenodd'%3E%3Cg fill='%23586ca8' fill-opacity='0.12'%3E%3Cpath d='M0 38.59l2.83-2.83 1.41 1.41L1.41 40H0v-1.41zM0 1.4l2.83 2.83 1.41-1.41L1.41 0H0v1.41zM38.59 40l-2.83-2.83 1.41-1.41L40 38.59V40h-1.41zM40 1.41l-2.83 2.83-1.41-1.41L38.59 0H40v1.41zM20 18.6l2.83-2.83 1.41 1.41L21.41 20l2.83 2.83-1.41 1.41L20 21.41l-2.83 2.83-1.41-1.41L18.59 20l-2.83-2.83 1.41-1.41L20 18.59z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E");
+ font-family: 'JetBrainsMono';
+}
+
+.messages {
+ background-color: #2D313D;
+ border-radius: 10px;
+ width: 80%;
+ padding-left: 10px;
+}
+
+.error {
+ color: #f3565d;
+}
+
+.info {
+ color: #2e5bbd;
+}
+
+.content {
+ padding: 1rem;
+ border-radius: 10px;
+ background-color: #2D313D;
+ width: 80%;
+}
+
+.video {
+ width: 100%;
+}
+
+form {
+ background-color: #2D313D;
+ padding: 5px;
+ width: 300px;
+ text-align: center;
+}
+
+input[type="submit"] {
+ width: 20%;
+}
+
+input[type="text"] {
+ width: 70%;
+}
\ No newline at end of file
diff --git a/assets/fonts/JetBrainsMono-Regular.woff2 b/assets/fonts/JetBrainsMono-Regular.woff2
new file mode 100644
index 00000000..80c62dd1
Binary files /dev/null and b/assets/fonts/JetBrainsMono-Regular.woff2 differ
diff --git a/assets/js/index.js b/assets/js/index.js
index 8a1e751c..b6431901 100644
--- a/assets/js/index.js
+++ b/assets/js/index.js
@@ -1,18 +1,12 @@
-const cfg = {
- base: "https://hidden-inlet-27205.herokuapp.com/https://lookmovie.io"
+function getCorsUrl(url) {
+ return `https://hidden-inlet-27205.herokuapp.com/${url}`;
}
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`;
- }
+ let url = getCorsUrl(`https://lookmovie.io/manifests/movies/json/${config.movieId}/${now}/${accessToken}/master.m3u8`);
if (url) {
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.";
}
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`;
- }
+ let url = getCorsUrl(`https://lookmovie.io/api/v1/security/movie-access?id_movie=${config.movieId}&token=1&sk=&step=1`);
const data = await fetch(url).then((d) => d.json());
@@ -55,27 +41,13 @@ async function getAccessToken(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());
+ sendMessage('info', `Searching for "${searchTerm}"`)
- let results = [
- ...movieSearchRes.result.map((v) => ({ ...v, type: "movie" })),
- ...showSearchRes.result.map((v) => ({ ...v, type: "show" })),
- ];
+ const searchUrl = getCorsUrl(`https://lookmovie.io/api/v1/movies/search/?q=${encodeURIComponent(searchTerm)}`);
+ const searchRes = await fetch(searchUrl).then((d) => d.json());
+ let results = [ ...searchRes.result.map((v) => ({ ...v, type: "movie" })) ];
- const fuse = new Fuse(results, {
- threshold: 0.3,
- distance: 200,
- keys: ["title"],
- });
+ const fuse = new Fuse(results, { threshold: 0.3, distance: 200, keys: ["title"] });
const matchedResults = fuse
.search(searchTerm.toString())
.map((result) => result.item);
@@ -89,81 +61,46 @@ async function findMovie() {
}
if (!toShow) {
- document.getElementById('error').innerHTML = 'Unable to find that, sorry!'
+ sendMessage('error', 'Unable to find that, sorry!')
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 = `https://hidden-inlet-27205.herokuapp.com/https://lookmovie.io/${toShow.type}s/view/${toShow.slug}`;
+ const url = getCorsUrl(`https://lookmovie.io/${toShow.type}s/view/${toShow.slug}`);
const pageReq = await fetch(url).then((d) => d.text());
- // Extract and parse JSON
- let scriptJson =
- "{" +
+ const data = JSON5.parse("{" +
pageReq
.slice(pageReq.indexOf(`${toShow.type}_storage`))
.split("};")[0]
.split("= {")[1]
.trim() +
- "}";
+ "}"
+ );
- const data = JSON5.parse(scriptJson);
+ const videoUrl = await getVideoUrl({
+ slug: toShow.slug,
+ movieId: data.id_movie,
+ type: "movie",
+ });
- // 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;
- }
- }
+ sendMessage('info', `Streaming "${toShow.title}"`)
+ streamVideo(videoUrl)
+}
- // 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);
+function sendMessage(type, message) {
+ if (!['info', 'error'].includes(type)) return;
+ document.getElementById(type).innerHTML += `${message}
`;
+}
+function streamVideo(url) {
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);
+ hls.loadSource(url);
}
}
\ No newline at end of file
diff --git a/index.html b/index.html
index a1d43324..9ec86391 100644
--- a/index.html
+++ b/index.html
@@ -5,19 +5,30 @@