concurrentLoop method

Future<void> concurrentLoop(
  1. HlsSegment? hlsSegment,
  2. Map<String, String> headers
)

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);
    }
  });
}