mirror of
https://github.com/kodjodevf/mangayomi.git
synced 2026-05-11 16:40:36 +00:00
80 lines
2.5 KiB
Dart
80 lines
2.5 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 [];
|
|
}
|
|
}
|
|
}
|