Help with VidMoly extractor #477

Closed
opened 2025-11-03 15:03:31 +00:00 by GLlgGL · 5 comments
GLlgGL commented 2025-11-03 15:03:31 +00:00 (Migrated from github.com)

Hi

I am trying to convert the VidMoly extractor from ResolveURL and I am able to get the final link but isn't playable

Maybe I'm missing something?

My Code

import * as cheerio from 'cheerio';
import { NotFoundError } from '../error';
import { Context, Format, Meta, UrlResult } from '../types';
import { Extractor } from './Extractor';
import { guessHeightFromPlaylist } from '../utils/height';

export class VidMoly extends Extractor {
public readonly id = 'vidmoly';
public readonly label = 'VidMoly';
public override readonly ttl = 10800000; // 3h

private domains = ['vidmoly.me', 'vidmoly.to', 'vidmoly.net'];

public supports(_ctx: Context, url: URL): boolean {
return this.domains.some((d) => url.host.includes(d));
}

public override normalize(url: URL): URL {
if (!this.supports({} as any, url)) return url; // skip if not our domain
const fixedPath = url.pathname.startsWith('/embed-')
? url.pathname
: url.pathname.replace(/^/(embed-|w/)?/, '/embed-');
return new URL(${url.origin}${fixedPath});
}

protected async extractInternal(ctx: Context, url: URL, meta: Meta): Promise<UrlResult[]> {
const headers: Record<string, string> = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)',
Referer: url.href,
'Sec-Fetch-Dest': 'iframe',
};

// Fetch HTML page
const html = await this.fetcher.text(ctx, url, headers);
if (!html || html.includes('Video not found')) {
  throw new NotFoundError();
}

// Extract sources
const sourcesMatch = html.match(/sources:\s*\[\{file:"(?<url>[^"]+)"/);
const mediaUrl = sourcesMatch?.groups?.['url'];
if (!mediaUrl) throw new NotFoundError('Video link not found');

// Normalize URL
const streamUrl = mediaUrl.startsWith('//')
  ? 'https:' + mediaUrl
  : mediaUrl.startsWith('/')
    ? url.origin + mediaUrl
    : mediaUrl;

let height: number | undefined;
try {
  height = await guessHeightFromPlaylist(ctx, this.fetcher, new URL(streamUrl), new URL(streamUrl), headers);
} catch {
  // ignore
}

// Extract title
const $ = cheerio.load(html);
const title = $('title').text().trim() || this.label;

return [{
  url: new URL(streamUrl),
  format: Format.hls,
  label: this.label,
  sourceId: `${this.id}_${meta.countryCodes?.join('_') ?? 'all'}`,
  ttl: this.ttl,
  requestHeaders: headers,
  meta: { ...meta, title, height },
}];

}
}

Logs

2025-11-03T14:57:58.636Z info 5f66855d-93a4-4d29-9869-031f524ca474: Extract https://vidmoly.net/embed-veruo20ra0sr.html using vidmoly extractor
2025-11-03T14:57:58.636Z info 5f66855d-93a4-4d29-9869-031f524ca474: Fetch GET https://vidmoly.net/embed-veruo20ra0sr.html
2025-11-03T14:57:58.862Z info 5f66855d-93a4-4d29-9869-031f524ca474: Got 200 (OK) for https://vidmoly.net/embed-veruo20ra0sr.html
2025-11-03T14:57:58.999Z info 5f66855d-93a4-4d29-9869-031f524ca474: Fetch GET https://prx-1328-ant.vmwesa.online/hls2/01/02022/5ffv1lrj1x0p_,l,n,.urlset/master.m3u8?t=gOSw6PadFPkD-28IovjZXWTEeis9-P9mmJvi2lbqM_U&s=1762181878&e=43200&v=&srv=bck-1356-ant-o&i=0.4&sp=0&asn=14618
2025-11-03T14:57:59.380Z info 5f66855d-93a4-4d29-9869-031f524ca474: Got 200 (OK) for https://prx-1328-ant.vmwesa.online/hls2/01/02022/5ffv1lrj1x0p_,l,n,.urlset/master.m3u8?t=gOSw6PadFPkD-28IovjZXWTEeis9-P9mmJvi2lbqM_U&s=1762181878&e=43200&v=&srv=bck-1356-ant-o&i=0.4&sp=0&asn=14618

