feat(source): add HDHub4u

This commit is contained in:
WebStreamr 2026-03-27 21:42:10 +00:00
parent 43637a2ff4
commit 43f04455f1
No known key found for this signature in database
21 changed files with 21404 additions and 6 deletions

View file

@ -0,0 +1,28 @@
import { createTestContext } from '../test';
import { FetcherMock, ImdbId } from '../utils';
import { HDHub4u } from './HDHub4u';
const ctx = createTestContext();
describe('HDHub4u', () => {
let source: HDHub4u;
beforeEach(() => {
source = new HDHub4u(new FetcherMock(`${__dirname}/__fixtures__/HDHub4u`));
});
test('handle superman 2025', async () => {
const streams = await source.handle(ctx, 'movie', new ImdbId('tt5950044', undefined, undefined));
expect(streams).toMatchSnapshot();
});
test('handle stranger things s05e01', async () => {
const streams = await source.handle(ctx, 'series', new ImdbId('tt4574334', 5, 1));
expect(streams).toMatchSnapshot();
});
test('handle stranger things s05e08', async () => {
const streams = await source.handle(ctx, 'series', new ImdbId('tt4574334', 5, 8));
expect(streams).toMatchSnapshot();
});
});

120
src/source/HDHub4u.ts Normal file
View file

@ -0,0 +1,120 @@
import * as cheerio from 'cheerio';
import { ContentType } from 'stremio-addon-sdk';
import { Context, CountryCode, Meta } from '../types';
import { Fetcher, findCountryCodes, getImdbId, Id, ImdbId } from '../utils';
import { resolveRedirectUrl } from './hd-hub-helper';
import { Source, SourceResult } from './Source';
interface SearchResponsePartial {
hits: {
document: {
imdb_id: string;
permalink: string;
post_title: string;
};
}[];
}
export class HDHub4u extends Source {
public readonly id = 'hdhub4u';
public readonly label = 'HDHub4u';
public readonly contentTypes: ContentType[] = ['movie', 'series'];
public readonly countryCodes: CountryCode[] = [CountryCode.multi, CountryCode.gu, CountryCode.hi, CountryCode.ml, CountryCode.pa, CountryCode.ta, CountryCode.te];
public readonly baseUrl = 'https://new5.hdhub4u.fo';
private readonly searchUrl = 'https://search.pingora.fyi';
private readonly fetcher: Fetcher;
public constructor(fetcher: Fetcher) {
super();
this.fetcher = fetcher;
}
public async handleInternal(ctx: Context, _type: string, id: Id): Promise<SourceResult[]> {
const imdbId = await getImdbId(ctx, this.fetcher, id);
const pageUrls = await this.fetchPageUrls(ctx, imdbId);
return (await Promise.all(
pageUrls.map(async (pageUrl) => {
return await this.handlePage(ctx, pageUrl, imdbId);
}),
)).flat();
};
private readonly handlePage = async (ctx: Context, pageUrl: URL, imdbId: ImdbId): Promise<SourceResult[]> => {
const html = await this.fetcher.text(ctx, pageUrl);
const $ = cheerio.load(html);
const meta = {
countryCodes: [CountryCode.multi, ...findCountryCodes($('div:contains("Language"):not(:has(div)):first').text())],
};
if (!imdbId.episode) {
return [
...this.extractHubDriveUrlResults(html, meta),
...(await Promise.all(
$('a[href*="gadgetsweb"]').map((_i, el) => this.handleHubLinks(ctx, new URL($(el).attr('href') as string), pageUrl, meta)),
)).flat(),
];
}
return [
...(await Promise.all(
$(`a:contains("EPiSODE ${imdbId.episode}"), a:contains("EPiSODE ${String(imdbId.episode).padStart(2, '0')}")`)
.map(async (_i, el) => this.handleHubLinks(ctx, new URL($(el).attr('href') as string), pageUrl, meta)),
)).flat(),
...this.extractHubDriveUrlResults(
$(`h4:contains("EPiSODE ${imdbId.episode}"), h4:contains("EPiSODE ${String(imdbId.episode).padStart(2, '0')}")`)
.first()
.nextUntil('hr')
.map((_i, el) => $.html(el))
.get()
.join(''),
meta,
),
];
};
private readonly handleHubLinks = async (ctx: Context, redirectUrl: URL, refererUrl: URL, meta: Meta): Promise<SourceResult[]> => {
const hubLinksUrl = await resolveRedirectUrl(ctx, this.fetcher, redirectUrl);
const hubLinksHtml = await this.fetcher.text(ctx, hubLinksUrl, { headers: { Referer: refererUrl.href } });
return [
...this.extractHubDriveUrlResults(hubLinksHtml, { ...meta, referer: hubLinksUrl.href }),
];
};
private readonly extractHubDriveUrlResults = (html: string, meta: Meta): SourceResult[] => {
console.log(html);
const $ = cheerio.load(html);
return $('a[href*="hubdrive"]')
.map((_i, el) => ({ url: new URL($(el).attr('href') as string), meta }))
.toArray();
};
private readonly fetchPageUrls = async (ctx: Context, imdbId: ImdbId): Promise<URL[]> => {
const searchUrl = new URL(`/collections/post/documents/search?query_by=imdb_id&q=${encodeURIComponent(imdbId.id)}`, this.searchUrl);
const searchResponse = await this.fetcher.json(ctx, searchUrl, { headers: { Referer: this.baseUrl } }) as SearchResponsePartial;
return searchResponse.hits
.filter(hit =>
hit.document.imdb_id === imdbId.id
&& (
!imdbId.season
|| hit.document.post_title.includes(`Season ${imdbId.season}`)
|| hit.document.post_title.includes(`S${String(imdbId.season)}`)
|| hit.document.post_title.includes(`S${String(imdbId.season).padStart(2, '0')}`)
),
)
.map(hit => new URL(hit.document.permalink, this.baseUrl));
};
}

