From fa3efac2fdc108b28e65a48ebfb005ab6b6d0f80 Mon Sep 17 00:00:00 2001 From: Swakshan Date: Fri, 20 Dec 2024 13:10:29 +0530 Subject: [PATCH 1/8] extension(Autoembed): Added movies support --- javascript/anime/src/all/autoembed.js | 162 ++++++++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 javascript/anime/src/all/autoembed.js diff --git a/javascript/anime/src/all/autoembed.js b/javascript/anime/src/all/autoembed.js new file mode 100644 index 00000000..716cf090 --- /dev/null +++ b/javascript/anime/src/all/autoembed.js @@ -0,0 +1,162 @@ +const mangayomiSources = [{ + "name": "Autoembed", + "lang": "all", + "baseUrl": "https://autoembed.cc", + "apiUrl": "https://tom.autoembed.cc", + "iconUrl": "https://www.google.com/s2/favicons?sz=64&domain=https://autoembed.cc/", + "typeSource": "multi", + "isManga": false, + "version": "0.0.1", + "dateFormat": "", + "dateFormatLocale": "", + "pkgPath": "" +}]; + +class DefaultExtension extends MProvider { + tmdb_api = "https://94c8cb9f702d-tmdb-addon.baby-beamup.club"; + getHeaders(url) { + return { + Referer: this.source.apiUrl + } + } + + async tmdbSearchRequest(slug, page = 1) { + var skip = (page - 1) * 20; + const api = `${this.tmdb_api}/${slug}skip=${skip}.json` + const response = await new Client().get(api); + const body = JSON.parse(response.body); + return body; + } + + async getSearchItems(body) { + var items = []; + var results = body.metas; + for (let i in results) { + var result = results[i]; + var id = result.id + var media_type = result.type; + items.push({ + name: result.name, + imageUrl: result.poster, + link: `${media_type}/${id}`, + description: result.description, + genre: result.genre + }); + } + var hasNextPage = true; + return { + "list": items, + hasNextPage + }; + } + + async getPopular(page) { + const preferences = new SharedPreferences(); + var media_type = preferences.get("pref_popular_page"); + var body = await this.tmdbSearchRequest(`catalog/${media_type}/tmdb.popular/`, page); + return this.getSearchItems(body); + } + get supportsLatest() { + throw new Error("supportsLatest not implemented"); + } + async getLatestUpdates(page) { + throw new Error("getLatestUpdates not implemented"); + } + async search(query, page, filters) { + throw new Error("search not implemented"); + } + async getDetail(url) { + var parts = url.split("/"); + var media_type = parts[0]; + var tmdbId = parts[1]; + var api = `${this.tmdb_api}/meta/${media_type}/${tmdbId}.json` + const response = await new Client().get(api); + const body = JSON.parse(response.body); + var result = body.meta; + + var release = result.released ? new Date(result.released) : Date.now(); + + var item = { + name: result.name, + imageUrl: result.poster, + link: `${media_type}/${tmdbId}`, + description: result.description, + genre: result.genre, + }; + var chaps = []; + + chaps.push({ + name: "Movie", + url: `${media_type}/${result.imdb_id}`, + dateUpload: release.valueOf().toString(), + }) + + item.chapters = chaps; + + return item; + } + + async extractStreams(url) { + const response = await new Client().get(url); + const body = response.body; + const lines = body.split('\n'); + var streams = []; + + for (let i = 0; i < lines.length; i++) { + if (lines[i].startsWith('#EXT-X-STREAM-INF:')) { + const resolution = lines[i].match(/RESOLUTION=(\d+x\d+)/)[1]; + const m3u8Url = lines[i + 1].trim(); + + streams.push({ + url: m3u8Url, + originalUrl: m3u8Url, + quality: resolution, + }); + } + } + return streams; + } + + // For anime episode video list + async getVideoList(url) { + var parts = url.split("/"); + var media_type = parts[0]; + var imdbId = parts[1]; + var api = `${this.source.apiUrl}/api/getVideoSource?type=${media_type}&id=${imdbId}` + const response = await new Client().get(api, this.getHeaders()); + const body = JSON.parse(response.body); + var link = body.videoSource + var subtitles = body.subtitles + var streams = await this.extractStreams(link); + streams.push({ + url: link, + originalUrl: link, + quality: "Auto", + subtitles: subtitles, + }); + + return streams; + } + // For manga chapter pages + async getPageList() { + throw new Error("getPageList not implemented"); + } + getFilterList() { + throw new Error("getSourcePreferences not implemented"); + } + + getSourcePreferences() { + return [{ + key: 'pref_popular_page', + listPreference: { + title: 'Preferred popular page', + summary: '', + valueIndex: 0, + entries: ["Movies", "TV Shows"], + entryValues: ["movie", "tv"] + } + }, + + ]; + } +} \ No newline at end of file From d696b62b91ef06fbb5cf5ce94497cb4eba97e27d Mon Sep 17 00:00:00 2001 From: Swakshan Date: Fri, 20 Dec 2024 17:22:18 +0530 Subject: [PATCH 2/8] extension(Autoembed): Added series support --- javascript/anime/src/all/autoembed.js | 74 ++++++++++++++++++++------- 1 file changed, 55 insertions(+), 19 deletions(-) diff --git a/javascript/anime/src/all/autoembed.js b/javascript/anime/src/all/autoembed.js index 716cf090..a65d8226 100644 --- a/javascript/anime/src/all/autoembed.js +++ b/javascript/anime/src/all/autoembed.js @@ -6,7 +6,7 @@ const mangayomiSources = [{ "iconUrl": "https://www.google.com/s2/favicons?sz=64&domain=https://autoembed.cc/", "typeSource": "multi", "isManga": false, - "version": "0.0.1", + "version": "0.0.2", "dateFormat": "", "dateFormatLocale": "", "pkgPath": "" @@ -68,34 +68,64 @@ class DefaultExtension extends MProvider { async getDetail(url) { var parts = url.split("/"); var media_type = parts[0]; - var tmdbId = parts[1]; - var api = `${this.tmdb_api}/meta/${media_type}/${tmdbId}.json` + var id = parts[1]; + var api = `${this.tmdb_api}/meta/${media_type}/${id}.json` const response = await new Client().get(api); const body = JSON.parse(response.body); var result = body.meta; - - var release = result.released ? new Date(result.released) : Date.now(); + + var tmdb_id = id.substring(5, ) + var imdb_id = result.imdb_id + var dateNow = Date.now().valueOf(); + var release = result.released ? new Date(result.released).valueOf() : dateNow + var chaps = []; var item = { name: result.name, imageUrl: result.poster, - link: `${media_type}/${tmdbId}`, + link: `https://imdb.com/title/${imdb_id}`, description: result.description, genre: result.genre, }; - var chaps = []; - chaps.push({ - name: "Movie", - url: `${media_type}/${result.imdb_id}`, - dateUpload: release.valueOf().toString(), - }) + if (media_type == "series") { + + var videos = result.videos + for (var i in videos) { + var video = videos[i]; + var seasonNum = video.season; + + if (!seasonNum) continue; + + var episodeNum = video.episode + + var eplink = `tv||${tmdb_id}/${seasonNum}/${episodeNum}` + release = video.released ? new Date(video.released).valueOf() : dateNow + + + if (release < dateNow) { + var name = video.name + chaps.push({ + name: name, + url: eplink, + dateUpload: release.toString(), + }) + } + } + } else { + if (release < dateNow) { + chaps.push({ + name: "Movie", + url: `${media_type}||${tmdb_id}`, + dateUpload: release.toString(), + }) + } + } item.chapters = chaps; return item; } - async extractStreams(url) { const response = await new Client().get(url); const body = response.body; @@ -113,21 +143,27 @@ class DefaultExtension extends MProvider { quality: resolution, }); } - } + } return streams; } // For anime episode video list async getVideoList(url) { - var parts = url.split("/"); + var parts = url.split("||"); var media_type = parts[0]; - var imdbId = parts[1]; - var api = `${this.source.apiUrl}/api/getVideoSource?type=${media_type}&id=${imdbId}` + var id = parts[1]; + var api = `${this.source.apiUrl}/api/getVideoSource?type=${media_type}&id=${id}` const response = await new Client().get(api, this.getHeaders()); const body = JSON.parse(response.body); + + if (response.statusCode == 404) { + throw new Error("Video unavailable"); + + } var link = body.videoSource + var subtitles = body.subtitles - var streams = await this.extractStreams(link); + var streams = await this.extractStreams(link); streams.push({ url: link, originalUrl: link, @@ -153,7 +189,7 @@ class DefaultExtension extends MProvider { summary: '', valueIndex: 0, entries: ["Movies", "TV Shows"], - entryValues: ["movie", "tv"] + entryValues: ["movie", "series"] } }, From b301de92865d1536531b7f04d6404888cf7760bc Mon Sep 17 00:00:00 2001 From: Swakshan Date: Fri, 20 Dec 2024 21:56:08 +0530 Subject: [PATCH 3/8] extension(Autoembed): Updated logic --- javascript/anime/src/all/autoembed.js | 55 ++++++++++++++------------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/javascript/anime/src/all/autoembed.js b/javascript/anime/src/all/autoembed.js index a65d8226..431f606b 100644 --- a/javascript/anime/src/all/autoembed.js +++ b/javascript/anime/src/all/autoembed.js @@ -6,7 +6,7 @@ const mangayomiSources = [{ "iconUrl": "https://www.google.com/s2/favicons?sz=64&domain=https://autoembed.cc/", "typeSource": "multi", "isManga": false, - "version": "0.0.2", + "version": "0.0.3", "dateFormat": "", "dateFormatLocale": "", "pkgPath": "" @@ -20,11 +20,15 @@ class DefaultExtension extends MProvider { } } - async tmdbSearchRequest(slug, page = 1) { - var skip = (page - 1) * 20; - const api = `${this.tmdb_api}/${slug}skip=${skip}.json` - const response = await new Client().get(api); - const body = JSON.parse(response.body); + async getPreference(key) { + const preferences = new SharedPreferences(); + return preferences.get(key); + } + + async tmdbRequest(slug) { + var api = `${this.tmdb_api}/${slug}` + var response = await new Client().get(api); + var body = JSON.parse(response.body); return body; } @@ -43,18 +47,30 @@ class DefaultExtension extends MProvider { genre: result.genre }); } + return items; + + } + async getSearchInfo(slug) { + + var body = await this.tmdbRequest(`catalog/movie/${slug}`); + var popMovie = await this.getSearchItems(body); + + + body = await this.tmdbRequest(`catalog/series/${slug}`); + var popSeries = await this.getSearchItems(body); + var hasNextPage = true; return { - "list": items, + list: [...popMovie, ...popSeries], hasNextPage }; + } + async getPopular(page) { - const preferences = new SharedPreferences(); - var media_type = preferences.get("pref_popular_page"); - var body = await this.tmdbSearchRequest(`catalog/${media_type}/tmdb.popular/`, page); - return this.getSearchItems(body); + var skip = (page - 1) * 20; + return await this.getSearchInfo(`tmdb.popular/skip=${skip}.json`); } get supportsLatest() { throw new Error("supportsLatest not implemented"); @@ -69,11 +85,9 @@ class DefaultExtension extends MProvider { var parts = url.split("/"); var media_type = parts[0]; var id = parts[1]; - var api = `${this.tmdb_api}/meta/${media_type}/${id}.json` - const response = await new Client().get(api); - const body = JSON.parse(response.body); + var body = await this.tmdbRequest(`meta/${media_type}/${id}.json`) var result = body.meta; - + var tmdb_id = id.substring(5, ) var imdb_id = result.imdb_id var dateNow = Date.now().valueOf(); @@ -182,17 +196,6 @@ class DefaultExtension extends MProvider { } getSourcePreferences() { - return [{ - key: 'pref_popular_page', - listPreference: { - title: 'Preferred popular page', - summary: '', - valueIndex: 0, - entries: ["Movies", "TV Shows"], - entryValues: ["movie", "series"] - } - }, - ]; } } \ No newline at end of file From 497c5625578fd0f0a296ffe775303df1275df7f0 Mon Sep 17 00:00:00 2001 From: Swakshan Date: Fri, 20 Dec 2024 22:16:17 +0530 Subject: [PATCH 4/8] extension(Autoembed): Added latest page --- javascript/anime/src/all/autoembed.js | 33 +++++++++++++++++++-------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/javascript/anime/src/all/autoembed.js b/javascript/anime/src/all/autoembed.js index 431f606b..3f3c85e5 100644 --- a/javascript/anime/src/all/autoembed.js +++ b/javascript/anime/src/all/autoembed.js @@ -6,14 +6,14 @@ const mangayomiSources = [{ "iconUrl": "https://www.google.com/s2/favicons?sz=64&domain=https://autoembed.cc/", "typeSource": "multi", "isManga": false, - "version": "0.0.3", + "version": "0.0.4", "dateFormat": "", "dateFormatLocale": "", "pkgPath": "" }]; class DefaultExtension extends MProvider { - tmdb_api = "https://94c8cb9f702d-tmdb-addon.baby-beamup.club"; + getHeaders(url) { return { Referer: this.source.apiUrl @@ -26,7 +26,7 @@ class DefaultExtension extends MProvider { } async tmdbRequest(slug) { - var api = `${this.tmdb_api}/${slug}` + var api = `https://94c8cb9f702d-tmdb-addon.baby-beamup.club/${slug}` var response = await new Client().get(api); var body = JSON.parse(response.body); return body; @@ -76,7 +76,9 @@ class DefaultExtension extends MProvider { throw new Error("supportsLatest not implemented"); } async getLatestUpdates(page) { - throw new Error("getLatestUpdates not implemented"); + var trend_window = await this.getPreference("pref_latest_time_window"); + var skip = (page - 1) * 20; + return await this.getSearchInfo(`tmdb.trending/genre=${trend_window}&skip=${skip}.json`); } async search(query, page, filters) { throw new Error("search not implemented"); @@ -87,7 +89,7 @@ class DefaultExtension extends MProvider { var id = parts[1]; var body = await this.tmdbRequest(`meta/${media_type}/${id}.json`) var result = body.meta; - + var tmdb_id = id.substring(5, ) var imdb_id = result.imdb_id var dateNow = Date.now().valueOf(); @@ -111,14 +113,13 @@ class DefaultExtension extends MProvider { if (!seasonNum) continue; - var episodeNum = video.episode - - var eplink = `tv||${tmdb_id}/${seasonNum}/${episodeNum}` release = video.released ? new Date(video.released).valueOf() : dateNow - if (release < dateNow) { - var name = video.name + var episodeNum = video.episode + var name = `S${seasonNum}:E${episodeNum} - ${video.name}` + var eplink = `tv||${tmdb_id}/${seasonNum}/${episodeNum}` + chaps.push({ name: name, url: eplink, @@ -196,6 +197,18 @@ class DefaultExtension extends MProvider { } getSourcePreferences() { + return [{ + key: 'pref_latest_time_window', + listPreference: { + title: 'Preferred latest trend time window', + summary: '', + valueIndex: 0, + entries: ["Day", "Week"], + entryValues: ["day", "week"] + } + }, + + ]; } } \ No newline at end of file From 7074eec94af04b942fa8289670fcd1cc54327598 Mon Sep 17 00:00:00 2001 From: Swakshan Date: Fri, 20 Dec 2024 22:59:49 +0530 Subject: [PATCH 5/8] extension(Autoembed): Added stream resolution preference --- javascript/anime/src/all/autoembed.js | 35 ++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/javascript/anime/src/all/autoembed.js b/javascript/anime/src/all/autoembed.js index 3f3c85e5..d96d9df5 100644 --- a/javascript/anime/src/all/autoembed.js +++ b/javascript/anime/src/all/autoembed.js @@ -6,7 +6,7 @@ const mangayomiSources = [{ "iconUrl": "https://www.google.com/s2/favicons?sz=64&domain=https://autoembed.cc/", "typeSource": "multi", "isManga": false, - "version": "0.0.4", + "version": "0.0.5", "dateFormat": "", "dateFormatLocale": "", "pkgPath": "" @@ -162,6 +162,25 @@ class DefaultExtension extends MProvider { return streams; } + async sortStreams(streams) { + var sortedStreams = []; + + var copyStreams = streams.slice() + var pref = await this.getPreference("pref_video_resolution"); + for (var i in streams) { + var stream = streams[i]; + if (stream.quality.indexOf(pref) > -1) { + sortedStreams.push(stream); + var index = copyStreams.indexOf(stream); + if (index > -1) { + copyStreams.splice(index, 1); + } + break; + } + } + return [...sortedStreams, ...copyStreams] + } + // For anime episode video list async getVideoList(url) { var parts = url.split("||"); @@ -182,11 +201,11 @@ class DefaultExtension extends MProvider { streams.push({ url: link, originalUrl: link, - quality: "Auto", + quality: "auto", subtitles: subtitles, }); - return streams; + return await this.sortStreams(streams); } // For manga chapter pages async getPageList() { @@ -206,8 +225,18 @@ class DefaultExtension extends MProvider { entries: ["Day", "Week"], entryValues: ["day", "week"] } + }, { + key: 'pref_video_resolution', + listPreference: { + title: 'Preferred video resolution', + summary: '', + valueIndex: 0, + entries: ["Auto", "1080p", "720p", "360p"], + entryValues: ["auto", "1080", "720", "360"] + } }, + ]; } From 9f6f9c5a12fdfd68ca40622c603af4d2a47b1154 Mon Sep 17 00:00:00 2001 From: Swakshan Date: Fri, 20 Dec 2024 23:07:54 +0530 Subject: [PATCH 6/8] extension(Autoembed): Added search --- javascript/anime/src/all/autoembed.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/javascript/anime/src/all/autoembed.js b/javascript/anime/src/all/autoembed.js index d96d9df5..ec0a51b3 100644 --- a/javascript/anime/src/all/autoembed.js +++ b/javascript/anime/src/all/autoembed.js @@ -6,7 +6,7 @@ const mangayomiSources = [{ "iconUrl": "https://www.google.com/s2/favicons?sz=64&domain=https://autoembed.cc/", "typeSource": "multi", "isManga": false, - "version": "0.0.5", + "version": "0.0.6", "dateFormat": "", "dateFormatLocale": "", "pkgPath": "" @@ -59,7 +59,7 @@ class DefaultExtension extends MProvider { body = await this.tmdbRequest(`catalog/series/${slug}`); var popSeries = await this.getSearchItems(body); - var hasNextPage = true; + var hasNextPage = slug.indexOf("search=") > -1 ? false : true; return { list: [...popMovie, ...popSeries], hasNextPage @@ -81,7 +81,7 @@ class DefaultExtension extends MProvider { return await this.getSearchInfo(`tmdb.trending/genre=${trend_window}&skip=${skip}.json`); } async search(query, page, filters) { - throw new Error("search not implemented"); + return await this.getSearchInfo(`tmdb.popular/search=${query}.json`); } async getDetail(url) { var parts = url.split("/"); @@ -180,7 +180,7 @@ class DefaultExtension extends MProvider { } return [...sortedStreams, ...copyStreams] } - + // For anime episode video list async getVideoList(url) { var parts = url.split("||"); From 14f90a32b04e02a53a6bdd45fddff501a91e141a Mon Sep 17 00:00:00 2001 From: Swakshan Date: Fri, 20 Dec 2024 23:42:26 +0530 Subject: [PATCH 7/8] extension(Autoembed): misc --- javascript/anime/src/all/autoembed.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/javascript/anime/src/all/autoembed.js b/javascript/anime/src/all/autoembed.js index ec0a51b3..409a2a96 100644 --- a/javascript/anime/src/all/autoembed.js +++ b/javascript/anime/src/all/autoembed.js @@ -6,7 +6,7 @@ const mangayomiSources = [{ "iconUrl": "https://www.google.com/s2/favicons?sz=64&domain=https://autoembed.cc/", "typeSource": "multi", "isManga": false, - "version": "0.0.6", + "version": "1.0.0", "dateFormat": "", "dateFormatLocale": "", "pkgPath": "" @@ -42,7 +42,7 @@ class DefaultExtension extends MProvider { items.push({ name: result.name, imageUrl: result.poster, - link: `${media_type}/${id}`, + link: `${media_type}||${id}`, description: result.description, genre: result.genre }); @@ -84,7 +84,7 @@ class DefaultExtension extends MProvider { return await this.getSearchInfo(`tmdb.popular/search=${query}.json`); } async getDetail(url) { - var parts = url.split("/"); + var parts = url.split("||"); var media_type = parts[0]; var id = parts[1]; var body = await this.tmdbRequest(`meta/${media_type}/${id}.json`) @@ -212,7 +212,7 @@ class DefaultExtension extends MProvider { throw new Error("getPageList not implemented"); } getFilterList() { - throw new Error("getSourcePreferences not implemented"); + throw new Error("getFilterList not implemented"); } getSourcePreferences() { From 10e532d23a6a5b84364922e31a20bbb1cbc382bd Mon Sep 17 00:00:00 2001 From: Moustapha Kodjo Amadou Date: Sat, 21 Dec 2024 16:03:26 +0100 Subject: [PATCH 8/8] Update autoembed.js --- javascript/anime/src/all/autoembed.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/javascript/anime/src/all/autoembed.js b/javascript/anime/src/all/autoembed.js index 409a2a96..b778a73b 100644 --- a/javascript/anime/src/all/autoembed.js +++ b/javascript/anime/src/all/autoembed.js @@ -9,7 +9,7 @@ const mangayomiSources = [{ "version": "1.0.0", "dateFormat": "", "dateFormatLocale": "", - "pkgPath": "" + "pkgPath": "anime/src/all/autoembed.js" }]; class DefaultExtension extends MProvider { @@ -240,4 +240,4 @@ class DefaultExtension extends MProvider { ]; } -} \ No newline at end of file +}