Compare commits

..

2 Commits

Author SHA1 Message Date
Seungmin Kim
a98e47a474
Merge 045c865904 into 0ec9f3535b 2025-03-24 21:40:20 +09:00
Seungmin Kim
045c865904 Add ISRC track search for YouTube 2025-03-24 05:40:01 -07:00

View File

@ -242,30 +242,28 @@ class YoutubeSourcedTrack extends SourcedTrack {
}) async { }) async {
List<SiblingType> siblings = []; List<SiblingType> siblings = [];
final isrc = track.externalIds?.isrc; final isrc = track.externalIds?.isrc.toString();
if (isrc != null && isrc.isNotEmpty) { if (isrc != null && isrc.isNotEmpty) {
final isrcResults = final isrcResults =
await ref.read(youtubeEngineProvider).searchVideos(isrc.toString()); await ref.read(youtubeEngineProvider).searchVideos(isrc);
if (isrcResults.isNotEmpty) { if (isrcResults.isNotEmpty) {
final rankedResults = rankResults( final rankedResults = rankResults(
isrcResults.map(YoutubeVideoInfo.fromVideo).toList(), track); isrcResults.map(YoutubeVideoInfo.fromVideo).toList(), track);
final matchingResults = <YoutubeVideoInfo>[]; final matchingResults = <YoutubeVideoInfo>[];
for (final video in rankedResults) { for (final video in rankedResults) {
final titleWords = video.title final titleWords = video.title
.replaceAll(RegExp(r'\((.*)\)'), '')
.toLowerCase() .toLowerCase()
.replaceAll(RegExp(r'[^a-zA-Z0-9\s]+'), '')
.split(RegExp(r'\s+')) .split(RegExp(r'\s+'))
.where((item) => item.isNotEmpty)
.toList(); .toList();
final nameLower = track.name! final nameLower = track.name!
.replaceAll(RegExp(r'\((.*)\)'), '')
.toLowerCase() .toLowerCase()
.replaceAll(RegExp(r'[^a-zA-Z0-9\s]+'), '')
.split(RegExp(r'\s+')) .split(RegExp(r'\s+'))
.where((item) => item.isNotEmpty)
.toList(); .toList();
final matchCount = final matchCount =
titleWords.where((word) => nameLower.contains(word)).length; titleWords.where((word) => nameLower.contains(word)).length;
if (matchCount > nameLower.length / 2) { if (matchCount >= nameLower.length) {
matchingResults.add(video); matchingResults.add(video);
} }
} }
@ -324,16 +322,18 @@ class YoutubeSourcedTrack extends SourcedTrack {
.mapIndexed((index, info) => toSiblingType(index, info, ref)), .mapIndexed((index, info) => toSiblingType(index, info, ref)),
)); ));
} }
return await (() async {
final seenIds = <String>{}; // Deduplicate siblings by info.id, keeping the first occurrence
// Deduplicate siblings by info.id, keeping the first occurrence final seenIds = <String>{};
return await Future.wait(siblings.map((sibling) async { final uniqueSiblings = <SiblingType>[];
if (!seenIds.contains(sibling.info.id)) { for (final sibling in siblings) {
seenIds.add(sibling.info.id); if (!seenIds.contains(sibling.info.id)) {
return sibling; seenIds.add(sibling.info.id);
uniqueSiblings.add(sibling);
}
} }
return null; return uniqueSiblings;
})).then((s) => s.whereType<SiblingType>().toList()); })();
} }
@override @override