View file

@ -0,0 +1,20 @@
<html>
<head>
<title>Redirecting ...</title>
<meta name="referrer" content="no-referrer">
<meta name="robots" content="noindex, nofollow">
<meta name="author" content="s-b0t">
<meta name="googlebot" content="noindex,nofollow">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
<style>#container{width:100%;aspect-ratio:100 / 29}@media only screen and (min-width: 992px){img{height:80%!important;width:50%!important}}@media only screen and (min-width: 1200px){img{height:80%!important;width:50%!important}}.relative{position:relative}.bottom-left{position:absolute}.PurpleTxt{color:#7e41ff!important;font-weight:600;margin-left:.5ch;margin-right:.5ch}</style>
</head>
<body>
Redirecting ..
<script type="text/javascript">
function stck(e,t,i){let n="";if(i){let o=new Date;o.setTime(o.getTime()+6e4*i),n="; expires="+o.toUTCString()}document.cookie=`${e}=${t}; path=/; SameSite=None; Secure${n}`}
function s(e,t,i){let n=new Date,m={value:t,expiry:n.getTime()+i};window.localStorage.setItem(e,JSON.stringify(m));stck('xla',"s4t",4);}s('o','Y214WE0xWjNZbXRhVUdwMmIxQldObFo2ZFRCeFZVOXRRbmxxYVV0UU9YZHdZWGxxY1ZRNVkyOWhRV05OTW5Vd2NHdzFiVzVMUlhsTFVEbGliekl4ZVc5VVUyaE5WRWxzUzFBNGRsbFFWMmxXZDJKMlRFaDFSbHBVUVZaSFIwMWFja2Q1YVVwS01UUndWRmRuY1ZWaldtOUpWMkpLZUZvMWJsUkJaMGQ2T1hWS1UyTm1URE40TkVGSU5VaE5iVVZCVFcwd09WWmhNRDA9',180*1000);setTimeout(()=>window.location.href='https://cryptoinsights.site/homelander/', 2000);
</script>
</body></html>

View file

