134 lines
3.7 KiB
Dart
134 lines
3.7 KiB
Dart
// ignore: file_names
|
|
class ParserSRT {
|
|
Subtitles getSubtitlesData(
|
|
String subtitlesContent,
|
|
SubtitleType subtitleType,
|
|
) {
|
|
RegExp regExp;
|
|
if (subtitleType == SubtitleType.webvtt) {
|
|
regExp = RegExp(
|
|
r'((\d{2}):(\d{2}):(\d{2})\.(\d+)) +--> +((\d{2}):(\d{2}):(\d{2})\.(\d{3})).*[\r\n]+\s*((?:(?!\r?\n\r?).)*(\r\n|\r|\n)(?:.*))',
|
|
caseSensitive: false,
|
|
multiLine: true,
|
|
);
|
|
} else if (subtitleType == SubtitleType.srt) {
|
|
regExp = RegExp(
|
|
r'((\d{2}):(\d{2}):(\d{2})\,(\d+)) +--> +((\d{2}):(\d{2}):(\d{2})\,(\d{3})).*[\r\n]+\s*((?:(?!\r?\n\r?).)*(\r\n|\r|\n)(?:.*))',
|
|
caseSensitive: false,
|
|
multiLine: true,
|
|
);
|
|
} else {
|
|
throw Exception('Incorrect subtitle type');
|
|
}
|
|
|
|
final matches = regExp.allMatches(subtitlesContent).toList();
|
|
final subtitleList = <Subtitle>[];
|
|
|
|
for (final regExpMatch in matches) {
|
|
final startTimeHours = int.parse(regExpMatch.group(2)!);
|
|
final startTimeMinutes = int.parse(regExpMatch.group(3)!);
|
|
final startTimeSeconds = int.parse(regExpMatch.group(4)!);
|
|
final startTimeMilliseconds = int.parse(regExpMatch.group(5)!);
|
|
|
|
final endTimeHours = int.parse(regExpMatch.group(7)!);
|
|
final endTimeMinutes = int.parse(regExpMatch.group(8)!);
|
|
final endTimeSeconds = int.parse(regExpMatch.group(9)!);
|
|
final endTimeMilliseconds = int.parse(regExpMatch.group(10)!);
|
|
final text = removeAllHtmlTags(regExpMatch.group(11)!);
|
|
|
|
final startTime = Time(Duration(
|
|
hours: startTimeHours,
|
|
minutes: startTimeMinutes,
|
|
seconds: startTimeSeconds,
|
|
milliseconds: startTimeMilliseconds,
|
|
));
|
|
final endTime = Time(Duration(
|
|
hours: endTimeHours,
|
|
minutes: endTimeMinutes,
|
|
seconds: endTimeSeconds,
|
|
milliseconds: endTimeMilliseconds,
|
|
));
|
|
|
|
subtitleList.add(
|
|
Subtitle(startTime: startTime, endTime: endTime, text: text.trim()),
|
|
);
|
|
}
|
|
|
|
return Subtitles(subtitles: subtitleList);
|
|
}
|
|
|
|
String removeAllHtmlTags(String htmlText) {
|
|
final exp = RegExp(
|
|
'(<[^>]*>)',
|
|
multiLine: true,
|
|
);
|
|
var newHtmlText = htmlText;
|
|
exp.allMatches(htmlText).toList().forEach(
|
|
(RegExpMatch regExpMatch) {
|
|
newHtmlText = regExpMatch.group(0) == '<br>'
|
|
? newHtmlText.replaceAll(regExpMatch.group(0)!, '\n')
|
|
: newHtmlText.replaceAll(regExpMatch.group(0)!, '');
|
|
},
|
|
);
|
|
|
|
return newHtmlText;
|
|
}
|
|
}
|
|
|
|
class Subtitles {
|
|
Subtitles({
|
|
required this.subtitles,
|
|
});
|
|
final List<Subtitle> subtitles;
|
|
}
|
|
|
|
class Subtitle {
|
|
Subtitle({
|
|
required this.startTime,
|
|
required this.endTime,
|
|
required this.text,
|
|
});
|
|
Time startTime;
|
|
Time endTime;
|
|
String text;
|
|
|
|
List<Object?> get props => [startTime, endTime, text];
|
|
}
|
|
|
|
enum SubtitleType {
|
|
webvtt,
|
|
srt,
|
|
}
|
|
|
|
class Time {
|
|
Time(Duration duration) {
|
|
this.duration = duration;
|
|
}
|
|
|
|
late Duration _duration;
|
|
Duration get duration => _duration;
|
|
set duration(Duration value) {
|
|
_duration = value;
|
|
var timeStr = duration.toString();
|
|
var timeArr = timeStr.substring(0, timeStr.lastIndexOf('.') + 4).split(':');
|
|
hour = int.parse(timeArr[0]);
|
|
minutes = int.parse(timeArr[1]);
|
|
var secArr = timeArr[2].split('.');
|
|
seconds = int.parse(secArr[0]);
|
|
milliseconds = int.parse(secArr[1]);
|
|
}
|
|
|
|
late int hour;
|
|
late int minutes;
|
|
late int seconds;
|
|
late int milliseconds;
|
|
|
|
Duration get before {
|
|
return Duration(milliseconds: duration.inMilliseconds - 1);
|
|
}
|
|
|
|
@override
|
|
String toString() {
|
|
return '${hour.toString().padLeft(2, '0')}:${minutes.toString().padLeft(2, '0')}:${seconds.toString().padLeft(2, '0')}.${milliseconds.toString().padLeft(3, '0')}';
|
|
}
|
|
}
|