generateThumbnail function

Stream<List<Uint8List?>> generateThumbnail({
  1. required String videoPath,
  2. required int videoDuration,
  3. required int numberOfThumbnails,
  4. required double thumbnailHeight,
  5. required int quality,
  6. required VoidCallback onThumbnailLoadingComplete,
})

Implementation

Stream<List<Uint8List?>> generateThumbnail({
  required String videoPath,
  required int videoDuration,
  required int numberOfThumbnails,
  required double thumbnailHeight,
  required int quality,
  required VoidCallback onThumbnailLoadingComplete,
}) async* {
  final double eachPart = videoDuration / numberOfThumbnails;
  final List<Uint8List?> thumbnailBytes = [];

  try {
    // Generate video thumbnails
    for (int i = 1; i <= numberOfThumbnails; i++) {
      log('Generating thumbnail $i / $numberOfThumbnails');

      Uint8List? bytes;

      // Calculate the timestamp for the thumbnail in milliseconds
      final timestamp = (eachPart * i).toInt();
      final formattedTimestamp =
          _formatDuration(Duration(milliseconds: timestamp));

      // Generate the thumbnail image bytes
      bytes = await VideoThumbnail.thumbnailData(
        video: videoPath,
        imageFormat: ImageFormat.JPEG,
        timeMs: timestamp,
        maxHeight: thumbnailHeight.toInt(),
        quality: quality,
      );

      log('Timestamp: $formattedTimestamp | Size: ${(bytes!.length / 1000).toStringAsFixed(2)} kB');
      log('---------------------------------');

      thumbnailBytes.add(bytes);

      if (thumbnailBytes.length == numberOfThumbnails) {
        onThumbnailLoadingComplete();
      }

      yield thumbnailBytes;
    }
    log('Thumbnails generated successfully!');
  } catch (e) {
    log('ERROR: Couldn\'t generate thumbnails: $e');
  }
}