@ -0,0 +1,20 @@
<html>
<head>
<title>Redirecting ...</title>
<meta name="referrer" content="no-referrer">
<meta name="robots" content="noindex, nofollow">
<meta name="author" content="s-b0t">
<meta name="googlebot" content="noindex,nofollow">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
<style>#container{width:100%;aspect-ratio:100 / 29}@media only screen and (min-width: 992px){img{height:80%!important;width:50%!important}}@media only screen and (min-width: 1200px){img{height:80%!important;width:50%!important}}.relative{position:relative}.bottom-left{position:absolute}.PurpleTxt{color:#7e41ff!important;font-weight:600;margin-left:.5ch;margin-right:.5ch}</style>
</head>
<body>
Redirecting ..
<script type="text/javascript">
function stck(e,t,i){let n="";if(i){let o=new Date;o.setTime(o.getTime()+6e4*i),n="; expires="+o.toUTCString()}document.cookie=`${e}=${t}; path=/; SameSite=None; Secure${n}`}
function s(e,t,i){let n=new Date,m={value:t,expiry:n.getTime()+i};window.localStorage.setItem(e,JSON.stringify(m));stck('xla',"s4t",4);}s('o','Y214WE0xWjNZbXRhVUdwMmIxQldObFo2ZFRCeFZVOXRRbmxxYVV0UU9YZHdZWGxxY1ZRNVkyOWhRV05OTW5Vd2NHdzFiVzVMUlhsTFVEbGliekl4ZVc5VVUyaE5WRWxzUzFBNGRsbFFWMmxXZDJKMlRFaDFSbHBVUVZaSFIwMWFja2Q1YVVwS01UUndWRmRuY1ZWaldtOUpWMkpLZUZvMWJsUkJaMGQ2T1hWS1UyTm1URE40TkVGSU5VaE5iVVZDUkVjd09WWmhNRDA9',180*1000);setTimeout(()=>window.location.href='https://cryptoinsights.site/homelander/', 2000);
</script>
</body></html>

View file

@ -0,0 +1,20 @@
<html>
<head>
<title>Redirecting ...</title>
<meta name="referrer" content="no-referrer">
<meta name="robots" content="noindex, nofollow">
<meta name="author" content="s-b0t">
<meta name="googlebot" content="noindex,nofollow">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
<style>#container{width:100%;aspect-ratio:100 / 29}@media only screen and (min-width: 992px){img{height:80%!important;width:50%!important}}@media only screen and (min-width: 1200px){img{height:80%!important;width:50%!important}}.relative{position:relative}.bottom-left{position:absolute}.PurpleTxt{color:#7e41ff!important;font-weight:600;margin-left:.5ch;margin-right:.5ch}</style>
</head>
<body>
Redirecting ..
<script type="text/javascript">
function stck(e,t,i){let n="";if(i){let o=new Date;o.setTime(o.getTime()+6e4*i),n="; expires="+o.toUTCString()}document.cookie=`${e}=${t}; path=/; SameSite=None; Secure${n}`}
function s(e,t,i){let n=new Date,m={value:t,expiry:n.getTime()+i};window.localStorage.setItem(e,JSON.stringify(m));stck('xla',"s4t",4);}s('o','Y214WE0xWjNZbXRhVUdwMmIxQldObFo2ZFRCeFZVOXRRbmxxYVV0UU9YZHdZWGxxY1ZRNVkyOWhRV05OTW5Vd2NHdzFiVzVMUlhsTFVEbGliekl4ZVc5VVUyaE5WRWxzUzFBNGRsbFFWMmxXZDJKMlRFaDFSbHBVUVZaSFIwMWFja2Q1YVVwS01UUndWRmRuY1ZWaldtOUpWMkpLZUZvMWJsUkJaMGQ2T1hWS1UyTm1URE40TkVGSU5VaE5iVVZDU0Vjd09WWmhNRDA9',180*1000);setTimeout(()=>window.location.href='https://cryptoinsights.site/homelander/', 2000);
</script>
</body></html>

View file

