precache method

  1. @override
Future<StreamController<Map>?> precache(
  1. String url,
  2. Map<String, Object>? headers,
  3. int cacheSegments,
  4. bool downloadNow,
  5. bool progressListen,
)
override

Pre-caches HLS video segments from the network.

Parses the given HLS playlist URL, selects a specified number of segments to cache, and either immediately downloads them or queues them for later processing.

If progressListen is true, returns a StreamController that emits progress updates.

Implementation

@override
Future<StreamController<Map>?> precache(
  String url,
  Map<String, Object>? headers,
  int cacheSegments,
  bool downloadNow,
  bool progressListen,
) async {
  StreamController<Map>? _streamController;
  if (progressListen) _streamController = StreamController();

  List<String> mediaList = await parseSegment(url.toSafeUri(), headers);
  int totalSize = mediaList.length;
  if (cacheSegments > totalSize) cacheSegments = totalSize;
  if (mediaList.isEmpty) return _streamController;

  final List<String> segments = mediaList.take(cacheSegments).toList();
  final String hlsKey = url.generateMd5;
  int downloadedSize = 0;

  /// Downloads or loads a segment from cache and emits progress to the stream.
  Future<void> processSegment(String segment) async {
    final task = DownloadTask(
      uri: segment.toSafeUri(),
      hlsKey: hlsKey,
      headers: headers,
    );
    Uint8List? data = await cache(task);
    if (data == null) {
      await download(task);
    }

    downloadedSize += 1;
    if (_streamController?.isClosed ?? false) return;
    _streamController?.sink.add({
      'progress': downloadedSize / cacheSegments,
      'segment_url': segment,
      'parent_url': url,
      'file_name': task.saveFile,
      'hls_key': hlsKey,
      'total_segments': segments.length,
      'current_segment_index': downloadedSize - 1,
    });
  }

  if (downloadNow) {
    for (final segment in segments) {
      await processSegment(segment);
    }
  } else {
    for (final segment in segments) {
      final task = DownloadTask(
        uri: segment.toSafeUri(),
        hlsKey: hlsKey,
        headers: headers,
      );
      push(task);
    }
  }

  return _streamController;
}