90 lines
2.8 KiB
Dart
90 lines
2.8 KiB
Dart
// lib/metadata/metadata_normalizer.dart
|
|
import 'metadata_model.dart';
|
|
|
|
class MetadataNormalizer {
|
|
NormalizedMetadata normalize(RawMetadata raw,
|
|
{String fileName = '', String filePath = ''}) {
|
|
// 1. 修剪空格
|
|
final title = raw.title.trim();
|
|
final artist = raw.artist.trim();
|
|
final album = raw.album.trim();
|
|
|
|
// 2. 如果 title 为空,从文件名推断
|
|
final finalTitle =
|
|
title.isNotEmpty ? title : _inferTitleFromFileName(fileName);
|
|
|
|
// 3. 如果 artist 为空,从路径推断或使用默认值
|
|
final finalArtist =
|
|
artist.isNotEmpty ? artist : _inferArtistFromPath(filePath);
|
|
|
|
// 4. 如果 performers 不为空且 artist 为空,用 performers 的第一个
|
|
final finalArtist2 = finalArtist.isNotEmpty
|
|
? finalArtist
|
|
: (raw.performers.isNotEmpty ? raw.performers.first : '未知艺术家');
|
|
|
|
return NormalizedMetadata(
|
|
title: finalTitle,
|
|
artist: finalArtist2,
|
|
album: album,
|
|
genres: raw.genres,
|
|
performers: raw.performers,
|
|
year: raw.year,
|
|
trackNumber: raw.trackNumber,
|
|
trackTotal: raw.trackTotal,
|
|
discNumber: raw.discNumber,
|
|
totalDisc: raw.totalDisc,
|
|
duration: raw.duration,
|
|
artwork: raw.artwork,
|
|
);
|
|
}
|
|
|
|
String _inferTitleFromFileName(String fileName) {
|
|
final dotIndex = fileName.lastIndexOf('.');
|
|
if (dotIndex > 0) {
|
|
return fileName.substring(0, dotIndex).trim();
|
|
}
|
|
return fileName.trim();
|
|
}
|
|
|
|
String _inferArtistFromPath(String filePath) {
|
|
final parts = filePath.split(RegExp(r'[/\\]'));
|
|
if (parts.length >= 2) {
|
|
final candidate = parts[parts.length - 2].trim();
|
|
if (candidate.isNotEmpty && !candidate.contains(' ')) {
|
|
return candidate;
|
|
}
|
|
}
|
|
return '未知艺术家';
|
|
}
|
|
|
|
CandidateMetadata evaluate(
|
|
NormalizedMetadata normalized, List<Map<String, dynamic>> history) {
|
|
return CandidateMetadata(
|
|
metadata: normalized,
|
|
confidence: 0.8,
|
|
evidence: {'normalized': 0.8},
|
|
);
|
|
}
|
|
|
|
FinalMetadata decide(CandidateMetadata candidate, {double threshold = 0.6}) {
|
|
return FinalMetadata(
|
|
title: candidate.metadata.title,
|
|
artist: candidate.metadata.artist,
|
|
album: candidate.metadata.album,
|
|
genre: candidate.metadata.genres.isNotEmpty
|
|
? candidate.metadata.genres.first
|
|
: '',
|
|
genres: candidate.metadata.genres,
|
|
performers: candidate.metadata.performers,
|
|
year: candidate.metadata.year,
|
|
trackNumber: candidate.metadata.trackNumber,
|
|
trackTotal: candidate.metadata.trackTotal,
|
|
discNumber: candidate.metadata.discNumber,
|
|
totalDisc: candidate.metadata.totalDisc,
|
|
duration: candidate.metadata.duration,
|
|
artwork: candidate.metadata.artwork,
|
|
source: 'normalized',
|
|
);
|
|
}
|
|
}
|