@ -0,0 +1,20 @@
<html>
<head>
<title>Redirecting ...</title>
<meta name="referrer" content="no-referrer">
<meta name="robots" content="noindex, nofollow">
<meta name="author" content="s-b0t">
<meta name="googlebot" content="noindex,nofollow">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
<style>#container{width:100%;aspect-ratio:100 / 29}@media only screen and (min-width: 992px){img{height:80%!important;width:50%!important}}@media only screen and (min-width: 1200px){img{height:80%!important;width:50%!important}}.relative{position:relative}.bottom-left{position:absolute}.PurpleTxt{color:#7e41ff!important;font-weight:600;margin-left:.5ch;margin-right:.5ch}</style>
</head>
<body>
Redirecting ..
<script type="text/javascript">
function stck(e,t,i){let n="";if(i){let o=new Date;o.setTime(o.getTime()+6e4*i),n="; expires="+o.toUTCString()}document.cookie=`${e}=${t}; path=/; SameSite=None; Secure${n}`}
function s(e,t,i){let n=new Date,m={value:t,expiry:n.getTime()+i};window.localStorage.setItem(e,JSON.stringify(m));stck('xla',"s4t",4);}s('o','Y214WE0xWjNZbXRhVUdwMmIxQldObFo2ZFRCeFZVOXRRbmxxYVV0UU9YZHdZWGxxY1ZRNVkyOWhRV05OTW5Vd2NHdzFiVzVMUlhsTFVEbGliekl4ZVc5VVUyaE5WRWxzUzFBNGRsbFFWMmxXZDJKMlRFaDFSbHBVUVZaSFIwMWFja2Q1YVVwS01UUndWRmRuY1ZWaldtOUpWMkpLZUZvMWJsUkJaMGQ2T1hWS1UyTm1URE40TkVGSU5VaE5iVVZCY1cwd09WWmhNRDA9',180*1000);setTimeout(()=>window.location.href='https://cryptoinsights.site/homelander/', 2000);
</script>
</body></html>

View file

@ -0,0 +1,20 @@
<html>
<head>
<title>Redirecting ...</title>
<meta name="referrer" content="no-referrer">
<meta name="robots" content="noindex, nofollow">
<meta name="author" content="s-b0t">
<meta name="googlebot" content="noindex,nofollow">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
<style>#container{width:100%;aspect-ratio:100 / 29}@media only screen and (min-width: 992px){img{height:80%!important;width:50%!important}}@media only screen and (min-width: 1200px){img{height:80%!important;width:50%!important}}.relative{position:relative}.bottom-left{position:absolute}.PurpleTxt{color:#7e41ff!important;font-weight:600;margin-left:.5ch;margin-right:.5ch}</style>
</head>
<body>
Redirecting ..
<script type="text/javascript">
function stck(e,t,i){let n="";if(i){let o=new Date;o.setTime(o.getTime()+6e4*i),n="; expires="+o.toUTCString()}document.cookie=`${e}=${t}; path=/; SameSite=None; Secure${n}`}
function s(e,t,i){let n=new Date,m={value:t,expiry:n.getTime()+i};window.localStorage.setItem(e,JSON.stringify(m));stck('xla',"s4t",4);}s('o','Y214WE0xWjNZbXRhVUdwMmIxQldObFo2ZFRCeFZVOXRRbmxxYVV0UU9YZHdZWGxxY1ZRNVkyOWhRV05OTW5Vd2NHdzFiVzVMUlhsTFVEbGliekl4ZVc5VVUyaE5WRWxzUzFBNGRsbFFWMmxXZDJKMlRFaDFSbHBVUVZaSFIwMWFja2Q1YVVwS01UUndWRmRuY1ZWaldtOUpWMkpLZUZvMWJsUkJaMGQ2T1hWS1UyTm1URE40TkhKU01WSkdTMk5CU1ZSbU9WWmhNRDA9',180*1000);setTimeout(()=>window.location.href='https://cryptoinsights.site/homelander/', 2000);
</script>
</body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1 @@
{"facet_counts":[],"found":1,"hits":[{"document":{"category":["300MB Movies","Action","Adventure","Dual Audio","HD Movies","Hindi Dubbed","HollyWood","Sci-Fi"],"director":["James Gunn"],"id":"174394","imdb_id":"tt5950044","permalink":"/superman-2025-hindi-webrip-full-movie/","post_date":"August 24, 2025","post_thumbnail":"https://image.tmdb.org/t/p/w500/1H9hdeRoniz30RKhyr1uLdBTfpG.jpg","post_title":"Superman (2025) iMAX DS4K WEB-DL [Hindi (DD5.1) & English] 4K 1080p 720p & 480p Dual Audio [x264/10Bit-HEVC] | Full Movie","post_type":"post","sort_by_date":1756030053,"stars":["David Corenswet","Rachel Brosnahan","Nicholas Hoult"]},"highlight":{"imdb_id":{"matched_tokens":["tt5950044"],"snippet":"<mark>tt5950044</mark>"}},"highlights":[{"field":"imdb_id","matched_tokens":["tt5950044"],"snippet":"<mark>tt5950044</mark>"}],"text_match":578730123365711993,"text_match_info":{"best_field_score":"1108091339008","best_field_weight":15,"fields_matched":1,"num_tokens_dropped":0,"score":"578730123365711993","tokens_matched":1,"typo_prefix_score":0}}],"out_of":13464,"page":1,"request_params":{"collection_name":"post","first_q":"tt5950044","per_page":10,"q":"tt5950044"},"search_cutoff":false,"search_time_ms":0}