but that final link is not playable...

Hi I am trying to convert the VidMoly extractor from [ResolveURL ](https://github.com/Gujal00/ResolveURL/blob/master/script.module.resolveurl/lib/resolveurl/plugins/vidmoly.py)and I am able to get the final link but isn't playable Maybe I'm missing something? My Code import * as cheerio from 'cheerio'; import { NotFoundError } from '../error'; import { Context, Format, Meta, UrlResult } from '../types'; import { Extractor } from './Extractor'; import { guessHeightFromPlaylist } from '../utils/height'; export class VidMoly extends Extractor { public readonly id = 'vidmoly'; public readonly label = 'VidMoly'; public override readonly ttl = 10800000; // 3h private domains = ['vidmoly.me', 'vidmoly.to', 'vidmoly.net']; public supports(_ctx: Context, url: URL): boolean { return this.domains.some((d) => url.host.includes(d)); } public override normalize(url: URL): URL { if (!this.supports({} as any, url)) return url; // skip if not our domain const fixedPath = url.pathname.startsWith('/embed-') ? url.pathname : url.pathname.replace(/^\/(embed-|w\/)?/, '/embed-'); return new URL(`${url.origin}${fixedPath}`); } protected async extractInternal(ctx: Context, url: URL, meta: Meta): Promise<UrlResult[]> { const headers: Record<string, string> = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)', Referer: url.href, 'Sec-Fetch-Dest': 'iframe', }; // Fetch HTML page const html = await this.fetcher.text(ctx, url, headers); if (!html || html.includes('Video not found')) { throw new NotFoundError(); } // Extract sources const sourcesMatch = html.match(/sources:\s*\[\{file:"(?<url>[^"]+)"/); const mediaUrl = sourcesMatch?.groups?.['url']; if (!mediaUrl) throw new NotFoundError('Video link not found'); // Normalize URL const streamUrl = mediaUrl.startsWith('//') ? 'https:' + mediaUrl : mediaUrl.startsWith('/') ? url.origin + mediaUrl : mediaUrl; let height: number | undefined; try { height = await guessHeightFromPlaylist(ctx, this.fetcher, new URL(streamUrl), new URL(streamUrl), headers); } catch { // ignore } // Extract title const $ = cheerio.load(html); const title = $('title').text().trim() || this.label; return [{ url: new URL(streamUrl), format: Format.hls, label: this.label, sourceId: `${this.id}_${meta.countryCodes?.join('_') ?? 'all'}`, ttl: this.ttl, requestHeaders: headers, meta: { ...meta, title, height }, }]; } } Logs 2025-11-03T14:57:58.636Z info 5f66855d-93a4-4d29-9869-031f524ca474: Extract https://vidmoly.net/embed-veruo20ra0sr.html using vidmoly extractor 2025-11-03T14:57:58.636Z info 5f66855d-93a4-4d29-9869-031f524ca474: Fetch GET https://vidmoly.net/embed-veruo20ra0sr.html 2025-11-03T14:57:58.862Z info 5f66855d-93a4-4d29-9869-031f524ca474: Got 200 (OK) for https://vidmoly.net/embed-veruo20ra0sr.html 2025-11-03T14:57:58.999Z info 5f66855d-93a4-4d29-9869-031f524ca474: Fetch GET https://prx-1328-ant.vmwesa.online/hls2/01/02022/5ffv1lrj1x0p_,l,n,.urlset/master.m3u8?t=gOSw6PadFPkD-28IovjZXWTEeis9-P9mmJvi2lbqM_U&s=1762181878&e=43200&v=&srv=bck-1356-ant-o&i=0.4&sp=0&asn=14618 2025-11-03T14:57:59.380Z info 5f66855d-93a4-4d29-9869-031f524ca474: Got 200 (OK) for https://prx-1328-ant.vmwesa.online/hls2/01/02022/5ffv1lrj1x0p_,l,n,.urlset/master.m3u8?t=gOSw6PadFPkD-28IovjZXWTEeis9-P9mmJvi2lbqM_U&s=1762181878&e=43200&v=&srv=bck-1356-ant-o&i=0.4&sp=0&asn=14618 but that final link is not playable...
GLlgGL commented 2025-11-04 10:01:30 +00:00 (Migrated from github.com)

This got it from extractor not working

https://prx-1328-ant.vmwesa.online/hls2/01/02071/g4ahma6kv2aw_,l,n,.urlset/master.m3u8?t=VAgaZRixAz9k8BRlGZSs5mBc6SvdoVG6MRKEEMDKxfI&s=1762254753&e=43200&v=&srv=bck-1331-ant&i=0.4&sp=0&asn=14618

This got it from dev tools browser works

https://prx-1328-ant.vmwesa.online/hls2/01/02075/x7r96gtp2m1b_,l,n,.urlset/master.m3u8?t=iVN1t4rdOU9yFMayxSPCRbTn8lnlgJtj159H--few_8&s=1762254842&e=43200&v=&srv=bck-1325-ant&i=0.4&sp=0&asn=47394

There are only small differencies...Maybe bad referer?

This got it from extractor not working `https://prx-1328-ant.vmwesa.online/hls2/01/02071/g4ahma6kv2aw_,l,n,.urlset/master.m3u8?t=VAgaZRixAz9k8BRlGZSs5mBc6SvdoVG6MRKEEMDKxfI&s=1762254753&e=43200&v=&srv=bck-1331-ant&i=0.4&sp=0&asn=14618` This got it from dev tools browser works `https://prx-1328-ant.vmwesa.online/hls2/01/02075/x7r96gtp2m1b_,l,n,.urlset/master.m3u8?t=iVN1t4rdOU9yFMayxSPCRbTn8lnlgJtj159H--few_8&s=1762254842&e=43200&v=&srv=bck-1325-ant&i=0.4&sp=0&asn=47394` There are only small differencies...Maybe bad referer?
GLlgGL commented 2025-11-13 11:07:36 +00:00 (Migrated from github.com)

Ok after some tests today I finally found that the links are IP locked. How to bypass this? Will mediaflow works? If yes, I see that mediflow doesnt list vidmoly in his extractors list. Any otherway to deal with?

curl -s -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)" -H "Referer: https://vidmoly.net/" -H "Sec-Fetch-Dest: iframe" "https://vidmoly.net/embed-hco244815wf7.html" | grep -oP 'sources :\s*\[\{file:"\K[^"]+'

