-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Replaced consumet data provider by consumet.ts implementation moved t…
…o Dart. This is done because of consumet/api.consumet.org#486
- Loading branch information
Showing
30 changed files
with
563 additions
and
696 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1 @@ | ||
export 'providers/providers.dart'; | ||
export 'models/models.dart'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export 'gogocdn.dart'; | ||
export 'streamsb.dart'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,163 @@ | ||
import 'dart:convert'; | ||
|
||
import 'package:encrypt/encrypt.dart'; | ||
import 'package:html/dom.dart'; | ||
import 'package:html/parser.dart'; | ||
import 'package:http/http.dart'; | ||
|
||
import '../models/models.dart'; | ||
|
||
class CDNKeys { | ||
CDNKeys({ | ||
required this.key, | ||
required this.secondKey, | ||
required this.iv, | ||
}); | ||
|
||
final Key key; | ||
final Key secondKey; | ||
final IV iv; | ||
} | ||
|
||
/// Adapted from `https://github.com/consumet/consumet.ts/blob/master/src/extractors/gogocdn.ts` | ||
class GogoCDN extends Extractor { | ||
final client = Client(); | ||
final serverName = 'goload'; | ||
|
||
final _keys = CDNKeys( | ||
key: Key.fromUtf8('37911490979715163134003223491201'), | ||
secondKey: Key.fromUtf8('54674138327930866480207815084989'), | ||
iv: IV.fromUtf8('3134003223491201'), | ||
); | ||
|
||
var referrer = ''; | ||
|
||
@override | ||
Future<List<VideoSource>> extract(Uri uri) async { | ||
referrer = uri.toString(); | ||
|
||
final List<VideoSource> results = []; | ||
|
||
final page = await client.get(uri); | ||
final document = parse(page.body); | ||
|
||
final encyptedParams = | ||
_generateEncryptedAjaxParams(document, uri.queryParameters['id'] ?? ''); | ||
|
||
final encryptedData = await client.get( | ||
Uri( | ||
scheme: uri.scheme, | ||
host: uri.host, | ||
path: 'encrypt-ajax.php', | ||
query: encyptedParams, | ||
), | ||
headers: { | ||
'X-Requested-With': 'XMLHttpRequest', | ||
}, | ||
); | ||
|
||
final decryptedData = _decryptAjaxData( | ||
json.decode(encryptedData.body)['data'], | ||
); | ||
if (decryptedData['source'] == null) throw NoEpisodeSourceException; | ||
|
||
final String? url = decryptedData['source'][0]['file']; | ||
|
||
if (url?.contains('.m3u8') == true) { | ||
final resResult = await client.get(Uri.parse(url!)); | ||
final regexp = RegExp(r'(RESOLUTION=)(.*)(\s*?)(\s*.*)'); | ||
final resolutions = regexp.allMatches(resResult.body); | ||
final baseUrl = url.substring(0, url.lastIndexOf('/')); | ||
|
||
for (final resolution in resolutions) { | ||
final res = resolution[0] as String; | ||
|
||
results.add( | ||
VideoSource( | ||
url: '$baseUrl/${res.split('\n')[1]}', | ||
isM3U8: (baseUrl + res.split('\n')[1]).contains('.m3u8'), | ||
quality: '${res.split('\n')[0].split('x')[1].split(',')[0]}p', | ||
), | ||
); | ||
} | ||
|
||
decryptedData['source'].forEach((dynamic source) { | ||
results.add( | ||
VideoSource( | ||
url: url, | ||
isM3U8: source['file'].contains('.m3u8'), | ||
quality: 'default', | ||
), | ||
); | ||
}); | ||
} else { | ||
decryptedData['source'].forEach((dynamic source) { | ||
results.add( | ||
VideoSource( | ||
url: source['file'], | ||
isM3U8: source['file'].contains('.m3u8'), | ||
quality: source.label.split(' ')[0] + 'p', | ||
), | ||
); | ||
}); | ||
} | ||
|
||
decryptedData['source_bk'].forEach((dynamic source) { | ||
results.add( | ||
VideoSource( | ||
url: source['file'], | ||
isM3U8: source['file'].contains('.m3u8'), | ||
quality: 'backup', | ||
), | ||
); | ||
}); | ||
|
||
return results; | ||
} | ||
|
||
String _generateEncryptedAjaxParams( | ||
Document document, | ||
String id, | ||
) { | ||
final encrypter = Encrypter( | ||
AES( | ||
_keys.key, | ||
mode: AESMode.cbc, | ||
), | ||
); | ||
|
||
final encryptedKey = encrypter.encrypt( | ||
id, | ||
iv: _keys.iv, | ||
); | ||
|
||
final scriptValue = document | ||
.querySelector("script[data-name='episode']") | ||
?.attributes["data-value"]; | ||
|
||
if (scriptValue == null) throw NoEpisodeSourceException; | ||
|
||
final decryptedToken = encrypter.decrypt( | ||
Encrypted.from64(scriptValue), | ||
iv: _keys.iv, | ||
); | ||
|
||
return 'id=${encryptedKey.base64}&alias=$decryptedToken'; | ||
} | ||
|
||
Map<String, dynamic> _decryptAjaxData(String encryptedData) { | ||
final encrypter = Encrypter( | ||
AES( | ||
_keys.secondKey, | ||
mode: AESMode.cbc, | ||
), | ||
); | ||
|
||
final decryptedData = encrypter.decrypt( | ||
Encrypted.from64(encryptedData), | ||
iv: _keys.iv, | ||
); | ||
|
||
return json.decode(decryptedData); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
import 'dart:convert'; | ||
|
||
import 'package:http/http.dart'; | ||
|
||
import '../models/models.dart'; | ||
import '../utils/utils.dart'; | ||
|
||
/// Adapted from `https://github.com/consumet/consumet.ts/blob/master/src/extractors/streamsb.ts` | ||
class StreamSB extends Extractor { | ||
final host = 'https://streamsss.net/sources50'; | ||
final host2 = 'https://watchsb.com/sources50'; | ||
|
||
final client = Client(); | ||
|
||
String payload(String hex) => | ||
'566d337678566f743674494a7c7c${hex}7c7c346b6767586d6934774855537c7c73747265616d7362/6565417268755339773461447c7c346133383438333436313335376136323337373433383634376337633465366534393338373136643732373736343735373237613763376334363733353737303533366236333463353333363534366137633763373337343732363536313664373336327c7c6b586c3163614468645a47617c7c73747265616d7362'; | ||
|
||
@override | ||
Future<List<VideoSource>> extract(Uri uri) async { | ||
final List<VideoSource> results = []; | ||
Map<String, String> headers = { | ||
'watchsb': 'sbstream', | ||
'User-Agent': userAgent, | ||
'Referer': uri.toString(), | ||
}; | ||
|
||
var id = uri.toString().split('/e/').lastOrNull; | ||
if (id?.contains('html') == true) id = id?.split('.html').firstOrNull; | ||
|
||
if (id == null) throw 'cannot find ID'; | ||
|
||
final res = await client.get( | ||
Uri.parse( | ||
'$host/${payload(utf8.encode(id).map((e) => e.toRadixString(16)).join())}', | ||
), | ||
headers: headers, | ||
); | ||
final jsonResponse = json.decode(res.body); | ||
|
||
if (jsonResponse['stream_data'] == null) { | ||
throw 'No source found. Try a different server.'; | ||
} | ||
|
||
headers = { | ||
'User-Agent': userAgent, | ||
'Referer': uri.toString().split('e/').first, | ||
}; | ||
|
||
final m3u8Urls = await client.get( | ||
Uri.parse(jsonResponse['stream_data']['file']), | ||
headers: headers, | ||
); | ||
|
||
final videoList = m3u8Urls.body.split('#EXT-X-STREAM-INF:'); | ||
|
||
for (final video in videoList) { | ||
if (!video.contains('m3u8')) continue; | ||
|
||
final url = video.split('\n')[1]; | ||
final quality = video.split('RESOLUTION=')[1].split(',')[0].split('x')[1]; | ||
|
||
results.add( | ||
VideoSource( | ||
url: url, | ||
quality: '${quality}p', | ||
isM3U8: true, | ||
), | ||
); | ||
} | ||
|
||
results.add( | ||
VideoSource( | ||
url: jsonResponse['stream_data']['file'], | ||
quality: 'auto', | ||
isM3U8: jsonResponse['stream_data']['file'].contains('.m3u8'), | ||
), | ||
); | ||
|
||
return results; | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
107 changes: 0 additions & 107 deletions
107
lib/data/consumet/models/anime/anime_info_response/anime_info_response.dart
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.