import 'dart:async'; import 'package:http_interceptor/http_interceptor.dart'; import 'package:mangayomi/models/video.dart'; import 'package:mangayomi/services/http/m_client.dart'; import 'package:mangayomi/utils/extensions/string_extensions.dart'; class MyStreamExtractor { Future> videosFromUrl(String url, Map headers) async { final host = url.substringBefore("/watch"); final InterceptedClient client = MClient.init(reqcopyWith: {'useDartHttpClient': true}); try { final response = await client.get(Uri.parse(url), headers: headers); final document = response.body; final streamCode = document.substringAfter("${url.substringAfter("?v=")}\", \"").substringBefore("\",null,null"); final streamUrl = "$host/m3u8/$streamCode/master.txt?s=1&cache=1"; final cookie = response.headers.entries .firstWhere( (entry) => entry.key.toLowerCase() == "set-cookie" && entry.value.startsWith("PHPSESSID", 0), orElse: () => const MapEntry("set-cookie", ""), ) .value .split(";") .first; final newHeaders = {...headers, "cookie": cookie, "accept": "*/*"}; final masterPlaylistResponse = await client.get(Uri.parse(streamUrl), headers: newHeaders); final masterPlaylist = masterPlaylistResponse.body; const separator = "#EXT-X-STREAM-INF"; return masterPlaylist.substringAfter(separator).split(separator).map((it) { final resolution = "${it.substringAfter("RESOLUTION=").substringBefore("\n").substringAfter("x").substringBefore(",")}p"; final quality = "MyStream - $resolution"; final videoUrl = it.substringAfter("\n").substringBefore("\n"); return Video(videoUrl, quality, videoUrl, headers: newHeaders); }).toList(); } catch (_) { return []; } finally { client.close(); } } }