mangayomi/lib/services/anime_extractors/filemoon.dart
kodjomoustapha b10c3f3a22 misc changes
- remove cronet_http & cupertino_http
- use rhttp package as default http client
- fix #198 #200 crashes on multiple downloads
- fix #162 #102 unable to download with forbidden characters in the name (as it is fixed this can cause reading problems concerning chapters downloaded before this version)
- now supports all features on all platforms such as VPNs and HTTP proxies thanks to rhttp package
2024-08-21 13:30:13 +01:00

68 lines
2.4 KiB
Dart

import 'dart:convert';
import 'package:http_interceptor/http_interceptor.dart';
import 'package:js_packer/js_packer.dart';
import 'package:mangayomi/models/video.dart';
import 'package:mangayomi/services/http/m_client.dart';
import 'package:mangayomi/utils/extensions/string_extensions.dart';
import 'package:mangayomi/utils/xpath_selector.dart';
class FilemoonExtractor {
final InterceptedClient client =
MClient.init(reqcopyWith: {'useDartHttpClient': true});
Future<List<Video>> videosFromUrl(
String url, String prefix, String suffix) async {
prefix = prefix.isEmpty ? "Filemoon " : prefix;
try {
final videoHeaders = {
'Referer': url,
'Origin': 'https://${Uri.parse(url).host}',
};
final response = await client.get(Uri.parse(url));
final jsEval = xpathSelector(response.body)
.queryXPath('//script[contains(text(), "eval")]/text()')
.attr;
final unpacked = JSPacker(jsEval!).unpack() ?? "";
final masterUrl = unpacked.isNotEmpty
? unpacked.substringAfter('{file:"').substringBefore('"}')
: '';
if (masterUrl.isEmpty) {
return [];
}
List<Track> subtitleTracks = [];
final subUrl = Uri.parse(url).queryParameters["sub.info"] ??
unpacked.substringAfter("""fetch('", """).substringBefore("""').""");
if (subUrl.isNotEmpty) {
try {
final subResponse =
await client.get(Uri.parse(subUrl), headers: videoHeaders);
final subList = jsonDecode(subResponse.body) as List;
for (var item in subList) {
subtitleTracks.add(Track(file: item["file"], label: item["label"]));
}
} catch (_) {}
}
final masterPlaylistResponse = await client.get(Uri.parse(masterUrl));
final masterPlaylist = masterPlaylistResponse.body;
const separator = '#EXT-X-STREAM-INF:';
final playlists = masterPlaylist.split(separator).sublist(1);
return playlists.map((playlist) {
final resolution =
'${playlist.substringAfter('RESOLUTION=').substringAfter('x').substringBefore(',').trim()}p';
final videoUrl = playlist.split('\n')[1].trim();
return Video(videoUrl, "$prefix - $resolution $suffix", videoUrl,
headers: videoHeaders, subtitles: subtitleTracks);
}).toList();
} catch (_) {
return [];
}
}
}