Ok after some tests today I finally found that the links are IP locked. How to bypass this? Will mediaflow works? If yes, I see that mediflow doesnt list vidmoly in his extractors list. Any otherway to deal with? `curl -s -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)" -H "Referer: https://vidmoly.net/" -H "Sec-Fetch-Dest: iframe" "https://vidmoly.net/embed-hco244815wf7.html" | grep -oP 'sources :\s*\[\{file:"\K[^"]+'`
webstreamr commented 2025-11-13 21:47:51 +00:00 (Migrated from github.com)

Sounds like it needs a new extractor in mfp. Most likely there is already one that works in a similar way and can be used as basis

Sounds like it needs a new extractor in mfp. Most likely there is already one that works in a similar way and can be used as basis
GLlgGL commented 2025-11-13 22:17:08 +00:00 (Migrated from github.com)

Ok I will wait for you. The vidmoly I see on alot of websites and has always 720/1080p qualities

Ok I will wait for you. The vidmoly I see on alot of websites and has always 720/1080p qualities
GLlgGL commented 2025-11-19 20:05:20 +00:00 (Migrated from github.com)

I will open a pull request for you to add vidmoly extractor.

I opened a pull request on mediaflow proxy repository and the author just merged it. I tested and it works.

So thats close this.

I will open a pull request for you to add vidmoly extractor. I opened a pull request on mediaflow proxy repository and the author just merged it. I tested and it works. So thats close this.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: Creepso/webstreamr-github#477
No description provided.