extractAudioAndVideoTs method
Implementation
Future<String> extractAudioAndVideoTs(
String m3u8, {
String initialSubtitle = "",
String Function(String quality)? formatter,
bool descending = true,
}) async {
Dio dio = Dio();
(dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate =
(HttpClient client) {
client.badCertificateCallback =
(X509Certificate cert, String host, int port) => true;
return client;
};
dio.options.connectTimeout = 5 * 1000;
dio.interceptors.add(RetryInterceptor(
dio: dio,
logPrint: print, // specify log function (optional)
retries: 10, // retry count (optional)
retryDelays: const [
// set delays between retries (optional)
Duration(seconds: 1), // wait 1 sec before first retry
Duration(seconds: 2), // wait 2 sec before second retry
Duration(seconds: 3), // wait 3 sec before third retry
],
));
//REGULAR EXPRESIONS//
final RegExp netRegxUrl = RegExp(r'^(http|https):\/\/([\w.]+\/?)\S*');
final RegExp netRegx2 = RegExp(r'(.*)\r?\/');
final RegExp regExpPlaylist = RegExp(
r"#EXT-X-STREAM-INF:(?:.*,RESOLUTION=(\d+x\d+))?,?(.*)\r?\n(.*)",
caseSensitive: false,
multiLine: true,
);
final RegExp regExpAudio = RegExp(
r"""^#EXT-X-MEDIA:TYPE=AUDIO(?:.*,URI="(.*m3u8.*)")""",
caseSensitive: false,
multiLine: true,
);
final RegExp regExpListOfLinks =
RegExp("#EXTINF:.+?\n+(.+)", multiLine: true, caseSensitive: false);
Response res = await dio.get(m3u8);
//GET m3u8 file
String content = "";
if (res.statusCode == 200) {
content = res.data;
//Find matches
List<RegExpMatch> playlistMatches =
regExpPlaylist.allMatches(content).toList();
List<RegExpMatch> audioMatches = regExpAudio.allMatches(content).toList();
//List<RegExpMatch> ListOfLinks = regExpListOfLinks.allMatches(content).toList();
Map<String, List<String?>> downloadLinks = {};
Map<String, String> sourceUrls = {};
final List<String> audioUrls = [];
for (final RegExpMatch playlistMatch in playlistMatches) {
final RegExpMatch? playlist = netRegx2.firstMatch(m3u8);
final String sourceURL = (playlistMatch.group(3)).toString();
final String quality = (playlistMatch.group(1)).toString();
final bool isNetwork = netRegxUrl.hasMatch(sourceURL);
String playlistUrl = sourceURL;
if (!isNetwork) {
final String? dataURL = playlist!.group(0);
playlistUrl = "$dataURL$sourceURL";
}
//Find audio url
for (final RegExpMatch audioMatch in audioMatches) {
final String audio = (audioMatch.group(1)).toString();
final bool isNetwork = netRegxUrl.hasMatch(audio);
final RegExpMatch? match = netRegx2.firstMatch(playlistUrl);
String audioUrl = audio;
if (!isNetwork && match != null) {
audioUrl = "${match.group(0)}$audio";
}
audioUrls.add(audioUrl);
}
sourceUrls[quality] = playlistUrl;
}
//print("here");
List<String> qualityKeys = sourceUrls.keys.toList();
qualityKeys.sort((a, b) {
try {
return int.parse(a.split("x")[0])
.compareTo(int.parse(b.split("x")[0]));
} catch (_) {
print("error comparing qualities hls,$_");
return -1;
}
});
if (sourceUrls.isEmpty) {
//input was playlist
List<RegExpMatch> ListOfLinks =
regExpListOfLinks.allMatches(content).toList();
String baseUrl = m3u8;
ListOfLinks.forEach((element) {
final bool isNetwork = netRegxUrl.hasMatch(element.group(1) ?? "");
if (!isNetwork) {
content.replaceAll(
element.group(1) ?? "",
baseUrl.substring(0, baseUrl.lastIndexOf('/')) +
"/" +
(element.group(1) ?? ""));
}
});
return content;
}
//print(downloadLinks);
return "";
} else {
return "";
}
}