View file

@ -0,0 +1,208 @@
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
exports[`HDHub4u handle stranger things s05e01 1`] = `
[
{
"meta": {
"countryCodes": [
"multi",
"en",
"hi",
],
},
"url": "https://hubdrive.space/file/2452204677",
},
{
"meta": {
"countryCodes": [
"multi",
"en",
"hi",
],
},
"url": "https://hubdrive.space/file/1788432714",
},
]
`;
exports[`HDHub4u handle stranger things s05e08 1`] = `
[
{
"meta": {
"countryCodes": [
"multi",
"en",
"hi",
],
"referer": "https://hblinks.dad/archives/102319",
},
"url": "https://hubdrive.space/file/1793632174",
},
{
"meta": {
"countryCodes": [
"multi",
"en",
"hi",
],
"referer": "https://hblinks.dad/archives/102319",
},
"url": "https://hubdrive.space/file/2655940410",
},
{
"meta": {
"countryCodes": [
"multi",
"en",
"hi",
],
"referer": "https://hblinks.dad/archives/102319",
},
"url": "https://hubdrive.space/file/2007803192",
},
{
"meta": {
"countryCodes": [
"multi",
"en",
"hi",
],
"referer": "https://hblinks.dad/archives/102319",
},
"url": "https://hubdrive.space/file/2913823672",
},
{
"meta": {
"countryCodes": [
"multi",
"en",
"hi",
],
"referer": "https://hblinks.dad/archives/102319",
},
"url": "https://hubdrive.space/file/1898122266",
},
{
"meta": {
"countryCodes": [
"multi",
"en",
"hi",
],
"referer": "https://hblinks.dad/archives/102319",
},
"url": "https://hubdrive.space/file/3043520687",
},
{
"meta": {
"countryCodes": [
"multi",
"en",
"hi",
],
"referer": "https://hblinks.dad/archives/102319",
},
"url": "https://hubdrive.space/file/4664307676",
},
{
"meta": {
"countryCodes": [
"multi",
"en",
"hi",
],
"referer": "https://hblinks.dad/archives/102319",
},
"url": "https://hubdrive.space/file/8835271729",
},
]
`;
exports[`HDHub4u handle superman 2025 1`] = `
[
{
"meta": {
"countryCodes": [
"multi",
"en",
"hi",
],
},
"url": "https://hubdrive.space/file/2048323831",
},
{
"meta": {
"countryCodes": [
"multi",
"en",
"hi",
],
},
"url": "https://hubdrive.space/file/1931317982",
},
{
"meta": {
"countryCodes": [
"multi",
"en",
"hi",
],
},
"url": "https://hubdrive.space/file/7875454809",
},
{
"meta": {
"countryCodes": [
"multi",
"en",
"hi",
],
},
"url": "https://hubdrive.space/file/3608508909",
},
{
"meta": {
"countryCodes": [
"multi",
"en",
"hi",
],
"referer": "https://hblinks.dad/archives/95885",
},
"url": "https://hubdrive.space/file/2171324800",
},
{
"meta": {
"countryCodes": [
"multi",
"en",
"hi",
],
"referer": "https://hblinks.dad/archives/95884",
},
"url": "https://hubdrive.space/file/1866728891",
},
{
"meta": {
"countryCodes": [
"multi",
"en",
"hi",
],
"referer": "https://hblinks.dad/archives/95883",
},
"url": "https://hubdrive.space/file/3938026297",
},
{
"meta": {
"countryCodes": [
"multi",
"en",
"hi",
],
"referer": "https://hblinks.dad/archives/95882",
},
"url": "https://hubdrive.space/file/2823990434",
},
]
`;

