Skip to content

Commit 92b4eb1

Browse files
committed
[AniLINK] add support for extracting episodes from FMovies + fix miruro
1 parent ff0a97f commit 92b4eb1

1 file changed

Lines changed: 45 additions & 7 deletions

File tree

AniLINK/AniLINK_Episode-Link-Extractor.user.js

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
// ==UserScript==
22
// @name AniLINK - Episode Link Extractor
33
// @namespace https://greasyfork.org/en/users/781076-jery-js
4-
// @version 6.26.0
4+
// @version 6.27.0
55
// @description Stream or download your favorite anime series effortlessly with AniLINK! Unlock the power to play any anime series directly in your preferred video player or download entire seasons in a single click using popular download managers like IDM. AniLINK generates direct download links for all episodes, conveniently sorted by quality. Elevate your anime-watching experience now!
6-
// @icon https://www.google.com/s2/favicons?domain=animepahe.ru
6+
// @icon https://upload-os-bbs.hoyolab.com/upload/2024/06/03/136787680/795963af96e199b14106441a955376fa_6229706912856146042.jpg
77
// @author Jery
88
// @license MIT
99
// @match https://anitaku.*/*
@@ -49,6 +49,8 @@
4949
// @match https://anikai.to/*
5050
// @match https://yflix.to/watch/*
5151
// @match https://anime.uniquestream.net/*/*/*
52+
// @match https://www.fmovies.gd/*/*
53+
// @match https://*fmovies.*/*/*
5254
// @grant GM_registerMenuCommand
5355
// @grant GM_xmlhttpRequest
5456
// @grant GM.xmlHttpRequest
@@ -502,7 +504,7 @@ const Websites = [
502504
document.getElementById('AniLINK_Overlay')?.remove();
503505
}
504506
// Append the extract button
505-
const target = document.querySelector('.App + div > div > div + div > div > div > div > div + div > div + div');
507+
const target = document.querySelector('div[class^="_tagRow"] > div+div');
506508
if (target && !document.getElementById(id)) {
507509
// clearInterval(intervalId);
508510
const btn = document.createElement('button');
@@ -521,10 +523,10 @@ const Websites = [
521523
extractEpisodes: async function* (status) {
522524
status.text = 'Fetching episode list...';
523525
const animeTitle = (document.querySelector('p.title-romaji') || document.querySelector(this.animeTitle)).textContent;
524-
const malId = document.querySelector(`a[href*="/myanimelist.net/anime/"]`)?.href.split('/').pop();
525-
if (!malId) return showToast('MAL ID not found.');
526+
const anilistId = document.querySelector(`a[href*="/anilist.co/anime/"]`)?.href.split('/').pop();
527+
if (!anilistId) return showToast('anilistId not found.');
526528

527-
const res = await this._secureFetch(`${this.baseApiUrl}/episodes`, { query: { malId } });
529+
const res = await this._secureFetch(`${this.baseApiUrl}/episodes`, { query: { anilistId } });
528530
const eps = Object.entries(res.providers).reduce((a, [provider, { episodes }]) => (
529531
Object.entries(episodes).forEach(([type, list]) => list.forEach(ep => (a[ep.number] ??= []).push({ ...ep, provider, type }))), a
530532
), {});
@@ -538,7 +540,7 @@ const Websites = [
538540
const source = this._getLocalSourceName(provider, type);
539541
try {
540542
const sresJson = await this._secureFetch(`${this.baseApiUrl}/sources`, { query: { episodeId: id, provider, category: type } });
541-
const referer = provider == 'KICKASSANIME' ? 'https://kaa.to/' : provider == 'ZORO' ? 'https://megacloud.blog/' : provider == 'ANIMEPAHE' ? 'https://kwik.cx/' : location.href;
543+
const referer = "https://" + (provider == 'kaa' ? 'kaa.to' : provider == 'zoro' ? 'megacloud.blog' : provider == 'kiwi' ? 'kwik.cx' : provider == 'arc' ? 'anikai.to' : location.origin) + "/";
542544
links[source] = { stream: sresJson.streams[0].url, type: "m3u8", tracks: sresJson.tracks || sresJson.subtitles || [], referer };
543545
} catch (e) { showToast(`Failed to fetch ep-${epNum} from ${source}: ${e}`); }
544546
};
@@ -875,6 +877,42 @@ const Websites = [
875877
return !Object.keys(links).length ? null : new Episode(epNum, _$('.series-title').textContent, links, epElm.querySelector('img')?.src || '', epTitle);
876878
} catch (e) { showToast(`error ${e.status}: ${e.message}`); return null; } }));
877879
}
880+
},
881+
{
882+
name: 'FMovies',
883+
url: ['fmovies'],
884+
_chunkSize: 12,
885+
extractEpisodes: async function* (status) {
886+
const epElms = await applyEpisodeRangeFilter([..._$$('a[href^="/watch/"]')].slice(location.pathname.startsWith('/tv/')));
887+
for (let i = 0; i < epElms.length; i += this._chunkSize) {
888+
yield* yieldEpisodesFromPromises((epElms.slice(i, i + this._chunkSize)).map(async epElm => {
889+
const ifr = Object.assign(document.createElement('iframe'), { src: epElm.href, style: 'position:fixed;top:-9999px;left:-9999px;width:1px;height:1px;' });
890+
try {
891+
const epNum = epElm.querySelector('.w-8')?.textContent?.trim() || '0';
892+
status.text = `Extracting Ep ${epNum - epNum + 1} - ${epNum}...`;
893+
document.body.appendChild(ifr);
894+
let links = {}, attempts = 0;
895+
await new Promise((r, t) => {
896+
const check = () => {
897+
try {
898+
if (ifr.contentWindow?.availableServers?.length) {
899+
links = Object.fromEntries(ifr.contentWindow.availableServers.flatMap(s => s.source?.sources?.map(src => [`${s.name}-${src.quality || 'auto'}`, { stream: src.file || src.url, type: 'm3u8', tracks: (s.source.subtitles || []).map(t => ({ file: t.url, label: t.lang, kind: 'caption' })) }]) || []));
900+
if (Object.keys(links).length) { clearInterval(checkInt); r(); return; }
901+
}
902+
} catch (e) { }
903+
attempts++; if (attempts >= 40) { clearInterval(checkInt); t('timeout'); }
904+
};
905+
const checkInt = setInterval(check, 500);
906+
setTimeout(() => { clearInterval(checkInt); if (!Object.keys(links).length) t('timeout'); }, 20000);
907+
});
908+
if (!Object.keys(links).length) throw new Error('no sources');
909+
return new Episode(epNum, (_$('h1')?.textContent?.trim() || ''), links, epElm.querySelector('img')?.src, (epElm.querySelector('h4')?.textContent?.trim()));
910+
}
911+
catch (e) { return showToast(`: ${e}`); }
912+
finally { ifr.remove(); }
913+
}));
914+
}
915+
}
878916
}
879917
];
880918

0 commit comments

Comments
 (0)