Files
sm-emby-share/lib/core/media/danmaku_comment_merger.dart
2026-07-14 11:11:36 +08:00

56 lines
1.4 KiB
Dart

import '../contracts/danmaku.dart';
const defaultDuplicateDanmakuMergeWindowSeconds = 1.0;
final _whitespacePattern = RegExp(r'\s+');
List<DanmakuComment> mergeDuplicateDanmakuComments(
Iterable<DanmakuComment> comments, {
double windowSeconds = defaultDuplicateDanmakuMergeWindowSeconds,
}) {
if (windowSeconds < 0) {
throw ArgumentError.value(
windowSeconds,
'windowSeconds',
'must be non-negative',
);
}
final sorted = comments.toList()..sort(_compareDanmakuComments);
if (sorted.length < 2) return sorted;
final keptByText = <String, List<DanmakuComment>>{};
final passthrough = <DanmakuComment>[];
for (final comment in sorted) {
final key = _mergeKey(comment);
if (key.isEmpty) {
passthrough.add(comment);
continue;
}
final kept = keptByText.putIfAbsent(key, () => []);
final windowStart = kept.isEmpty ? null : kept.last.time;
if (windowStart == null || comment.time - windowStart > windowSeconds) {
kept.add(comment);
}
}
return <DanmakuComment>[
...passthrough,
for (final kept in keptByText.values) ...kept,
]..sort(_compareDanmakuComments);
}
int _compareDanmakuComments(DanmakuComment a, DanmakuComment b) {
final timeOrder = a.time.compareTo(b.time);
if (timeOrder != 0) return timeOrder;
return a.cid.compareTo(b.cid);
}
String _mergeKey(DanmakuComment comment) {
return comment.text.trim().replaceAll(_whitespacePattern, ' ');
}