View file

@ -6,6 +6,7 @@ import { Eurostreaming } from './Eurostreaming';
import { FourKHDHub } from './FourKHDHub';
import { Frembed } from './Frembed';
import { FrenchCloud } from './FrenchCloud';
import { HDHub4u } from './HDHub4u';
import { HomeCine } from './HomeCine';
import { KinoGer } from './KinoGer';
import { Kokoshka } from './Kokoshka';
@ -28,6 +29,7 @@ export const createSources = (fetcher: Fetcher): Source[] => {
return [
// multi
new FourKHDHub(fetcher),
new HDHub4u(fetcher),
new VixSrc(fetcher),
new VidSrc(),
new RgShows(fetcher),

View file

@ -11,7 +11,7 @@ exports[`buildManifest default manifest 1`] = `
"config": [
{
"key": "multi",
"title": "Multi 🌐 (4KHDHub, RgShows, VidSrc, VixSrc)",
"title": "Multi 🌐 (4KHDHub, HDHub4u, RgShows, VidSrc, VixSrc)",
"type": "checkbox",
},
{
@ -34,9 +34,14 @@ exports[`buildManifest default manifest 1`] = `
"title": "French 🇫🇷 (Frembed, FrenchCloud, Movix)",
"type": "checkbox",
},
{
"key": "gu",
"title": "Gujarati 🇮🇳 (HDHub4u)",
"type": "checkbox",
},
{
"key": "hi",
"title": "Hindi 🇮🇳 (4KHDHub)",
"title": "Hindi 🇮🇳 (4KHDHub, HDHub4u)",
"type": "checkbox",
},
{
@ -44,19 +49,29 @@ exports[`buildManifest default manifest 1`] = `
"title": "Italian 🇮🇹 (Eurostreaming, MostraGuarda, VixSrc)",
"type": "checkbox",
},
{
"key": "ml",
"title": "Malayalam 🇮🇳 (HDHub4u)",
"type": "checkbox",
},
{
"key": "mx",
"title": "Latin American Spanish 🇲🇽 (CineHDPlus, Cuevana, HomeCine, VerHdLink)",
"type": "checkbox",
},
{
"key": "pa",
"title": "Punjabi 🇮🇳 (HDHub4u)",
"type": "checkbox",
},
{
"key": "ta",
"title": "Tamil 🇮🇳 (4KHDHub)",
"title": "Tamil 🇮🇳 (4KHDHub, HDHub4u)",
"type": "checkbox",
},
{
"key": "te",
"title": "Telugu 🇮🇳 (4KHDHub)",
"title": "Telugu 🇮🇳 (4KHDHub, HDHub4u)",
"type": "checkbox",
},
{
@ -134,9 +149,9 @@ exports[`buildManifest default manifest 1`] = `
],
"description": "Provides HTTP URLs from streaming websites. Configure add-on for additional languages. Add MediaFlow proxy for more URLs.
Supported languages: Albanian, German, Castilian Spanish, French, Hindi, Italian, Latin American Spanish, Tamil, Telugu
Supported languages: Albanian, German, Castilian Spanish, French, Gujarati, Hindi, Italian, Malayalam, Latin American Spanish, Punjabi, Tamil, Telugu
Supported sources: 4KHDHub, CineHDPlus, Cuevana, Einschalten, Eurostreaming, Frembed, FrenchCloud, HomeCine, KinoGer, Kokoshka, MegaKino, MeineCloud, MostraGuarda, Movix, RgShows, StreamKiste, VerHdLink, VidSrc, VixSrc
Supported sources: 4KHDHub, CineHDPlus, Cuevana, Einschalten, Eurostreaming, Frembed, FrenchCloud, HDHub4u, HomeCine, KinoGer, Kokoshka, MegaKino, MeineCloud, MostraGuarda, Movix, RgShows, StreamKiste, VerHdLink, VidSrc, VixSrc
Supported extractors: ",
"id": "webstreamr",