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<HlsSegment> mediaList = await parseSegment(url.toSafeUri(), headers);
  int totalSize = mediaList.length;
  if (cacheSegments > totalSize) cacheSegments = totalSize;
  if (mediaList.isEmpty) return _streamController;

  final List<HlsSegment> 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> processSegments() async {
    for (final segment in segments) {
      final task = DownloadTask(
        uri: segment.url.toSafeUri(),
        hlsKey: hlsKey,
        headers: headers,
        startRange: segment.startRange,
        endRange: segment.endRange,
      );
      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.fileName,
        'hls_key': hlsKey,
        'total_segments': segments.length,
        'current_segment_index': downloadedSize - 1,
      });
    }
  }

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

  return _streamController;
}