feat: Aniwave (EN): add Video extractors

This commit is contained in:
kodjomoustapha
2023-12-27 20:41:52 +01:00
parent 14b924cd9d
commit 694c8a8b99
6 changed files with 121 additions and 9 deletions

View File

@@ -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`)

View File

@@ -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 = [];

View File

@@ -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 [

View File

@@ -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 = [];

View File

@@ -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) {

View File

@@ -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 =