From e15a81b3aaf93a8624822799b9bc397c12d7bfa5 Mon Sep 17 00:00:00 2001 From: Swakshan Date: Sat, 26 Apr 2025 13:18:10 +0530 Subject: [PATCH 1/5] anime(netmirror): rework popular, latest, search --- javascript/anime/src/all/netflixmirror.js | 99 +++++++++++------------ 1 file changed, 46 insertions(+), 53 deletions(-) diff --git a/javascript/anime/src/all/netflixmirror.js b/javascript/anime/src/all/netflixmirror.js index 89c92d5f..8b8c27ca 100644 --- a/javascript/anime/src/all/netflixmirror.js +++ b/javascript/anime/src/all/netflixmirror.js @@ -7,7 +7,7 @@ const mangayomiSources = [{ "iconUrl": "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/javascript/icon/all.netflixmirror.png", "typeSource": "single", "itemType": 1, - "version": "0.2.1", + "version": "0.3.0", "pkgPath": "anime/src/all/netflixmirror.js" }]; @@ -37,73 +37,66 @@ class DefaultExtension extends MProvider { return `https://imgcdn.media/pv/480/${id}.jpg` } + getCookie() { - async getCookie() { - const preferences = new SharedPreferences(); - let cookie = preferences.getString("cookie", ""); - var cookie_ts = parseInt(preferences.getString("cookie_ts", "0")); - var now_ts = parseInt(new Date().getTime() / 1000); + return `ott=${service};`; + } - // Cookie lasts for 24hrs but still checking for 12hrs - if (now_ts - cookie_ts > 60 * 60 * 12) { - const check = await new Client().get(this.getMobileBaseUrl() + `/mobile/home`, { "cookie": cookie }); - const hDocBody = new Document(check.body).selectFirst("body") + async request(slug, service) { + var service = service ?? this.getServiceDetails(); + var srv = "" + if (service === "pv") srv = "/" + service + var url = this.getTVBaseUrl() + "/tv" + srv + slug + return (await new Client().get(url)).body; + } - const addhash = hDocBody.attr("data-addhash"); - const data_time = hDocBody.attr("data-time"); - - var res = await new Client().post(`${this.getTVBaseUrl()}/tv/p.php`, { "cookie": "" }, { "hash": addhash }); - cookie = res.headers["set-cookie"]; - preferences.setString("cookie", cookie); - preferences.setString("cookie_ts", data_time); - } + async getHome(body) { var service = this.getServiceDetails(); + var list = [] + if (service === "nf") { + var body = await this.request("/home", service) + var elements = new Document(body).select("a.slider-item.boxart-container.open-modal.focusme"); - return `ott=${service}; ${cookie}`; - } - async request(url, cookie) { - cookie = cookie ?? await this.getCookie(); + elements.forEach(item => { + var id = item.attr("data-post") + if (id.length > 0) { + var imageUrl = this.getPoster(id, service) + // Having no name breaks the script so having "id" as name + var name = `\n${id}` + list.push({ name, imageUrl, link: id }) + } + }) + } else { + var body = await this.request("/homepage.php", service) + var elements = JSON.parse(body).post - var service = this.getServiceDetails(); - var slug = ""; - if (url == "/home") slug = ""; - else if (service == "pv") slug = "/pv"; - if (!(url.startsWith("https"))) { - url = this.getMobileBaseUrl() + "/mobile" + slug + url - } - - return (await new Client().get(url, { "cookie": cookie })).body; - } - async getPopular(page) { - return await this.getPages(await this.request("/home"), ".tray-container, #top10") - } - async getLatestUpdates(page) { - return await this.getPages(await this.request("/home"), ".inner-mob-tray-container") - } - async getPages(body, selector) { - var name_pref = this.getPreference("netmirror_pref_display_name_1"); - const elements = new Document(body).select(selector); - const cookie = await this.getCookie(); - const list = []; - for (const element of elements) { - const linkElement = element.selectFirst("article, .top10-post"); - const id = linkElement.selectFirst("a").attr("data-post"); - if (id.length > 0) { - const imageUrl = linkElement.selectFirst(".card-img-container img, .top10-img img").attr("data-src"); - var name = name_pref ? JSON.parse(await this.request(`/post.php?id=${id}`, cookie)).title : `\n${id}` - - list.push({ name, imageUrl, link: id }); - } + elements.forEach(item => { + var ids = item.ids + ids.split(",").forEach(id => { + var imageUrl = this.getPoster(id, service) + // Having no name breaks the script so having "id" as name + var name = `\n${id}` + list.push({ name, imageUrl, link: id }) + }) + }) } return { list: list, hasNextPage: false } } + + async getPopular(page) { + return await this.getHome() + } + async getLatestUpdates(page) { + return await this.getHome() + } + async search(query, page, filters) { var service = this.getServiceDetails(); - const data = JSON.parse(await this.request(`/search.php?s=${query}`)); + const data = JSON.parse(await this.request(`/search.php?s=${query}`,service)); const list = []; data.searchResult.map(async (res) => { const id = res.id; From 38bec2b137dc3a697c8d423352b7000e6095c64c Mon Sep 17 00:00:00 2001 From: Swakshan Date: Sat, 26 Apr 2025 14:10:16 +0530 Subject: [PATCH 2/5] anime(netmirror): rework details --- javascript/anime/src/all/netflixmirror.js | 95 +++++++++++++++-------- 1 file changed, 61 insertions(+), 34 deletions(-) diff --git a/javascript/anime/src/all/netflixmirror.js b/javascript/anime/src/all/netflixmirror.js index 8b8c27ca..f37392b7 100644 --- a/javascript/anime/src/all/netflixmirror.js +++ b/javascript/anime/src/all/netflixmirror.js @@ -7,7 +7,7 @@ const mangayomiSources = [{ "iconUrl": "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/javascript/icon/all.netflixmirror.png", "typeSource": "single", "itemType": 1, - "version": "0.3.0", + "version": "0.3.1", "pkgPath": "anime/src/all/netflixmirror.js" }]; @@ -37,17 +37,39 @@ class DefaultExtension extends MProvider { return `https://imgcdn.media/pv/480/${id}.jpg` } - getCookie() { + async getCookie(service) { + const preferences = new SharedPreferences(); + let cookie = preferences.getString("cookie", ""); + var cookie_ts = parseInt(preferences.getString("cookie_ts", "0")); + var now_ts = parseInt(new Date().getTime() / 1000); - return `ott=${service};`; + // Cookie lasts for 24hrs but still checking for 12hrs + if (now_ts - cookie_ts > 60 * 60 * 12) { + const check = await new Client().get(this.getMobileBaseUrl() + `/mobile/home`, { "cookie": cookie }); + const hDocBody = new Document(check.body).selectFirst("body") + + const addhash = hDocBody.attr("data-addhash"); + const data_time = hDocBody.attr("data-time"); + + var res = await new Client().post(`${this.getTVBaseUrl()}/tv/p.php`, { "cookie": "" }, { "hash": addhash }); + cookie = res.headers["set-cookie"]; + preferences.setString("cookie", cookie); + preferences.setString("cookie_ts", data_time); + } + + service = service ?? this.getServiceDetails(); + + return `ott=${service}; ${cookie}`; } - async request(slug, service) { + async request(slug, service, cookie = {}) { var service = service ?? this.getServiceDetails(); + var cookie = cookie ?? this.getCookie(); + var srv = "" if (service === "pv") srv = "/" + service var url = this.getTVBaseUrl() + "/tv" + srv + slug - return (await new Client().get(url)).body; + return (await new Client().get(url, { "cookie": cookie })).body; } @@ -96,7 +118,7 @@ class DefaultExtension extends MProvider { async search(query, page, filters) { var service = this.getServiceDetails(); - const data = JSON.parse(await this.request(`/search.php?s=${query}`,service)); + const data = JSON.parse(await this.request(`/search.php?s=${query}`, service)); const list = []; data.searchResult.map(async (res) => { const id = res.id; @@ -108,57 +130,62 @@ class DefaultExtension extends MProvider { hasNextPage: false } } + async getDetail(url) { var service = this.getServiceDetails(); - const cookie = await this.getCookie(); + var cookie = await this.getCookie(service); + var linkSlug = "https://netflix.com/title/" + if (service === "pv") linkSlug = `https://www.primevideo.com/detail/` - const data = JSON.parse(await this.request(`/post.php?id=${url}`, cookie)); + // Check needed while refreshing existing data + var vidId = url + if (url.includes(linkSlug)) vidId = url.replaceAll(linkSlug, '') + + const data = JSON.parse(await this.request(`/post.php?id=${vidId}`)); const name = data.title; const genre = [data.ua, ...(data.genre || '').split(',').map(g => g.trim())]; const description = data.desc; let episodes = []; - if (data.episodes[0] === null) { - episodes.push({ name, url: url }); - } else { - episodes = data.episodes.map(ep => ({ - name: `${ep.s.replace('S', 'Season ')} ${ep.ep.replace('E', 'Episode ')} : ${ep.t}`, - url: ep.id - })); - } - if (data.nextPageShow === 1) { - const eps = await this.getEpisodes(name, url, data.nextPageSeason, 2, cookie); - episodes.push(...eps); - } - episodes.reverse(); - if (data.season && data.season.length > 1) { + + var seasons = data.season + if (seasons) { let newEpisodes = []; - const seasonsToProcess = data.season.slice(0, -1); - await Promise.all(seasonsToProcess.map(async (season) => { - const eps = await this.getEpisodes(name, url, season.id, 1, cookie); + await Promise.all(seasons.map(async (season) => { + const eps = await this.getEpisodes(name, vidId, season.id, 1, service, cookie); newEpisodes.push(...eps); })); - newEpisodes.reverse(); episodes.push(...newEpisodes); + } else { + // For movies aka if there are no seasons and episodes + episodes.push({ + name: `Movie`, + url: vidId + }); } - var service = this.getServiceDetails(); - var link = `https://netflix.com/title/${url}` - if (service === "pv") link = `https://www.primevideo.com/detail/${url}` + var link = `${linkSlug}${vidId}` return { - name, imageUrl: this.getPoster(url, service), link, description, status: 1, genre, episodes + name, imageUrl: this.getPoster(vidId, service), link, description, status: 1, genre, episodes }; } - async getEpisodes(name, eid, sid, page, cookie) { + + async getEpisodes(name, eid, sid, page, service, cookie) { const episodes = []; let pg = page; while (true) { try { - const data = JSON.parse(await this.request(`/episodes.php?s=${sid}&series=${eid}&page=${pg}`, cookie)); + const data = JSON.parse(await this.request(`/episodes.php?s=${sid}&series=${eid}&page=${pg}`, service, cookie)); data.episodes?.forEach(ep => { + var season = ep.s.replace('S', 'Season ') + var epNum = ep.ep.replace("E","") + var epText = `Episode ${epNum}` + var title = ep.t + title = title == epNum ? title : `${epText}: ${title}` + episodes.push({ - name: `${ep.s.replace('S', 'Season ')} ${ep.ep.replace('E', 'Episode ')} : ${ep.t}`, + name: `${season} ${title}`, url: ep.id }); }); @@ -170,7 +197,7 @@ class DefaultExtension extends MProvider { } } - return episodes; + return episodes.reverse(); } // Sorts streams based on user preference. From 102b4faa7b1d57d383ca482c9059d55077137bd5 Mon Sep 17 00:00:00 2001 From: Swakshan Date: Sat, 26 Apr 2025 14:42:11 +0530 Subject: [PATCH 3/5] anime(netmirror): rework stream extraction --- javascript/anime/src/all/netflixmirror.js | 223 +++++++++------------- 1 file changed, 94 insertions(+), 129 deletions(-) diff --git a/javascript/anime/src/all/netflixmirror.js b/javascript/anime/src/all/netflixmirror.js index f37392b7..852e7f91 100644 --- a/javascript/anime/src/all/netflixmirror.js +++ b/javascript/anime/src/all/netflixmirror.js @@ -7,7 +7,7 @@ const mangayomiSources = [{ "iconUrl": "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/javascript/icon/all.netflixmirror.png", "typeSource": "single", "itemType": 1, - "version": "0.3.1", + "version": "0.3.2", "pkgPath": "anime/src/all/netflixmirror.js" }]; @@ -18,10 +18,6 @@ class DefaultExtension extends MProvider { return preferences.get(key); } - getMobileBaseUrl() { - return this.getPreference("netmirror_override_mobile_base_url"); - } - getTVBaseUrl() { return this.getPreference("netmirror_override_tv_base_url"); } @@ -45,13 +41,14 @@ class DefaultExtension extends MProvider { // Cookie lasts for 24hrs but still checking for 12hrs if (now_ts - cookie_ts > 60 * 60 * 12) { - const check = await new Client().get(this.getMobileBaseUrl() + `/mobile/home`, { "cookie": cookie }); + var baseUrl = this.getTVBaseUrl() + const check = await new Client().get(baseUrl + `/mobile/home`, { "cookie": cookie }); const hDocBody = new Document(check.body).selectFirst("body") const addhash = hDocBody.attr("data-addhash"); const data_time = hDocBody.attr("data-time"); - var res = await new Client().post(`${this.getTVBaseUrl()}/tv/p.php`, { "cookie": "" }, { "hash": addhash }); + var res = await new Client().post(`${baseUrl}/tv/p.php`, { "cookie": "" }, { "hash": addhash }); cookie = res.headers["set-cookie"]; preferences.setString("cookie", cookie); preferences.setString("cookie_ts", data_time); @@ -62,9 +59,9 @@ class DefaultExtension extends MProvider { return `ott=${service}; ${cookie}`; } - async request(slug, service, cookie = {}) { + async request(slug, service=null, cookie = null) { var service = service ?? this.getServiceDetails(); - var cookie = cookie ?? this.getCookie(); + var cookie = cookie ?? await this.getCookie(); var srv = "" if (service === "pv") srv = "/" + service @@ -179,7 +176,7 @@ class DefaultExtension extends MProvider { data.episodes?.forEach(ep => { var season = ep.s.replace('S', 'Season ') - var epNum = ep.ep.replace("E","") + var epNum = ep.ep.replace("E", "") var epText = `Episode ${epNum}` var title = ep.t title = title == epNum ? title : `${epText}: ${title}` @@ -221,145 +218,113 @@ class DefaultExtension extends MProvider { } async getVideoList(url) { - var slug = "" - var src = this.getPreference("netmirror_pref_stream_extraction"); - var service = this.getServiceDetails(); - // prime extracton works only in mobile - if (service == "pv") { - slug = "/pv" - src = "mobile" - } - - var device = "/mobile" - if (src == 'tv') device = "/tv"; - - var baseUrl = src === 'tv' ? this.getTVBaseUrl() : this.getMobileBaseUrl() - url = baseUrl + device + slug + `/playlist.php?id=${url}` + var baseUrl = this.getTVBaseUrl() + var url = `/playlist.php?id=${url}` const data = JSON.parse(await this.request(url)); + + let videoList = []; let subtitles = []; let audios = []; - for (const playlist of data) { - var source = playlist.sources[0] - var link = baseUrl + source.file; - var headers = - { - 'Origin': baseUrl, - 'Referer': `${baseUrl}/` - }; + var playlist = data[0] + var source = playlist.sources[0] - var resp = await new Client().get(link, headers); + var link = baseUrl + source.file; + var headers = + { + 'Origin': baseUrl, + 'Referer': `${baseUrl}/` + }; - if (resp.statusCode === 200) { - const masterPlaylist = resp.body; + // Auto + videoList.push({ url: link, quality: "Auto", "originalUrl": link, headers }); - if (masterPlaylist.indexOf("#EXT-X-STREAM-INF:") > 1) { + var resp = await new Client().get(link, headers); - masterPlaylist.substringAfter('#EXT-X-MEDIA:').split('#EXT-X-MEDIA:').forEach(it => { - if (it.includes('TYPE=AUDIO')) { - const audioInfo = it.substringAfter('TYPE=AUDIO').substringBefore('\n'); - const language = audioInfo.substringAfter('NAME="').substringBefore('"'); - const url = audioInfo.substringAfter('URI="').substringBefore('"'); - audios.push({ file: url, label: language }); - } + if (resp.statusCode === 200) { + const masterPlaylist = resp.body; + + if (masterPlaylist.indexOf("#EXT-X-STREAM-INF:") > 1) { + + masterPlaylist.substringAfter('#EXT-X-MEDIA:').split('#EXT-X-MEDIA:').forEach(it => { + if (it.includes('TYPE=AUDIO')) { + const audioInfo = it.substringAfter('TYPE=AUDIO').substringBefore('\n'); + const language = audioInfo.substringAfter('NAME="').substringBefore('"'); + const url = audioInfo.substringAfter('URI="').substringBefore('"'); + audios.push({ file: url, label: language }); + } + }); + + + masterPlaylist.substringAfter('#EXT-X-STREAM-INF:').split('#EXT-X-STREAM-INF:').forEach(it => { + var quality = `${it.substringAfter('RESOLUTION=').substringAfter('x').substringBefore(',')}p`; + let videoUrl = it.substringAfter('\n').substringBefore('\n'); + + if (!videoUrl.startsWith('http')) { + videoUrl = resp.request.url.substringBeforeLast('/') + `/${videoUrl}`; + } + var headers = + { + 'Host': videoUrl.match(/^(?:https?:\/\/)?(?:www\.)?([^\/]+)/)[1], + 'Origin': baseUrl, + 'Referer': `${baseUrl}/` + }; + videoList.push({ url: videoUrl, quality, originalUrl: videoUrl, headers }); + + }); + } + + + if ("tracks" in playlist) { + playlist.tracks.filter(track => track.kind === 'captions').forEach(track => { + var subUrl = track.file + subUrl = subUrl.startsWith("//") ? `https:${subUrl}` : subUrl; + + subtitles.push({ + label: track.label, + file: subUrl }); - - - masterPlaylist.substringAfter('#EXT-X-STREAM-INF:').split('#EXT-X-STREAM-INF:').forEach(it => { - var quality = `${it.substringAfter('RESOLUTION=').substringAfter('x').substringBefore(',')}p (${source.label})`; - let videoUrl = it.substringAfter('\n').substringBefore('\n'); - - if (!videoUrl.startsWith('http')) { - videoUrl = resp.request.url.substringBeforeLast('/') + `/${videoUrl}`; - } - var headers = - { - 'Host': videoUrl.match(/^(?:https?:\/\/)?(?:www\.)?([^\/]+)/)[1], - 'Origin': baseUrl, - 'Referer': `${baseUrl}/` - }; - videoList.push({ url: videoUrl, quality, originalUrl: videoUrl, headers }); - - }); - } - - - if ("tracks" in playlist) { - playlist.tracks.filter(track => track.kind === 'captions').forEach(track => { - var subUrl = track.file - subUrl = subUrl.startsWith("//") ? `https:${subUrl}` : subUrl; - - subtitles.push({ - label: track.label, - file: subUrl - }); - }); - } + }); } } + videoList[0].audios = audios; videoList[0].subtitles = subtitles; return this.sortStreams(videoList); } getSourcePreferences() { - return [ - { - key: "netmirror_override_mobile_base_url", - editTextPreference: { - title: "Override mobile base url", - summary: "", - value: "https://netfree.cc", - dialogTitle: "Override base url", - dialogMessage: "", - } - }, { - key: "netmirror_override_tv_base_url", - editTextPreference: { - title: "Override tv base url", - summary: "", - value: "https://pcmirror.cc", - dialogTitle: "Override base url", - dialogMessage: "", - } - }, { - key: 'netmirror_pref_video_resolution', - listPreference: { - title: 'Preferred video resolution', - summary: '', - valueIndex: 0, - entries: ["1080p", "720p", "480p"], - entryValues: ["1080", "720", "480"] - } - }, { - "key": "netmirror_pref_display_name_1", - "switchPreferenceCompat": { - "title": "Display media name on home page", - "summary": "Homepage loads faster by not calling details API", - "value": true - } - }, { - key: 'netmirror_pref_service', - listPreference: { - title: 'Preferred OTT service', - summary: '', - valueIndex: 0, - entries: ["Net mirror", "Prime mirror"], - entryValues: ["nf", "pv",] - } - }, { - key: 'netmirror_pref_stream_extraction', - listPreference: { - title: 'Preferred stream extraction source', - summary: 'Extract stream from which source (if one source fails choose another)', - valueIndex: 0, - entries: ["TV", "Mobile"], - entryValues: ["tv", "mobile"] - } - }, + return [{ + key: "netmirror_override_tv_base_url", + editTextPreference: { + title: "Override tv base url", + summary: "", + value: "https://pcmirror.cc", + dialogTitle: "Override base url", + dialogMessage: "", + } + }, { + key: 'netmirror_pref_service', + listPreference: { + title: 'Preferred OTT service', + summary: '', + valueIndex: 0, + entries: ["Net mirror", "Prime mirror"], + entryValues: ["nf", "pv",] + } + }, { + key: 'netmirror_pref_video_resolution', + listPreference: { + title: 'Preferred video resolution', + summary: '', + valueIndex: 0, + entries: ["1080p", "720p", "480p"], + entryValues: ["1080", "720", "480"] + } + } ]; } From ec55adeb1fb9bfe812855e8dc7dd9fd3ce01e3af Mon Sep 17 00:00:00 2001 From: Swakshan Date: Sat, 26 Apr 2025 16:03:27 +0530 Subject: [PATCH 4/5] anime(netmirror): minor fixes --- javascript/anime/src/all/netflixmirror.js | 30 +++++++++++------------ 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/javascript/anime/src/all/netflixmirror.js b/javascript/anime/src/all/netflixmirror.js index 852e7f91..8391054d 100644 --- a/javascript/anime/src/all/netflixmirror.js +++ b/javascript/anime/src/all/netflixmirror.js @@ -2,17 +2,22 @@ const mangayomiSources = [{ "name": "NetMirror", "id": 446414301, "lang": "all", - "baseUrl": "https://iosmirror.cc", - "apiUrl": "https://pcmirror.cc", + "baseUrl": "https://netfree2.cc", + "apiUrl": "https://netfree2.cc", "iconUrl": "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/javascript/icon/all.netflixmirror.png", "typeSource": "single", "itemType": 1, - "version": "0.3.2", + "version": "0.3.3", "pkgPath": "anime/src/all/netflixmirror.js" }]; class DefaultExtension extends MProvider { + constructor(){ + super(); + this.client = new Client(); + } + getPreference(key) { const preferences = new SharedPreferences(); return preferences.get(key); @@ -42,13 +47,13 @@ class DefaultExtension extends MProvider { // Cookie lasts for 24hrs but still checking for 12hrs if (now_ts - cookie_ts > 60 * 60 * 12) { var baseUrl = this.getTVBaseUrl() - const check = await new Client().get(baseUrl + `/mobile/home`, { "cookie": cookie }); + const check = await this.client.get(baseUrl + `/mobile/home`, { "cookie": cookie }); const hDocBody = new Document(check.body).selectFirst("body") const addhash = hDocBody.attr("data-addhash"); const data_time = hDocBody.attr("data-time"); - var res = await new Client().post(`${baseUrl}/tv/p.php`, { "cookie": "" }, { "hash": addhash }); + var res = await this.client.post(`${baseUrl}/tv/p.php`, { "cookie": "" }, { "hash": addhash }); cookie = res.headers["set-cookie"]; preferences.setString("cookie", cookie); preferences.setString("cookie_ts", data_time); @@ -66,7 +71,7 @@ class DefaultExtension extends MProvider { var srv = "" if (service === "pv") srv = "/" + service var url = this.getTVBaseUrl() + "/tv" + srv + slug - return (await new Client().get(url, { "cookie": cookie })).body; + return (await this.client.get(url, { "cookie": cookie })).body; } @@ -179,7 +184,7 @@ class DefaultExtension extends MProvider { var epNum = ep.ep.replace("E", "") var epText = `Episode ${epNum}` var title = ep.t - title = title == epNum ? title : `${epText}: ${title}` + title = title == epText ? title : `${epText}: ${title}` episodes.push({ name: `${season} ${title}`, @@ -240,7 +245,7 @@ class DefaultExtension extends MProvider { // Auto videoList.push({ url: link, quality: "Auto", "originalUrl": link, headers }); - var resp = await new Client().get(link, headers); + var resp = await this.client.get(link, headers); if (resp.statusCode === 200) { const masterPlaylist = resp.body; @@ -264,12 +269,7 @@ class DefaultExtension extends MProvider { if (!videoUrl.startsWith('http')) { videoUrl = resp.request.url.substringBeforeLast('/') + `/${videoUrl}`; } - var headers = - { - 'Host': videoUrl.match(/^(?:https?:\/\/)?(?:www\.)?([^\/]+)/)[1], - 'Origin': baseUrl, - 'Referer': `${baseUrl}/` - }; + headers['Host'] = videoUrl.match(/^(?:https?:\/\/)?(?:www\.)?([^\/]+)/)[1] videoList.push({ url: videoUrl, quality, originalUrl: videoUrl, headers }); }); @@ -302,7 +302,7 @@ class DefaultExtension extends MProvider { editTextPreference: { title: "Override tv base url", summary: "", - value: "https://pcmirror.cc", + value: "https://netfree2.cc", dialogTitle: "Override base url", dialogMessage: "", } From 9e71b33724d94b4c462fff570d47b6ec0af2bc20 Mon Sep 17 00:00:00 2001 From: Swakshan Date: Sat, 26 Apr 2025 16:39:50 +0530 Subject: [PATCH 5/5] anime(netmirror): fix subtitles --- javascript/anime/src/all/netflixmirror.js | 26 ++++++++++++----------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/javascript/anime/src/all/netflixmirror.js b/javascript/anime/src/all/netflixmirror.js index 8391054d..b444187e 100644 --- a/javascript/anime/src/all/netflixmirror.js +++ b/javascript/anime/src/all/netflixmirror.js @@ -7,13 +7,13 @@ const mangayomiSources = [{ "iconUrl": "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/javascript/icon/all.netflixmirror.png", "typeSource": "single", "itemType": 1, - "version": "0.3.3", + "version": "0.3.4", "pkgPath": "anime/src/all/netflixmirror.js" }]; class DefaultExtension extends MProvider { - constructor(){ + constructor() { super(); this.client = new Client(); } @@ -64,7 +64,7 @@ class DefaultExtension extends MProvider { return `ott=${service}; ${cookie}`; } - async request(slug, service=null, cookie = null) { + async request(slug, service = null, cookie = null) { var service = service ?? this.getServiceDetails(); var cookie = cookie ?? await this.getCookie(); @@ -277,15 +277,17 @@ class DefaultExtension extends MProvider { if ("tracks" in playlist) { - playlist.tracks.filter(track => track.kind === 'captions').forEach(track => { - var subUrl = track.file - subUrl = subUrl.startsWith("//") ? `https:${subUrl}` : subUrl; - - subtitles.push({ - label: track.label, - file: subUrl - }); - }); + await Promise.all(playlist.tracks.map(async (track) => { + if (track.kind == 'captions') { + var subUrl = track.file + subUrl = subUrl.startsWith("//") ? `https:${subUrl}` : subUrl; + var subText = await this.client.get(subUrl) + subtitles.push({ + label: track.label, + file: subText.body + }); + } + })); } }