keep only essentials, add height and title parsing and tests
This commit is contained in:
parent
8b3e2765c6
commit
63b0f34525
7 changed files with 124 additions and 82 deletions
16
src/extractor/StreamUp.test.ts
Normal file
16
src/extractor/StreamUp.test.ts
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import winston from 'winston';
|
||||
import { createTestContext } from '../test';
|
||||
import { FetcherMock } from '../utils';
|
||||
import { ExtractorRegistry } from './ExtractorRegistry';
|
||||
import { StreamUp } from './StreamUp';
|
||||
|
||||
const logger = winston.createLogger({ transports: [new winston.transports.Console({ level: 'nope' })] });
|
||||
const extractorRegistry = new ExtractorRegistry(logger, [new StreamUp(new FetcherMock(`${__dirname}/__fixtures__/StreamUp`))]);
|
||||
|
||||
const ctx = createTestContext();
|
||||
|
||||
describe('StreamUp', () => {
|
||||
test('handle one battle after another', async () => {
|
||||
expect(await extractorRegistry.handle(ctx, new URL('https://strmup.to/6950ae79eaa4c'))).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
|
@ -1,111 +1,52 @@
|
|||
import crypto from 'crypto';
|
||||
import { NotFoundError } from '../error';
|
||||
import * as cheerio from 'cheerio';
|
||||
import { Context, Format, Meta, UrlResult } from '../types';
|
||||
import { guessHeightFromPlaylist } from '../utils';
|
||||
import { Extractor } from './Extractor';
|
||||
|
||||
/**
|
||||
* Port of:
|
||||
* https://github.com/Gujal00/ResolveURL/blob/master/script.module.resolveurl/lib/resolveurl/plugins/streamup.py
|
||||
*/
|
||||
interface StreamUpApiData {
|
||||
streaming_url: string;
|
||||
}
|
||||
|
||||
/** @see https://github.com/Gujal00/ResolveURL/blob/master/script.module.resolveurl/lib/resolveurl/plugins/streamup.py */
|
||||
export class StreamUp extends Extractor {
|
||||
public readonly id = 'streamup';
|
||||
public readonly label = 'StreamUp';
|
||||
public override readonly ttl = 6 * 60 * 60 * 1000; // 6 hours
|
||||
|
||||
public readonly label = 'StreamUP';
|
||||
|
||||
public override readonly ttl: number = 10800000; // 3h
|
||||
|
||||
public supports(_ctx: Context, url: URL): boolean {
|
||||
return [
|
||||
'streamup.ws',
|
||||
'streamup.cc',
|
||||
'strmup.to',
|
||||
'strmup.cc',
|
||||
return null !== url.host.match(/streamup|strmup/) || [
|
||||
'vfaststream.com',
|
||||
].includes(url.host);
|
||||
}
|
||||
|
||||
public override normalize(url: URL): URL {
|
||||
return new URL(`/${url.pathname.split('/').at(-1)}`, url.origin);
|
||||
}
|
||||
|
||||
protected async extractInternal(
|
||||
ctx: Context,
|
||||
url: URL,
|
||||
meta: Meta,
|
||||
): Promise<UrlResult[]> {
|
||||
const referer = `${url.origin}/`;
|
||||
|
||||
protected async extractInternal(ctx: Context, url: URL, meta: Meta): Promise<UrlResult[]> {
|
||||
const headers = {
|
||||
'Referer': referer,
|
||||
'Referer': `${url.origin}/`,
|
||||
'Origin': url.origin,
|
||||
'User-Agent': 'Mozilla/5.0',
|
||||
};
|
||||
|
||||
const html = await this.fetcher.text(ctx, url, { headers });
|
||||
|
||||
const sessionMatch = html.match(/'([a-f0-9]{32})'/);
|
||||
const encryptedMatch = html.match(/'([A-Za-z0-9+/=]{200,})'/);
|
||||
const data = await this.fetcher.json(ctx, new URL(`/ajax/stream?filecode=${url.pathname.split('/').at(-1)}`, url), { headers }) as StreamUpApiData;
|
||||
const playlistUrl = new URL(data.streaming_url);
|
||||
|
||||
let streamUrl: string | undefined;
|
||||
|
||||
if (sessionMatch && encryptedMatch) {
|
||||
/* encrypted flow */
|
||||
const sessionId = sessionMatch[1] as string;
|
||||
const encryptedB64 = encryptedMatch[1] as string;
|
||||
|
||||
const keyUrl = new URL(`/ajax/stream?session=${sessionId}`, url.origin);
|
||||
const keyB64 = await this.fetcher.text(ctx, keyUrl, { headers });
|
||||
|
||||
const key = Buffer.from(keyB64, 'base64');
|
||||
const encrypted = Buffer.from(encryptedB64, 'base64');
|
||||
|
||||
const iv = encrypted.subarray(0, 16);
|
||||
const ciphertext = encrypted.subarray(16);
|
||||
|
||||
const decipher = crypto.createDecipheriv('aes-128-cbc', key, iv);
|
||||
const decrypted = Buffer.concat([
|
||||
decipher.update(ciphertext),
|
||||
decipher.final(),
|
||||
]).toString('utf-8');
|
||||
|
||||
const data = JSON.parse(decrypted) as {
|
||||
streaming_url?: string;
|
||||
};
|
||||
|
||||
streamUrl = data.streaming_url;
|
||||
} else {
|
||||
/* fallback flow */
|
||||
const filecode = url.pathname.split('/').at(-1);
|
||||
const apiUrl = new URL(`/ajax/stream?filecode=${filecode}`, url.origin);
|
||||
|
||||
const jsonText = await this.fetcher.text(ctx, apiUrl, { headers });
|
||||
const data = JSON.parse(jsonText) as {
|
||||
streaming_url?: string;
|
||||
};
|
||||
|
||||
streamUrl = data.streaming_url;
|
||||
}
|
||||
|
||||
if (!streamUrl) {
|
||||
throw new NotFoundError();
|
||||
}
|
||||
|
||||
/* cleanup identical to Python resolver */
|
||||
streamUrl = streamUrl
|
||||
.replace(/\\r\\n/g, '')
|
||||
.replace(/\r|\n/g, '')
|
||||
.replace(/\\\//g, '/');
|
||||
const $ = cheerio.load(html);
|
||||
const title = $('title').text().trim();
|
||||
|
||||
return [
|
||||
{
|
||||
url: new URL(streamUrl),
|
||||
url: playlistUrl,
|
||||
format: Format.hls,
|
||||
label: this.label,
|
||||
sourceId: `${this.id}_${meta.countryCodes?.join('_')}`,
|
||||
ttl: this.ttl,
|
||||
requestHeaders: {
|
||||
Referer: referer,
|
||||
Origin: url.origin,
|
||||
},
|
||||
requestHeaders: headers,
|
||||
meta: {
|
||||
...meta,
|
||||
height: await guessHeightFromPlaylist(ctx, this.fetcher, playlistUrl, url, { headers }),
|
||||
title,
|
||||
},
|
||||
},
|
||||
];
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
#EXTM3U
|
||||
#EXT-X-VERSION:6
|
||||
#EXT-X-STREAM-INF:BANDWIDTH=1500000,AVERAGE-BANDWIDTH=1350000,CODECS="avc1.4d401f,mp4a.40.2",RESOLUTION=1920x1080,FRAME-RATE=30
|
||||
index_1920x1080.m3u8?token=35f702a94c0e324d607d8761795a3788-1768016464-104.28.197.7-5ebad85b212e5e349b388501e051c992a2b68e70fdcaa6cc18270adee1f7c003
|
||||
55
src/extractor/__fixtures__/StreamUp/https:strmup.to6950ae79eaa4c
generated
Normal file
55
src/extractor/__fixtures__/StreamUp/https:strmup.to6950ae79eaa4c
generated
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<script id="aclib" type="text/javascript" src="//acscdn.com/script/aclib.js"></script>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
|
||||
<title>Wake.Up.Dead.Man.A.Knives.Out.Mystery.2025</title>
|
||||
<script src='https://ssl.p.jwpcdn.com/player/v/8.36.2/jwplayer.js'></script>
|
||||
<meta name="robots" content="noindex">
|
||||
<link rel="stylesheet" type="text/css" href="panel/assets/css/jwplayer.css?v=5" />
|
||||
<link rel="stylesheet" type="text/css" href="panel/assets/css/netflix.css?v=5" />
|
||||
<script src="https://imasdk.googleapis.com/js/sdkloader/ima3.js"></script>
|
||||
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/sweetalert/2.1.0/sweetalert.min.js"></script>
|
||||
<style type="text/css">#video-container,body,html{width:100%;height:100%;overflow:hidden}body,html{font-family:Tahoma;padding:0;margin:0;background-color:#000}#video-container{position:fixed;top:0;left:0;z-index:10}#jwplayer{width:100%!important;height:100%!important}.play-button-outer{position:absolute;z-index:999997;width:6em;height:6em;background-color:gray;cursor:pointer}.play-button{margin:0 auto;top:25%;position:relative;width:0;height:0;border-style:solid;border-width:1.5em 0 1.5em 3em;border-color:transparent transparent transparent #000;opacity:.75}.play-button-outer:hover{background-color:#a9a9a9}.play-button-outer:hover .play-button{opacity:1}.swal-text,.swal-title{font-family:Arial,sans-serif}</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="video-container">
|
||||
<div id="jwplayer"></div>
|
||||
</div>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
|
||||
<script>
|
||||
jwplayer.key="ITWMv7t88JGzI0xPwW8I0+LveiXX9SWbfdmt0ArUSyc=";let player=jwplayer("jwplayer"),globalFilecode=null,positionApplied=!1,totalWatchTime=0;function getFilecodeFromURL(){let e=window.location.pathname.split("/");return e.pop()||e.pop()}function getQueryParam(e){return new URL(window.location.href).searchParams.get(e)}let filecode=getFilecodeFromURL();if(filecode){globalFilecode=filecode;let e=`/ajax/stream?filecode=${encodeURIComponent(filecode)}`,t=new URLSearchParams(window.location.search);t.delete("filecode");let _=t.toString();_&&(e+="&"+_),fetch(e).then(e=>e.json()).then(e=>{window.videoSubtitles=e.subtitles||[],window.defaultSubtitleLang=(e.default_sub_lang||"").toLowerCase(),setupSubtitlesOnly(e)}).catch(e=>console.error("Failed to load stream data:",e))}function setupSubtitlesOnly(e){let t=window.videoSubtitles||[],_=(window.defaultSubtitleLang||"").toLowerCase(),$=t.filter(e=>0===e.type).map(e=>{let t=e.language||"Subtitle",$=t.toLowerCase(),l=_&&($===_||$.includes(_));return{file:e.file_path,label:t,kind:"captions",default:l}});if($.filter(e=>e.default).length>1){let l=$.findIndex(e=>e.default);$=$.map((e,t)=>({...e,default:t===l}))}setupPlayer(e,$)}function setupPlayer(e,t){player.setup({playlist:[{sources:[{file:e.streaming_url}],title:e.title,image:e.thumbnail,tracks:t}],autostart:!1,cast:{},controls:!0,displaytitle:!0,displaydescription:!0,abouttext:"StreamUP",aboutlink:"https://streamup.cc/",skin:{name:"netflix",buttons:"over"},advertising:{client:"googima",schedule:{adBreak1:{offset:"pre",tag:e.vast_ads}}},playbackRateControls:!0,playbackRates:[.5,1,1.5,2]}),player.on("ready",function(){jwplayer().addButton('<svg xmlns="http://www.w3.org/2000/svg" class="jw-svg-icon jw-svg-icon-rewind2" viewBox="0 0 240 240" focusable="false"><path d="m 25.993957,57.778 v 125.3 c 0.03604,2.63589 2.164107,4.76396 4.8,4.8 h 62.7 v -19.3 h -48.2 v -96.4 H 160.99396 v 19.3 c 0,5.3 3.6,7.2 8,4.3 l 41.8,-27.9 c 2.93574,-1.480087 4.13843,-5.04363 2.7,-8 -0.57502,-1.174985 -1.52502,-2.124979 -2.7,-2.7 l -41.8,-27.9 c -4.4,-2.9 -8,-1 -8,4.3 v 19.3 H 30.893957 c -2.689569,0.03972 -4.860275,2.210431 -4.9,4.9 z m 163.422413,73.04577 c -3.72072,-6.30626 -10.38421,-10.29683 -17.7,-10.6 -7.31579,0.30317 -13.97928,4.29374 -17.7,10.6 -8.60009,14.23525 -8.60009,32.06475 0,46.3 3.72072,6.30626 10.38421,10.29683 17.7,10.6 7.31579,-0.30317 13.97928,-4.29374 17.7,-10.6 8.60009,-14.23525 8.60009,-32.06475 0,-46.3 z m -17.7,47.2 c -7.8,0 -14.4,-11 -14.4,-24.1 0,-13.1 6.6,-24.1 14.4,-24.1 7.8,0 14.4,11 14.4,24.1 0,13.1 -6.5,24.1 -14.4,24.1 z m -47.77056,9.72863 v -51 l -4.8,4.8 -6.8,-6.8 13,-12.99999 c 3.02543,-3.03598 8.21053,-0.88605 8.2,3.4 v 62.69999 z"></path></svg>',"Forward 10 sec",function(){jwplayer().seek(jwplayer().getPosition()+10)},"ff11"),jwplayer().addButton('<svg xmlns="http://www.w3.org/2000/svg" class="jw-svg-icon jw-svg-icon-rewind" viewBox="0 0 240 240" focusable="false"><path d="M113.2,131.078a21.589,21.589,0,0,0-17.7-10.6,21.589,21.589,0,0,0-17.7,10.6,44.769,44.769,0,0,0,0,46.3,21.589,21.589,0,0,0,17.7,10.6,21.589,21.589,0,0,0,17.7-10.6,44.769,44.769,0,0,0,0-46.3Zm-17.7,47.2c-7.8,0-14.4-11-14.4-24.1s6.6-24.1,14.4-24.1,14.4,11,14.4,24.1S103.4,178.278,95.5,178.278Zm-43.4,9.7v-51l-4.8,4.8-6.8-6.8,13-13a4.8,4.8,0,0,1,8.2,3.4v62.7l-9.6-.1Zm162-130.2v125.3a4.867,4.867,0,0,1-4.8,4.8H146.6v-19.3h48.2v-96.4H79.1v19.3c0,5.3-3.6,7.2-8,4.3l-41.8-27.9a6.013,6.013,0,0,1-2.7-8,5.887,5.887,0,0,1,2.7-2.7l41.8-27.9c4.4-2.9,8-1,8,4.3v19.3H209.2A4.974,4.974,0,0,1,214.1,57.778Z"></path></svg>',"Rewind 10 sec",function(){var e=jwplayer().getPosition()-10;e<0&&(e=0),jwplayer().seek(e)},"ff00")}),handlePlayerEvents(e.filecode)}function handlePlayerEvents(e){if(!e)return;let t=null;player.on("play",function(){if(!positionApplied){let _=localStorage.getItem(`videoPlaybackPosition_${e}`);_&&(player.seek(parseFloat(_)/1e3),positionApplied=!0)}t||(t=setInterval(()=>{totalWatchTime++},1e3))}),player.on("pause",()=>{clearInterval(t),t=null}),player.on("complete",()=>{clearInterval(t),t=null}),player.on("time",function(t){let _=t.position;localStorage.setItem(`videoPlaybackPosition_${e}`,1e3*_)})}
|
||||
</script>
|
||||
<script>
|
||||
const file_id="2229055",visitorData={file_id:"2229055",gpu:null,cpu:null,screen_res:`${screen.width}x${screen.height}`,iframe_size:`${window.innerWidth}x${window.innerHeight}`,mouse_position:"",click_position:"",page_duration:0,referer:document.referrer||window.location.href,watch_time:0,tab_visibility_changes:0};let startTime=Date.now(),lastActivityTime=Date.now(),inactivityStart=null;function updateActivity(){lastActivityTime=Date.now()}document.addEventListener("mousemove",t=>{visitorData.mouse_position=`${t.pageX}x${t.pageY}`,updateActivity()}),document.addEventListener("click",t=>{visitorData.click_position=`${t.pageX}x${t.pageY}`,updateActivity()}),document.addEventListener("visibilitychange",()=>{document.hidden&&visitorData.tab_visibility_changes++}),setInterval(()=>{let t=Date.now();t-lastActivityTime>=1e4&&!inactivityStart?inactivityStart=lastActivityTime:t-lastActivityTime<1e4&&inactivityStart&&(inactivityStart=null)},1e3);try{let t=document.createElement("canvas"),i=t.getContext("webgl")||t.getContext("experimental-webgl"),a=i.getExtension("WEBGL_debug_renderer_info");visitorData.gpu=a?i.getParameter(a.UNMASKED_RENDERER_WEBGL):"Unknown"}catch{visitorData.gpu="Unavailable"}visitorData.cpu=navigator.hardwareConcurrency?`${navigator.hardwareConcurrency} cores`:"Unknown";let hasSentData=!1;function sendVisitorData(){hasSentData||(hasSentData=!0,visitorData.page_duration=Math.round((Date.now()-startTime)/1e3),visitorData.watch_time=Math.round(totalWatchTime),fetch("/ajax/data",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(visitorData)}).catch(()=>{}))}setInterval(()=>{"undefined"!=typeof totalWatchTime&&!hasSentData&&Math.floor(totalWatchTime)>=87&&sendVisitorData()},500);
|
||||
</script>
|
||||
|
||||
<script src="assets/js/new100.js?v=1"></script>
|
||||
<!-- Google tag (gtag.js) -->
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=G-MJZHCJR7Q8"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
|
||||
gtag('config', 'G-MJZHCJR7Q8');
|
||||
</script>
|
||||
<script>
|
||||
const l = [{"url":"https://zoovanuzauphoth.net/4/9188322","delay":3000,"lastOpened":0}];
|
||||
let i = 0;
|
||||
document.addEventListener("click", function () {
|
||||
const t = Date.now(), e = l[i % l.length];
|
||||
if (t - e.lastOpened >= e.delay) {
|
||||
window.open(e.url, "popupWindow", "width=800,height=600,scrollbars=yes,resizable=yes");
|
||||
e.lastOpened = t;
|
||||
}
|
||||
i++;
|
||||
});
|
||||
</script>
|
||||
|
||||
<script>
|
||||
const l=[{"url":"https://obqj2.com/4/9637106","delay":240000,"lastOpened":0},{"url":"https://obqj2.com/4/9637106","delay":240000,"lastOpened":0}];let i=0;document.addEventListener("click",function(){const t=Date.now(),e=l[i%l.length];t-e.lastOpened>=e.delay&&(window.open(e.url,"popupWindow","width=800,height=600,scrollbars=yes,resizable=yes"),e.lastOpened=t),i++});
|
||||
</script><script>(function(){function c(){var b=a.contentDocument||a.contentWindow.document;if(b){var d=b.createElement('script');d.innerHTML="window.__CF$cv$params={r:'9bb6680ecad95d57',t:'MTc2Nzk4NzYyNw=='};var a=document.createElement('script');a.src='/cdn-cgi/challenge-platform/scripts/jsd/main.js';document.getElementsByTagName('head')[0].appendChild(a);";b.getElementsByTagName('head')[0].appendChild(d)}}if(document.body){var a=document.createElement('iframe');a.height=1;a.width=1;a.style.position='absolute';a.style.top=0;a.style.left=0;a.style.border='none';a.style.visibility='hidden';document.body.appendChild(a);if('loading'!==document.readyState)c();else if(window.addEventListener)document.addEventListener('DOMContentLoaded',c);else{var e=document.onreadystatechange||function(){};document.onreadystatechange=function(b){e(b);'loading'!==document.readyState&&(document.onreadystatechange=e,c())}}}})();</script></body>
|
||||
</html>
|
||||
1
src/extractor/__fixtures__/StreamUp/https:strmup.toajaxstreamfilecode6950ae79eaa4c
generated
Normal file
1
src/extractor/__fixtures__/StreamUp/https:strmup.toajaxstreamfilecode6950ae79eaa4c
generated
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"title":"","thumbnail":"https:\/\/add4.cdnup.cc\/thumbnail\/xWcziV3Qim\/6950ae79eaa4c.jpg","streaming_url":"https:\/\/s3-hls2-cdn59.strmupcdn.com\/hls\/SJbD5Zm1pj06jZ2LDbHa13YBmryxas\/master.m3u8?token=35f702a94c0e324d607d8761795a3788-1768016464-104.28.197.7-5ebad85b212e5e349b388501e051c992a2b68e70fdcaa6cc18270adee1f7c003","vast_ads":null,"filecode":"6950ae79eaa4c","subtitles":[{"id":521875,"status":1,"file_id":2229055,"type":0,"file_path":"https:\/\/add4.cdnup.cc\/subtitles\/QUKzfdu1n4\/PPTRdlsmJY94PKK_subtitle_0.vtt","language":"German \u2013 German (Forced)"},{"id":521876,"status":1,"file_id":2229055,"type":0,"file_path":"https:\/\/add4.cdnup.cc\/subtitles\/gxReoqgF82\/ABVuNSZeq61xYhM_subtitle_1.vtt","language":"German \u2013 German"},{"id":521877,"status":1,"file_id":2229055,"type":0,"file_path":"https:\/\/add4.cdnup.cc\/subtitles\/YSzO4RQUAu\/DNRW2kgCksC8YYq_subtitle_2.vtt","language":"German \u2013 German"},{"id":521878,"status":1,"file_id":2229055,"type":0,"file_path":"https:\/\/add4.cdnup.cc\/subtitles\/l7MtB81Fsb\/DSFucpIAjME1ZdV_subtitle_3.vtt","language":"German \u2013 German (SDH)"}],"default_sub_lang":"German"}
|
||||
23
src/extractor/__snapshots__/StreamUp.test.ts.snap
Normal file
23
src/extractor/__snapshots__/StreamUp.test.ts.snap
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
|
||||
exports[`StreamUp handle one battle after another 1`] = `
|
||||
[
|
||||
{
|
||||
"format": "hls",
|
||||
"label": "StreamUP",
|
||||
"meta": {
|
||||
"countryCodes": [],
|
||||
"extractorId": "streamup",
|
||||
"height": 1080,
|
||||
"title": "Wake.Up.Dead.Man.A.Knives.Out.Mystery.2025",
|
||||
},
|
||||
"requestHeaders": {
|
||||
"Origin": "https://strmup.to",
|
||||
"Referer": "https://strmup.to/",
|
||||
"User-Agent": "Mozilla/5.0",
|
||||
},
|
||||
"ttl": 10800000,
|
||||
"url": "https://s3-hls2-cdn59.strmupcdn.com/hls/SJbD5Zm1pj06jZ2LDbHa13YBmryxas/master.m3u8?token=35f702a94c0e324d607d8761795a3788-1768016464-104.28.197.7-5ebad85b212e5e349b388501e051c992a2b68e70fdcaa6cc18270adee1f7c003",
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
|
@ -15,6 +15,7 @@ import { RgShows } from './RgShows';
|
|||
import { SaveFiles } from './SaveFiles';
|
||||
import { StreamEmbed } from './StreamEmbed';
|
||||
import { Streamtape } from './Streamtape';
|
||||
import { StreamUp } from './StreamUp';
|
||||
import { SuperVideo } from './SuperVideo';
|
||||
import { Uqload } from './Uqload';
|
||||
import { Vidora } from './Vidora';
|
||||
|
|
@ -43,6 +44,7 @@ export const createExtractors = (fetcher: Fetcher): Extractor[] => {
|
|||
new SaveFiles(fetcher),
|
||||
new StreamEmbed(fetcher),
|
||||
new Streamtape(fetcher),
|
||||
new StreamUp(fetcher),
|
||||
new SuperVideo(fetcher),
|
||||
new Uqload(fetcher),
|
||||
new Vidora(fetcher),
|
||||
|
|
|
|||
Loading…
Reference in a new issue