gomostream works!

we don't want to use this ever though.
This commit is contained in:
James Hawkins 2021-07-19 22:26:49 +01:00
parent 8d91170ff5
commit 7ee63c4c7f
4 changed files with 132 additions and 44 deletions

View File

@ -10,21 +10,23 @@ export function VideoElement({ streamUrl, loading, setProgress }) {
const [error, setError] = React.useState(false);
React.useEffect(() => {
setError(false)
if (!videoRef || !videoRef.current || !streamUrl || streamUrl.length === 0 || loading) return;
const hls = new Hls();
if (!Hls.isSupported() && videoRef.current.canPlayType('application/vnd.apple.mpegurl')) {
videoRef.current.src = streamUrl;
return;
} else if (!Hls.isSupported()) {
setError(true)
return;
if (!streamUrl.endsWith('.mp4')) {
setError(false)
if (!videoRef || !videoRef.current || !streamUrl || streamUrl.length === 0 || loading) return;
const hls = new Hls();
if (!Hls.isSupported() && videoRef.current.canPlayType('application/vnd.apple.mpegurl')) {
videoRef.current.src = streamUrl;
return;
} else if (!Hls.isSupported()) {
setError(true)
return;
}
hls.attachMedia(videoRef.current);
hls.loadSource(streamUrl);
}
hls.attachMedia(videoRef.current);
hls.loadSource(streamUrl);
}, [videoRef, streamUrl, loading])
if (error)
@ -36,7 +38,13 @@ export function VideoElement({ streamUrl, loading, setProgress }) {
if (!streamUrl || streamUrl.length === 0)
return <VideoPlaceholder>No video selected</VideoPlaceholder>
return (
<video className="videoElement" ref={videoRef} controls autoPlay onProgress={setProgress} />
)
if (!streamUrl.endsWith('.mp4')) {
return (
<video className="videoElement" ref={videoRef} controls autoPlay onProgress={setProgress} />
)
} else {
return (
<video className="videoElement" ref={videoRef} controls autoPlay onProgress={setProgress}><source src={streamUrl} type="video/mp4" /></video>
)
}
}

View File

@ -1,3 +1,5 @@
import { unpacker } from './unpacker';
const CORS_URL = 'https://hidden-inlet-27205.herokuapp.com/';
const BASE_URL = `${CORS_URL}https://gomo.to`;
const MOVIE_URL = `${BASE_URL}/movie`
@ -9,37 +11,68 @@ async function findContent(searchTerm, type) {
const term = searchTerm.toLowerCase()
const imdbRes = await fetch(`${CORS_URL}https://v2.sg.media-imdb.com/suggestion/${term.slice(0, 1)}/${term}.json`).then(d => d.json())
const movieId = imdbRes.d[0]?.id
if(!movieId) {
return;
const results = [];
imdbRes.d.forEach((e) => {
if (!e.id.startsWith('tt')) return;
results.push({
title: e.l,
slug: e.id,
type: 'movie',
year: e.y
})
});
if (results.length > 1) {
return { options: results };
} else {
return { options: [results[0]] }
}
console.log(imdbRes, movieId)
// const movieId = imdbRes.d[0]?.id
// if (!movieId) return;
// Get stream to go with IMDB ID
const site1 = await fetch(`${MOVIE_URL}/${movieId}`).then((d) => d.text());
const tc = site1.match(/var tc = '(.+)';/)?.[1]
const _token = site1.match(/"_token": "(.+)",/)?.[1]
const fd = new FormData()
fd.append('tokenCode', tc)
fd.append('_token', _token)
const src = await fetch(DECODING_URL, {
method: "POST",
body: fd,
headers: {
'x-token': tc.slice(5, 13).split("").reverse().join("") + "13574199"
}
}).then((d) => d.json());
console.log(src);
const embedUrl = src.find(url => url.includes('gomo.to'));
const site2 = await fetch(`${CORS_URL}${embedUrl}`).then((d) => d.text());
} catch (err) {
console.log(err);
throw new Error(err)
}
}
export { findContent }
async function getStreamUrl(slug, type, season, episode) {
if (type !== 'movie') return;
// Get stream to go with IMDB ID
const site1 = await fetch(`${MOVIE_URL}/${slug}`).then((d) => d.text());
const tc = site1.match(/var tc = '(.+)';/)?.[1]
const _token = site1.match(/"_token": "(.+)",/)?.[1]
const fd = new FormData()
fd.append('tokenCode', tc)
fd.append('_token', _token)
const src = await fetch(DECODING_URL, {
method: "POST",
body: fd,
headers: {
'x-token': tc.slice(5, 13).split("").reverse().join("") + "13574199"
}
}).then((d) => d.json());
const embedUrl = src.find(url => url.includes('gomo.to'));
const site2 = await fetch(`${CORS_URL}${embedUrl}`).then((d) => d.text());
const parser = new DOMParser();
const site2Dom = parser.parseFromString(site2, "text/html");
const script = site2Dom.querySelectorAll("script")[8].innerHTML;
let unpacked = unpacker.unpack(script).split('');
unpacked.splice(0, 43);
let index = unpacked.findIndex((e) => e === '"');
const url = unpacked.slice(0, index).join('');
return { url }
}
export { findContent, getStreamUrl }

46
src/lib/unpacker.js Normal file
View File

@ -0,0 +1,46 @@
/* port of https://github.com/beautify-web/js-beautify/blob/master/python/jsbeautifier/unpackers/packer.py (MIT) */
const unpacker = {
unpack: function (str) {
var params = unpacker.filterargs(str);
var payload = params[0], symtab = params[1], radix = params[2], count = params[3];
if (count !== symtab.length) {
throw new Error("Malformed p.a.c.k.e.r. symtab. (" + count + " != " + symtab.length + ")");
}
var unbase = unpacker.unbaser(radix);
var lookup = (word) => symtab[unbase(word)] || word;
var source = payload.replace(/\b\w+\b/g, lookup);
return source;
},
filterargs: function(str) {
/* [\s\S] insteadof . because javascript has no dotall modifier */
var juicers = [
/}\('([\s\S]*)', *(\d+), *(\d+), *'([\s\S]*)'\.split\('\|'\), *(\d+), *([\s\S]*)\)\)/,
/}\('([\s\S]*)', *(\d+), *(\d+), *'([\s\S]*)'\.split\('\|'\)/
];
for (var c = 0; c < juicers.length; ++c) {
var m, juicer = juicers[c];
// eslint-disable-next-line no-cond-assign
if (m = juicer.exec(str)) {
return [m[1], m[4].split('|'), parseInt(m[2]), parseInt(m[3])];
}
}
throw new Error("Could not make sense of p.a.c.k.e.r data (unexpected code structure)");
},
alphabet: {
62: "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
95: '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~'
},
unbaser: function(base)
{
if (2 <= base <= 36) return (str) => parseInt(str, base);
var dictionary = {};
var alphabet = unpacker.alphabet[base];
if (!alphabet) throw new Error("Unsupported encoding");
for (var c = 0; c < alphabet.length; ++alphabet) {
dictionary[alphabet[c]] = c;
}
return (str) => str.split("").reverse().reduce((cipher, ind) => Math.pow(base, ind) * dictionary[cipher]);
}
};
export { unpacker };

View File

@ -6,7 +6,8 @@ import { ErrorBanner } from '../components/ErrorBanner'
import { MovieRow } from '../components/MovieRow'
import { Arrow } from '../components/Arrow'
import { Progress } from '../components/Progress'
import { findContent, getStreamUrl, getEpisodes } from '../lib/lookMovie'
import { /* findContent, getStreamUrl,*/ getEpisodes } from '../lib/lookMovie'
import { findContent, getStreamUrl } from '../lib/gomostream';
import { useMovie } from '../hooks/useMovie';
import { TypeSelector } from '../components/TypeSelector'