dart-app-core/lib/subtitle/ParserSRT.dart
2023-03-26 01:48:46 +09:00

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')}';
}
}