86 lines
2.7 KiB
Dart
86 lines
2.7 KiB
Dart
// lib/metadata/metadata_normalizer.dart
|
|
import 'metadata_model.dart';
|
|
|
|
class MetadataNormalizer {
|
|
/// 标准化原始数据(清洗空格、推断、fallback)
|
|
NormalizedMetadata normalize(RawMetadata raw,
|
|
{String fileName = '', String filePath = ''}) {
|
|
// 1. 修剪空格
|
|
final title = raw.title.trim();
|
|
final artist = raw.artist.trim();
|
|
final album = raw.album.trim();
|
|
final albumArtist = raw.albumArtist.trim();
|
|
|
|
// 2. 如果 title 为空,尝试从文件名推断
|
|
final finalTitle =
|
|
title.isNotEmpty ? title : _inferTitleFromFileName(fileName);
|
|
|
|
// 3. 如果 artist 为空,尝试从路径推断或使用默认值
|
|
final finalArtist =
|
|
artist.isNotEmpty ? artist : _inferArtistFromPath(filePath);
|
|
|
|
return NormalizedMetadata(
|
|
title: finalTitle,
|
|
artist: finalArtist,
|
|
album: album,
|
|
albumArtist: albumArtist,
|
|
composer: raw.composer.trim(),
|
|
genre: raw.genre.trim(),
|
|
year: raw.year,
|
|
trackNumber: raw.trackNumber,
|
|
discNumber: raw.discNumber,
|
|
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) {
|
|
// 第一阶段:置信度固定为 0.8(文件名+标签混合)
|
|
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,
|
|
albumArtist: candidate.metadata.albumArtist,
|
|
composer: candidate.metadata.composer,
|
|
genre: candidate.metadata.genre,
|
|
year: candidate.metadata.year,
|
|
trackNumber: candidate.metadata.trackNumber,
|
|
discNumber: candidate.metadata.discNumber,
|
|
artwork: candidate.metadata.artwork,
|
|
source: 'normalized',
|
|
);
|
|
}
|
|
}
|