Merge pull request #125 from Swakshan/extension/autoembed

Added new stream sources for Autoembed
This commit is contained in:
Moustapha Kodjo Amadou
2025-01-05 19:19:41 +01:00
committed by GitHub

View File

@@ -6,7 +6,7 @@ const mangayomiSources = [{
"iconUrl": "https://www.google.com/s2/favicons?sz=64&domain=https://autoembed.cc/", "iconUrl": "https://www.google.com/s2/favicons?sz=64&domain=https://autoembed.cc/",
"typeSource": "multi", "typeSource": "multi",
"isManga": false, "isManga": false,
"version": "1.0.3", "version": "1.1.4",
"dateFormat": "", "dateFormat": "",
"dateFormatLocale": "", "dateFormatLocale": "",
"pkgPath": "anime/src/all/autoembed.js" "pkgPath": "anime/src/all/autoembed.js"
@@ -129,7 +129,7 @@ class DefaultExtension extends MProvider {
if (release < dateNow) { if (release < dateNow) {
var episodeNum = video.episode var episodeNum = video.episode
var name = `S${seasonNum}:E${episodeNum} - ${video.name}` var name = `S${seasonNum}:E${episodeNum} - ${video.name}`
var eplink = `${link}/${seasonNum}/${episodeNum}` var eplink = `${link}||${seasonNum}||${episodeNum}`
chaps.push({ chaps.push({
name: name, name: name,
@@ -152,27 +152,57 @@ class DefaultExtension extends MProvider {
chaps.reverse(); chaps.reverse();
return item; return item;
} }
async extractStreams(url) {
// Extracts the streams url for different resolutions from a hls stream.
async extractStreams(url, lang = "", hdr = {}) {
const response = await new Client().get(url); const response = await new Client().get(url);
const body = response.body; const body = response.body;
const lines = body.split('\n'); const lines = body.split('\n');
var streams = []; var streams = [{
url: url,
originalUrl: url,
quality: "auto",
}];
for (let i = 0; i < lines.length; i++) { for (let i = 0; i < lines.length; i++) {
if (lines[i].startsWith('#EXT-X-STREAM-INF:')) { if (lines[i].startsWith('#EXT-X-STREAM-INF:')) {
const resolution = lines[i].match(/RESOLUTION=(\d+x\d+)/)[1]; var resolution = lines[i].match(/RESOLUTION=(\d+x\d+)/)[1];
const m3u8Url = lines[i + 1].trim(); resolution = `${lang} ${resolution}`
var m3u8Url = lines[i + 1].trim();
m3u8Url = m3u8Url.replace("./", `${url}/`)
streams.push({ streams.push({
url: m3u8Url, url: m3u8Url,
originalUrl: m3u8Url, originalUrl: m3u8Url,
quality: resolution, quality: resolution,
headers: hdr
}); });
} }
} }
return streams
}
// For some streams, we can form stream url using a default template.
async splitStreams(url, lang = "", hdr = {}) {
var streams = [];
var quality = ["auto", "360", "480", "720", "1080"]
for (var q of quality) {
var link = url
if (q != "auto") {
link = link.replace("index.m3u8", `${q}/index.m3u8`)
q = `${q}p`
}
streams.push({
url: link,
originalUrl: link,
quality: `${lang} - ${q}`,
headers: hdr
});
}
return streams; return streams;
} }
// Sorts streams based on user preference.
async sortStreams(streams) { async sortStreams(streams) {
var sortedStreams = []; var sortedStreams = [];
@@ -192,31 +222,177 @@ class DefaultExtension extends MProvider {
return [...sortedStreams, ...copyStreams] return [...sortedStreams, ...copyStreams]
} }
// Gets subtitles based on TMDB id.
async getSubtitleList(id, s, e) {
var api = `https://sub.wyzie.ru/search?id=${id}`
if (s != "0") api = `${api}&season=${s}&episode=${e}`
var response = await new Client().get(api);
var body = JSON.parse(response.body);
var subs = []
for (var sub of body) {
subs.push({
file: sub.url,
label: sub.display
})
}
return subs
}
// For anime episode video list // For anime episode video list
async getVideoList(url) { async getVideoList(url) {
var streamAPI = parseInt(await this.getPreference("pref_stream_source"))
var parts = url.split("||"); var parts = url.split("||");
var media_type = parts[0]; var media_type = parts[0];
var id = parts[1]; var id = parts[1];
var api = `${this.source.apiUrl}/api/getVideoSource?type=${media_type}&id=${id}` var tmdb = id
const response = await new Client().get(api, this.getHeaders()); var streams = []
const body = JSON.parse(response.body); var subtitles = []
switch (streamAPI) {
case 2: {
var s = "0"
var e = "0"
if (media_type == "tv") {
s = parts[2]
e = parts[3]
id = `${id}/${s}/${e}`
}
var api = `https://play2.123embed.net/server/3?path=/${media_type}/${id}`
var response = await new Client().get(api);
if (response.statusCode == 404) { if (response.statusCode != 200) {
throw new Error("Video unavailable"); throw new Error("Video unavailable");
}
var body = JSON.parse(response.body);
var link = body.playlist[0].file
streams.push({
url: link,
originalUrl: link,
quality: "auto",
headers: { "Origin": "https://play2.123embed.net" },
});
break;
}
case 3: {
var s = "0"
var e = "0"
if (media_type == "tv") {
s = parts[2]
e = parts[3]
id = `${id}&s=${s}&e=${e}`
}
var api = `https://autoembed.cc/embed/player.php?id=${id}`
var response = await new Client().get(api);
if (response.statusCode != 200) {
throw new Error("Video unavailable");
}
var body = response.body
var sKey = '"file": '
var eKey = "]});"
var start = body.indexOf(sKey)
if (start < 0) {
throw new Error("Video unavailable");
}
start += sKey.length
var end = body.substring(start,).indexOf(eKey) + start - 1
var strms = JSON.parse(body.substring(start, end) + "]")
for (var strm of strms) {
var link = strm.file
var lang = strm.title
var streamSplit = await this.splitStreams(link, lang);
streams = [...streams, ...streamSplit]
}
break;
}
case 4: {
var s = "0"
var e = "0"
if (media_type == "tv") {
s = parts[2]
e = parts[3]
id = `${id}&season=${s}&episode=${e}`
}
var api = `https://player.flicky.host/Server-main.php?id=${id}`
var response = await new Client().get(api, { "Referer": "https://flicky.host/" });
if (response.statusCode != 200) {
throw new Error("Video unavailable");
}
var body = response.body
var sKey = 'streams = '
var eKey = "];"
var start = body.indexOf(sKey)
if (start < 0) {
throw new Error("Video unavailable");
}
start += sKey.length
var end = body.substring(start,).indexOf(eKey) + start + 1
var strms = JSON.parse(body.substring(start, end))
for (var strm of strms) {
var link = strm.url
var lang = strm.language
var streamSplit = await this.splitStreams(link, lang);
streams = [...streams, ...streamSplit]
}
break;
}
case 5: {
if (media_type == "tv") {
id = `${id}/${parts[2]}/${parts[3]}`
}
var api = `https://vidapi.click/api/video/${media_type}/${id}`
var response = await new Client().get(api);
if (response.statusCode != 200) {
throw new Error("Video unavailable");
}
var body = JSON.parse(response.body);
var link = body.sources[0].file
subtitles = body.tracks
streams = await this.extractStreams(link);
break;
}
default: {
if (media_type == "tv") {
id = `${id}/${parts[2]}/${parts[3]}`
}
var api = `${this.source.apiUrl}/api/getVideoSource?type=${media_type}&id=${id}`
var response = await new Client().get(api, this.getHeaders());
if (response.statusCode != 200) {
throw new Error("Video unavailable");
}
var body = JSON.parse(response.body);
var link = body.videoSource
subtitles = body.subtitles
streams = await this.extractStreams(link);
break;
}
} }
var link = body.videoSource if (streams.length < 1) {
throw new Error("Video unavailable");
}
var subtitles = body.subtitles if (subtitles.length < 1) {
var streams = await this.extractStreams(link); subtitles = await this.getSubtitleList(tmdb, s, e)
streams.push({ }
url: link, streams[0].subtitles = subtitles
originalUrl: link,
quality: "auto",
subtitles: subtitles,
});
return await this.sortStreams(streams); return await this.sortStreams(streams)
} }
// For manga chapter pages // For manga chapter pages
async getPageList() { async getPageList() {
@@ -255,8 +431,16 @@ class DefaultExtension extends MProvider {
entryValues: ["movies", "series"] entryValues: ["movies", "series"]
} }
}, },
{
key: 'pref_stream_source',
listPreference: {
title: 'Preferred stream source',
summary: '',
valueIndex: 0,
entries: ["tom.autoembed.cc", "123embed.net", "autoembed.cc - Indian languages", "flicky.host - Indian languages", "vidapi.click"],
entryValues: ["1", "2", "3", "4", "5"]
}
},
]; ];
} }