mirror of
https://github.com/kodjodevf/mangayomi-extensions.git
synced 2026-02-14 19:01:15 +00:00
feat: Aniwave (EN): add Video extractors
This commit is contained in:
@@ -333,7 +333,8 @@ See [`MDocument` model](https://github.com/kodjodevf/mangayomi/blob/main/lib/eva
|
|||||||
- `String` substringBeforeLast(`String text`, `String pattern`)
|
- `String` substringBeforeLast(`String text`, `String pattern`)
|
||||||
|
|
||||||
### Crypto utils
|
### Crypto utils
|
||||||
- `String` evalJs(`String code`);
|
- `String` unpackJs(`String code`);
|
||||||
|
- `Future<String>` evalJs(`String code`);
|
||||||
- `String` deobfuscateJsPassword(`String inputString`)
|
- `String` deobfuscateJsPassword(`String inputString`)
|
||||||
- `String` encryptAESCryptoJS(`String plainText`, `String passphrase`)
|
- `String` encryptAESCryptoJS(`String plainText`, `String passphrase`)
|
||||||
- `String` decryptAESCryptoJS(`String encrypted`, `String passphrase`)
|
- `String` decryptAESCryptoJS(`String encrypted`, `String passphrase`)
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ class DataLifeEngine extends MProvider {
|
|||||||
final res = await http('GET', json.encode({"url": url}));
|
final res = await http('GET', json.encode({"url": url}));
|
||||||
final masterUrl = substringBefore(
|
final masterUrl = substringBefore(
|
||||||
substringAfter(
|
substringAfter(
|
||||||
substringAfter(substringAfter(evalJs(res), "sources:"), "file:\""),
|
substringAfter(substringAfter(unpackJs(res), "sources:"), "file:\""),
|
||||||
"src:\""),
|
"src:\""),
|
||||||
'"');
|
'"');
|
||||||
final masterPlaylistRes =
|
final masterPlaylistRes =
|
||||||
@@ -203,7 +203,7 @@ class DataLifeEngine extends MProvider {
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
final masterUrl =
|
final masterUrl =
|
||||||
substringBefore(substringAfter(evalJs(js.first), "{file:\""), "\"}");
|
substringBefore(substringAfter(unpackJs(js.first), "{file:\""), "\"}");
|
||||||
final masterPlaylistRes =
|
final masterPlaylistRes =
|
||||||
await http('GET', json.encode({"url": masterUrl}));
|
await http('GET', json.encode({"url": masterUrl}));
|
||||||
List<MVideo> videos = [];
|
List<MVideo> videos = [];
|
||||||
|
|||||||
@@ -204,7 +204,13 @@ class Aniwave extends MProvider {
|
|||||||
final hosterSelection = preferenceHosterSelection(source.id);
|
final hosterSelection = preferenceHosterSelection(source.id);
|
||||||
final typeSelection = preferenceTypeSelection(source.id);
|
final typeSelection = preferenceTypeSelection(source.id);
|
||||||
if (typeSelection.contains(type.toLowerCase())) {
|
if (typeSelection.contains(type.toLowerCase())) {
|
||||||
if (url.contains("mp4upload") &&
|
if (url.contains("vidplay") || url.contains("mcloud")) {
|
||||||
|
final hosterName =
|
||||||
|
url.contains("vidplay") ? "VidPlay" : "MyCloud";
|
||||||
|
if (hosterSelection.contains(hosterName.toLowerCase())) {
|
||||||
|
a = await vidsrcExtractor(url, hosterName, type);
|
||||||
|
}
|
||||||
|
} else if (url.contains("mp4upload") &&
|
||||||
hosterSelection.contains("mp4upload")) {
|
hosterSelection.contains("mp4upload")) {
|
||||||
a = await mp4UploadExtractor(url, null, "", type);
|
a = await mp4UploadExtractor(url, null, "", type);
|
||||||
} else if (url.contains("streamtape") &&
|
} else if (url.contains("streamtape") &&
|
||||||
@@ -305,6 +311,111 @@ class Aniwave extends MProvider {
|
|||||||
return vrf;
|
return vrf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<List<MVideo>> vidsrcExtractor(
|
||||||
|
String url, String name, String type) async {
|
||||||
|
List<String> keys = json.decode(await http(
|
||||||
|
'GET',
|
||||||
|
json.encode({
|
||||||
|
"url":
|
||||||
|
"https://raw.githubusercontent.com/Claudemirovsky/worstsource-keys/keys/keys.json"
|
||||||
|
})));
|
||||||
|
final host = Uri.parse(url).host;
|
||||||
|
final apiUrl = await getApiUrl(url, keys);
|
||||||
|
final headers = {
|
||||||
|
"Accept": "application/json, text/javascript, */*; q=0.01",
|
||||||
|
"Host": host,
|
||||||
|
"Referer": Uri.decodeComponent(url),
|
||||||
|
"X-Requested-With": "XMLHttpRequest"
|
||||||
|
};
|
||||||
|
final res =
|
||||||
|
await http('GET', json.encode({"url": apiUrl, "headers": headers}));
|
||||||
|
if (res == "error") return [];
|
||||||
|
String masterUrl =
|
||||||
|
((json.decode(res)['result']['sources'] as List<Map<String, dynamic>>)
|
||||||
|
.first)['file'];
|
||||||
|
final tracks = (json.decode(res)['result']['tracks'] as List)
|
||||||
|
.where((e) => e['kind'] == 'captions' ? true : false)
|
||||||
|
.toList();
|
||||||
|
List<MTrack> subtitles = [];
|
||||||
|
|
||||||
|
for (var sub in tracks) {
|
||||||
|
try {
|
||||||
|
MTrack subtitle = MTrack();
|
||||||
|
subtitle
|
||||||
|
..label = sub["label"]
|
||||||
|
..file = sub["file"];
|
||||||
|
subtitles.add(subtitle);
|
||||||
|
} catch (_) {}
|
||||||
|
}
|
||||||
|
List<MVideo> videoList = [];
|
||||||
|
final masterPlaylistRes =
|
||||||
|
await http('GET', json.encode({"url": masterUrl}));
|
||||||
|
for (var it in substringAfter(masterPlaylistRes, "#EXT-X-STREAM-INF:")
|
||||||
|
.split("#EXT-X-STREAM-INF:")) {
|
||||||
|
final quality =
|
||||||
|
"${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p";
|
||||||
|
|
||||||
|
String videoUrl = substringBefore(substringAfter(it, "\n"), "\n");
|
||||||
|
|
||||||
|
if (!videoUrl.startsWith("http")) {
|
||||||
|
videoUrl =
|
||||||
|
"${masterUrl.split("/").sublist(0, masterUrl.split("/").length - 1).join("/")}/$videoUrl";
|
||||||
|
}
|
||||||
|
|
||||||
|
MVideo video = MVideo();
|
||||||
|
video
|
||||||
|
..url = videoUrl
|
||||||
|
..originalUrl = videoUrl
|
||||||
|
..quality = "$name - $type - $quality"
|
||||||
|
..headers = {"Referer": "https://$host/"}
|
||||||
|
..subtitles = subtitles;
|
||||||
|
videoList.add(video);
|
||||||
|
}
|
||||||
|
return videoList;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<String> getApiUrl(String url, List<String> keyList) async {
|
||||||
|
final host = Uri.parse(url).host;
|
||||||
|
final paramsToString = Uri.parse(url)
|
||||||
|
.queryParameters
|
||||||
|
.entries
|
||||||
|
.map((e) => "${e.key}=${e.value}")
|
||||||
|
.join("&");
|
||||||
|
var vidId = substringBefore(substringAfterLast(url, "/"), "?");
|
||||||
|
var encodedID = encodeID(vidId, keyList);
|
||||||
|
final apiSlug = await callFromFuToken(host, encodedID);
|
||||||
|
String apiUrlString = "";
|
||||||
|
apiUrlString += "https://$host/$apiSlug";
|
||||||
|
if (paramsToString.isNotEmpty) {
|
||||||
|
apiUrlString += "?$paramsToString";
|
||||||
|
}
|
||||||
|
|
||||||
|
return apiUrlString;
|
||||||
|
}
|
||||||
|
|
||||||
|
String encodeID(String vidId, List<String> keyList) {
|
||||||
|
var rc4Key1 = keyList[0];
|
||||||
|
var rc4Key2 = keyList[1];
|
||||||
|
final rc4 = rc4Encrypt(rc4Key1, vidId.codeUnits);
|
||||||
|
final rc41 = rc4Encrypt(rc4Key2, rc4);
|
||||||
|
return base64.encode(rc41).replaceAll("/", "_").trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<String> callFromFuToken(String host, String data) async {
|
||||||
|
final fuTokenScript =
|
||||||
|
await http('GET', json.encode({"url": "https://$host/futoken"}));
|
||||||
|
String js = "";
|
||||||
|
js += "(function";
|
||||||
|
js += substringBefore(
|
||||||
|
substringAfter(substringAfter(fuTokenScript, "window"), "function")
|
||||||
|
.replaceAll("jQuery.ajax(", ""),
|
||||||
|
"+location.search");
|
||||||
|
js += "}(\"$data\"))";
|
||||||
|
final jsRes = await evalJs(js);
|
||||||
|
if (jsRes == "error") return "";
|
||||||
|
return jsRes;
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<dynamic> getFilterList(MSource source) {
|
List<dynamic> getFilterList(MSource source) {
|
||||||
return [
|
return [
|
||||||
|
|||||||
@@ -362,7 +362,7 @@ class OtakuFr extends MProvider {
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
final masterUrl =
|
final masterUrl =
|
||||||
substringBefore(substringAfter(evalJs(js.first), "{file:\""), "\"}");
|
substringBefore(substringAfter(unpackJs(js.first), "{file:\""), "\"}");
|
||||||
final masterPlaylistRes =
|
final masterPlaylistRes =
|
||||||
await http('GET', json.encode({"url": masterUrl}));
|
await http('GET', json.encode({"url": masterUrl}));
|
||||||
List<MVideo> videos = [];
|
List<MVideo> videos = [];
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ class NimeGami extends MProvider {
|
|||||||
'//script[contains(text(), "eval") and contains(text(), "p,a,c,k,e,d")]/text()');
|
'//script[contains(text(), "eval") and contains(text(), "p,a,c,k,e,d")]/text()');
|
||||||
if (script.isNotEmpty) {
|
if (script.isNotEmpty) {
|
||||||
final videoUrl = substringBefore(
|
final videoUrl = substringBefore(
|
||||||
substringAfter(substringAfter(evalJs(script.first), "sources:[", ""),
|
substringAfter(substringAfter(unpackJs(script.first), "sources:[", ""),
|
||||||
"file\":\"", ""),
|
"file\":\"", ""),
|
||||||
'"');
|
'"');
|
||||||
if (videoUrl.isNotEmpty) {
|
if (videoUrl.isNotEmpty) {
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ class MangaHere extends MProvider {
|
|||||||
res, "//script[contains(text(),'function(p,a,c,k,e,d)')]/text()")
|
res, "//script[contains(text(),'function(p,a,c,k,e,d)')]/text()")
|
||||||
.first
|
.first
|
||||||
.replaceAll("eval", "");
|
.replaceAll("eval", "");
|
||||||
String deobfuscatedScript = evalJs(script);
|
String deobfuscatedScript = unpackJs(script);
|
||||||
int a = deobfuscatedScript.indexOf("newImgs=['") + 10;
|
int a = deobfuscatedScript.indexOf("newImgs=['") + 10;
|
||||||
int b = deobfuscatedScript.indexOf("'];");
|
int b = deobfuscatedScript.indexOf("'];");
|
||||||
List<String> urls = deobfuscatedScript.substring(a, b).split("','");
|
List<String> urls = deobfuscatedScript.substring(a, b).split("','");
|
||||||
@@ -197,7 +197,7 @@ class MangaHere extends MProvider {
|
|||||||
String secretKeyScript = res
|
String secretKeyScript = res
|
||||||
.substring(secretKeyScriptLocation, secretKeyScriptEndLocation)
|
.substring(secretKeyScriptLocation, secretKeyScriptEndLocation)
|
||||||
.replaceAll("eval", "");
|
.replaceAll("eval", "");
|
||||||
String secretKeyDeobfuscatedScript = evalJs(secretKeyScript);
|
String secretKeyDeobfuscatedScript = unpackJs(secretKeyScript);
|
||||||
int secretKeyStartLoc = secretKeyDeobfuscatedScript.indexOf("'");
|
int secretKeyStartLoc = secretKeyDeobfuscatedScript.indexOf("'");
|
||||||
int secretKeyEndLoc = secretKeyDeobfuscatedScript.indexOf(";");
|
int secretKeyEndLoc = secretKeyDeobfuscatedScript.indexOf(";");
|
||||||
|
|
||||||
@@ -231,7 +231,7 @@ class MangaHere extends MProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
String deobfuscatedScript = evalJs(responseText.replaceAll("eval", ""));
|
String deobfuscatedScript = unpackJs(responseText.replaceAll("eval", ""));
|
||||||
|
|
||||||
int baseLinkStartPos = deobfuscatedScript.indexOf("pix=") + 5;
|
int baseLinkStartPos = deobfuscatedScript.indexOf("pix=") + 5;
|
||||||
int baseLinkEndPos =
|
int baseLinkEndPos =
|
||||||
|
|||||||
Reference in New Issue
Block a user