parseWebVTT static method

List<SubtitleCue> parseWebVTT(
  1. String content
)

Parse WebVTT subtitle format

Implementation

static List<SubtitleCue> parseWebVTT(String content) {
  final cues = <SubtitleCue>[];
  final lines = content.split('\n');

  String? currentText;
  Duration? startTime;
  Duration? endTime;

  for (var i = 0; i < lines.length; i++) {
    final line = lines[i].trim();

    // Skip empty lines and WebVTT header
    if (line.isEmpty || line == 'WEBVTT' || line.startsWith('NOTE')) {
      continue;
    }

    // Check for timestamp line (format: 00:00:00.000 --> 00:00:00.000)
    if (line.contains('-->')) {
      final parts = line.split('-->');
      if (parts.length == 2) {
        startTime = _parseTime(parts[0].trim());
        endTime = _parseTime(parts[1].trim().split(' ').first);
        currentText = '';
      }
    } else if (startTime != null && endTime != null && line.isNotEmpty) {
      // This is subtitle text
      if (currentText != null && currentText.isNotEmpty) {
        currentText += '\n$line';
      } else {
        currentText = line;
      }

      // Check if next line is empty or timestamp (end of cue)
      final isLastLine = i + 1 >= lines.length;
      final nextLineEmpty = !isLastLine && lines[i + 1].trim().isEmpty;
      final nextLineIsTimestamp = !isLastLine && lines[i + 1].contains('-->');

      if (isLastLine || nextLineEmpty || nextLineIsTimestamp) {
        // At this point, startTime, endTime, and currentText are guaranteed to be non-null
        // due to the outer else-if condition and the text assignment above
        if (currentText.isNotEmpty) {
          cues.add(
            SubtitleCue(start: startTime, end: endTime, text: currentText),
          );
        }
        currentText = null;
        startTime = null;
        endTime = null;
      }
    }
  }

  // Add last cue if exists
  if (currentText != null && startTime != null && endTime != null) {
    cues.add(SubtitleCue(start: startTime, end: endTime, text: currentText));
  }

  return cues;
}