refactor: add support for multi-language extractor results

This commit is contained in:
WebStreamr 2025-06-25 18:27:44 +00:00
parent e895077a7b
commit 91d5e9dd36
No known key found for this signature in database
27 changed files with 120 additions and 54 deletions

View file

@ -57,7 +57,7 @@ export class DoodStream extends Extractor {
sourceId: `${this.id}_${countryCode}`,
ttl: this.ttl,
meta: {
countryCode,
countryCodes: [countryCode],
title,
...(mp4Head['content-length'] && { bytes: parseInt(mp4Head['content-length'] as string) }),
...(height && { height }),

View file

@ -47,7 +47,7 @@ export class Dropload extends Extractor {
ttl: this.ttl,
meta: {
bytes: bytes.parse(sizeMatch[1] as string) as number,
countryCode,
countryCodes: [countryCode],
height: parseInt(heightMatch[1] as string) as number,
title,
},

View file

@ -38,7 +38,7 @@ export class ExternalUrl extends Extractor {
sourceId: `${this.id}_${countryCode}`,
ttl: this.ttl,
meta: {
countryCode,
countryCodes: [countryCode],
...(title && { title }),
},
},

View file

@ -33,7 +33,7 @@ export abstract class Extractor {
label: this.label,
sourceId: `${this.id}`,
meta: {
countryCode,
countryCodes: [countryCode],
...(title && { title }),
},
},

View file

@ -39,7 +39,7 @@ export class Fsst extends Extractor {
label: this.label,
sourceId: `${this.id}_${countryCode}_${index}`,
meta: {
countryCode,
countryCodes: [countryCode],
height: parseInt(heightAndUrlMatch[1] || heightFromFileHrefMatch[1] as string),
title,
},

View file

@ -46,7 +46,7 @@ export class KinoGer extends Extractor {
sourceId: `${this.id}_${countryCode}`,
ttl: this.ttl,
meta: {
countryCode,
countryCodes: [countryCode],
title,
...(height && { height }),
},

View file

@ -45,7 +45,7 @@ export class Mixdrop extends Extractor {
sourceId: `${this.id}_${countryCode}`,
ttl: this.ttl,
meta: {
countryCode,
countryCodes: [countryCode],
title,
...(sizeMatch && {
bytes: bytes.parse((sizeMatch[1] as string).replace(',', '')) as number,

View file

@ -58,7 +58,7 @@ export class Soaper extends Extractor {
sourceId: `${this.id}_${countryCode}`,
ttl: this.ttl,
meta: {
countryCode,
countryCodes: [countryCode],
title: `${title}`,
...(height && { height }),
},

View file

@ -50,7 +50,7 @@ export class SuperVideo extends Extractor {
sourceId: `${this.id}_${countryCode}`,
ttl: this.ttl,
meta: {
countryCode,
countryCodes: [countryCode],
title,
...(heightAndSizeMatch && {
bytes: bytes.parse(heightAndSizeMatch[2] as string) as number,

View file

@ -42,7 +42,7 @@ export class Uqload extends Extractor {
sourceId: `${this.id}_${countryCode}`,
ttl: this.ttl,
meta: {
countryCode,
countryCodes: [countryCode],
title,
...(heightMatch && {
height: parseInt(heightMatch[1] as string) as number,

View file

@ -55,7 +55,7 @@ export class VidSrc extends Extractor {
sourceId: `${this.id}_${slugify(serverName)}_${countryCode}`,
ttl: this.ttl,
meta: {
countryCode,
countryCodes: [countryCode],
title,
...(height && { height }),
},

View file

@ -37,7 +37,7 @@ export class VixSrc extends Extractor {
sourceId: `${this.id}_${countryCode}`,
ttl: this.ttl,
meta: {
countryCode,
countryCodes: [countryCode],
...(filenameMatch && { title: filenameMatch[1] }),
...(sizeMatch && { bytes: bytes.parse(`${sizeMatch[1]} kb`) as number }),
...(qualityMatch && { height: parseInt(qualityMatch[1] as string) }),

View file

@ -6,7 +6,9 @@ exports[`DoodStream can guess height from title 1`] = `
"format": "mp4",
"label": "DoodStream",
"meta": {
"countryCode": "fr",
"countryCodes": [
"fr",
],
"height": 720,
"title": "Black Mirror S04E02 FRENCH 720p WEB x264-RiPiT",
},
@ -27,7 +29,9 @@ exports[`DoodStream dood.to 1`] = `
"label": "DoodStream",
"meta": {
"bytes": 791702409,
"countryCode": "de",
"countryCodes": [
"de",
],
"title": "des-teufels-bad-2024",
},
"requestHeaders": {
@ -46,7 +50,9 @@ exports[`DoodStream doodster 1`] = `
"format": "mp4",
"label": "DoodStream",
"meta": {
"countryCode": "de",
"countryCodes": [
"de",
],
"title": "Brokeback Mountain 2005",
},
"requestHeaders": {

View file

@ -7,7 +7,9 @@ exports[`Dropload dropload.io 1`] = `
"label": "Dropload",
"meta": {
"bytes": 1395864371,
"countryCode": "de",
"countryCodes": [
"de",
],
"height": 1080,
"title": "des-teufels-bad-2024",
},

View file

@ -9,7 +9,9 @@ exports[`ExternalUrl johnalwayssame.com with title 1`] = `
"isExternal": true,
"label": "johnalwayssame.com",
"meta": {
"countryCode": "fr",
"countryCodes": [
"fr",
],
"title": "Black Mirror 4x2",
},
"sourceId": "external_fr",
@ -26,7 +28,9 @@ exports[`ExternalUrl netu.fanstream.us 1`] = `
"isExternal": true,
"label": "netu.fanstream.us",
"meta": {
"countryCode": "fr",
"countryCodes": [
"fr",
],
},
"sourceId": "external_fr",
"ttl": 3600000,

View file

@ -9,7 +9,9 @@ exports[`ExtractorRegistry returns external URLs if enabled by config 1`] = `
"isExternal": true,
"label": "mixdrop.ag",
"meta": {
"countryCode": "de",
"countryCodes": [
"de",
],
},
"sourceId": "external_de",
"ttl": 3600000,
@ -27,7 +29,9 @@ exports[`ExtractorRegistry returns external url for error 1`] = `
"isExternal": true,
"label": "Dropload",
"meta": {
"countryCode": "de",
"countryCodes": [
"de",
],
},
"sourceId": "dropload",
"url": "https://dropload.io/mocked-blocked.html",
@ -44,7 +48,9 @@ exports[`ExtractorRegistry returns external url for error with title 1`] = `
"isExternal": true,
"label": "Dropload",
"meta": {
"countryCode": "de",
"countryCodes": [
"de",
],
"title": "a title!",
},
"sourceId": "dropload",

View file

@ -6,7 +6,9 @@ exports[`Fsst Blood & Sinners 1`] = `
"format": "mp4",
"label": "Fsst",
"meta": {
"countryCode": "de",
"countryCodes": [
"de",
],
"height": 360,
"title": "Blood.and.Sinners.2025.mkv",
},
@ -17,7 +19,9 @@ exports[`Fsst Blood & Sinners 1`] = `
"format": "mp4",
"label": "Fsst",
"meta": {
"countryCode": "de",
"countryCodes": [
"de",
],
"height": 720,
"title": "Blood.and.Sinners.2025.mkv",
},
@ -28,7 +32,9 @@ exports[`Fsst Blood & Sinners 1`] = `
"format": "mp4",
"label": "Fsst",
"meta": {
"countryCode": "de",
"countryCodes": [
"de",
],
"height": 1080,
"title": "Blood.and.Sinners.2025.mkv",
},
@ -44,7 +50,9 @@ exports[`Fsst Dead City 1`] = `
"format": "mp4",
"label": "Fsst",
"meta": {
"countryCode": "de",
"countryCodes": [
"de",
],
"height": 360,
"title": "the.walking.dead.dead.city.s02e06.german.dl.1080p.web.x264-wvf.mkv",
},
@ -55,7 +63,9 @@ exports[`Fsst Dead City 1`] = `
"format": "mp4",
"label": "Fsst",
"meta": {
"countryCode": "de",
"countryCodes": [
"de",
],
"height": 720,
"title": "the.walking.dead.dead.city.s02e06.german.dl.1080p.web.x264-wvf.mkv",
},
@ -66,7 +76,9 @@ exports[`Fsst Dead City 1`] = `
"format": "mp4",
"label": "Fsst",
"meta": {
"countryCode": "de",
"countryCodes": [
"de",
],
"height": 1080,
"title": "the.walking.dead.dead.city.s02e06.german.dl.1080p.web.x264-wvf.mkv",
},
@ -82,7 +94,9 @@ exports[`Fsst How to Train Your Dragon 1`] = `
"format": "mp4",
"label": "Fsst",
"meta": {
"countryCode": "de",
"countryCodes": [
"de",
],
"height": 360,
"title": "How To Train Your Dragon 2025.mp4",
},

View file

@ -6,7 +6,9 @@ exports[`KinoGer Blood & Sinners 1`] = `
"format": "hls",
"label": "KinoGer",
"meta": {
"countryCode": "de",
"countryCodes": [
"de",
],
"title": "Blood.and.Sinners.2025.mkv",
},
"requestHeaders": {
@ -25,7 +27,9 @@ exports[`KinoGer Dead City 1`] = `
"format": "hls",
"label": "KinoGer",
"meta": {
"countryCode": "de",
"countryCodes": [
"de",
],
"height": 1080,
"title": "the.walking.dead.dead.city.s02e05.german.dl.1080p.web.x264-wvf.mkv",
},

View file

@ -9,7 +9,9 @@ exports[`Mixdrop mixdrop.my /e/ 1`] = `
"label": "Mixdrop (via MediaFlow Proxy)",
"meta": {
"bytes": 1059806248,
"countryCode": "de",
"countryCodes": [
"de",
],
"title": "28_giorni_dopo_2002_HD_-_Altadefinizione01.mp4",
},
"sourceId": "mixdrop_de",

View file

@ -6,7 +6,9 @@ exports[`Soaper Black Mirror 1`] = `
"format": "hls",
"label": "Soaper",
"meta": {
"countryCode": "en",
"countryCodes": [
"en",
],
"height": 720,
"title": "Black Mirror 4x2",
},
@ -23,7 +25,9 @@ exports[`Soaper Full Metal Jacket 1`] = `
"format": "hls",
"label": "Soaper",
"meta": {
"countryCode": "en",
"countryCodes": [
"en",
],
"height": 1080,
"title": "Full Metal Jacket (1987)",
},
@ -40,7 +44,9 @@ exports[`Soaper last of us s2e3 1`] = `
"format": "hls",
"label": "Soaper",
"meta": {
"countryCode": "de",
"countryCodes": [
"de",
],
"title": "The Last of Us 2x3",
},
"sourceId": "soaper_de",

View file

@ -8,7 +8,9 @@ exports[`SuperVideo embed only 1`] = `
"format": "hls",
"label": "SuperVideo",
"meta": {
"countryCode": "it",
"countryCodes": [
"it",
],
"title": "",
},
"sourceId": "supervideo_it",
@ -25,7 +27,9 @@ exports[`SuperVideo supervideo.cc /e/ 1`] = `
"label": "SuperVideo",
"meta": {
"bytes": 1073741824,
"countryCode": "de",
"countryCodes": [
"de",
],
"height": 720,
"title": "des-teufels-bad-2024",
},
@ -43,7 +47,9 @@ exports[`SuperVideo supervideo.tv /embed-/ 1`] = `
"label": "SuperVideo",
"meta": {
"bytes": 219571814,
"countryCode": "it",
"countryCodes": [
"it",
],
"height": 344,
"title": "Babylon 5 2x3",
},

View file

@ -6,7 +6,9 @@ exports[`Uqload uqload.net / 1`] = `
"format": "mp4",
"label": "Uqload (via MediaFlow Proxy)",
"meta": {
"countryCode": "fr",
"countryCodes": [
"fr",
],
"height": 360,
"title": "Black Mirror S07E06 MULTI VFF 1080p WEBrip EAC3 5 1 x265-TyHD",
},
@ -23,7 +25,9 @@ exports[`Uqload uqload.net /embed- 1`] = `
"format": "mp4",
"label": "Uqload (via MediaFlow Proxy)",
"meta": {
"countryCode": "fr",
"countryCodes": [
"fr",
],
"height": 360,
"title": "Black Mirror S07E06 MULTI VFF 1080p WEBrip EAC3 5 1 x265-TyHD",
},

View file

@ -6,7 +6,9 @@ exports[`VidSrc Black Mirror 1`] = `
"format": "hls",
"label": "VidSrc (CloudStream Pro)",
"meta": {
"countryCode": "en",
"countryCodes": [
"en",
],
"height": 1040,
"title": "Black Mirror (2011) S04E02",
},
@ -23,7 +25,9 @@ exports[`VidSrc Full Metal Jacket 1`] = `
"format": "hls",
"label": "VidSrc (CloudStream Pro)",
"meta": {
"countryCode": "en",
"countryCodes": [
"en",
],
"height": 714,
"title": "Full Metal Jacket (1987)",
},

View file

@ -7,7 +7,9 @@ exports[`VixSrc Black Mirror 1`] = `
"label": "VixSrc (via MediaFlow Proxy)",
"meta": {
"bytes": 2389338112,
"countryCode": "it",
"countryCodes": [
"it",
],
"height": 1080,
"title": "Black.Mirror.S04E02.Arkangel.1080p.NF.WEB-DL.ITA.ENG.DDP5.1.H.264.mkv",
},
@ -25,7 +27,9 @@ exports[`VixSrc Full Metal Jacket 1`] = `
"label": "VixSrc (via MediaFlow Proxy)",
"meta": {
"bytes": 8544718848,
"countryCode": "it",
"countryCodes": [
"it",
],
"height": 1080,
"title": "Full.metal.jacket.1987.1080p.x264.AC3.ITA.AAC.ENG.Subs.mkv",
},

View file

@ -27,9 +27,11 @@ export enum BlockedReason {
unknown = 'unknown',
}
type NonEmptyArray<T> = [T, ...T[]];
export interface Meta {
bytes?: number;
countryCode: CountryCode;
countryCodes: NonEmptyArray<CountryCode>;
height?: number;
title?: string;
}

View file

@ -98,7 +98,7 @@ describe('resolve', () => {
label: 'hoster.com',
sourceId: '',
meta: {
countryCode: CountryCode.de,
countryCodes: [CountryCode.de],
},
},
{
@ -109,7 +109,7 @@ describe('resolve', () => {
label: 'hoster.com',
sourceId: '',
meta: {
countryCode: CountryCode.de,
countryCodes: [CountryCode.de],
},
},
{
@ -120,7 +120,7 @@ describe('resolve', () => {
label: 'hoster.com',
sourceId: '',
meta: {
countryCode: CountryCode.de,
countryCodes: [CountryCode.de],
},
},
{
@ -131,7 +131,7 @@ describe('resolve', () => {
label: 'hoster.com',
sourceId: '',
meta: {
countryCode: CountryCode.de,
countryCodes: [CountryCode.de],
},
},
{
@ -142,7 +142,7 @@ describe('resolve', () => {
label: 'hoster.com',
sourceId: '',
meta: {
countryCode: CountryCode.de,
countryCodes: [CountryCode.de],
},
},
{
@ -153,7 +153,7 @@ describe('resolve', () => {
label: 'hoster.com',
sourceId: '',
meta: {
countryCode: CountryCode.de,
countryCodes: [CountryCode.de],
},
},
{
@ -164,7 +164,7 @@ describe('resolve', () => {
label: 'hoster.com',
sourceId: '',
meta: {
countryCode: CountryCode.de,
countryCodes: [CountryCode.de],
},
},
{
@ -175,7 +175,7 @@ describe('resolve', () => {
label: 'hoster.com',
sourceId: '',
meta: {
countryCode: CountryCode.de,
countryCodes: [CountryCode.de],
},
},
{
@ -186,7 +186,7 @@ describe('resolve', () => {
label: 'hoster.com',
sourceId: '',
meta: {
countryCode: CountryCode.de,
countryCodes: [CountryCode.de],
},
},
];

View file

@ -152,7 +152,9 @@ export class StreamResolver {
private buildName(ctx: Context, urlResult: UrlResult): string {
let name = envGetAppName();
name += ` ${flagFromCountryCode(urlResult.meta.countryCode)}`;
urlResult.meta.countryCodes.forEach((countryCode) => {
name += ` ${flagFromCountryCode(countryCode)}`;
});
if (urlResult.meta.height) {
name += ` ${urlResult.meta.height}p`;