concurrentLoop method
Asynchronously downloads TS files for HLS segments.
Manages download concurrency and updates segment status.
Implementation
Future<void> concurrentLoop(
HlsSegment? hlsSegment,
Map<String, String> headers,
) async {
if (hlsSegment == null) return;
_latestUrl = hlsSegment.url;
Set<String?> hlsKeys = _list.map((e) => e.key).toSet();
if (hlsKeys.length > 2) {
_list.where((e) => e.key == hlsKeys.first).forEach((e) {
VideoProxy.downloadManager.allTasks
.removeWhere((task) => task.url == e.url);
});
_list.removeWhere((e) => e.key == hlsKeys.first);
}
HlsSegment? segment = _list.where((e) => e.url == _latestUrl).firstOrNull;
if (segment == null) return;
List<HlsSegment> downloading = _list
.where((e) => e.key == segment.key)
.where((e) => e.status == DownloadStatus.DOWNLOADING)
.toList();
if (downloading.length >= 4) return;
Uint8List? cache =
await LruCacheSingleton().memoryGet(segment.url.generateMd5);
if (cache != null) {
concurrentComplete(segment, headers);
return;
}
DownloadTask task = DownloadTask(
uri: segment.url.toSafeUri(),
headers: headers,
);
String cachePath = await FileExt.createCachePath(segment.key);
File file = File('$cachePath/${task.saveFileName}');
if (await file.exists()) {
concurrentComplete(segment, headers);
return;
}
bool exitUri = VideoProxy.downloadManager.isUrlExit(segment.url);
if (exitUri) {
concurrentComplete(segment, headers, status: DownloadStatus.DOWNLOADING);
return;
}
task.priority += 1;
task.cacheDir = cachePath;
await VideoProxy.downloadManager.executeTask(task);
StreamSubscription? subscription;
subscription = VideoProxy.downloadManager.stream.listen((downloadTask) {
if (downloadTask.status == DownloadStatus.COMPLETED &&
downloadTask.matchUrl == task.matchUrl) {
logD("Asynchronous download completed: ${task.toString()}");
subscription?.cancel();
concurrentComplete(segment, headers);
}
});
}