// lib/metadata/metadata_service.dart import 'dart:io'; import 'metadata_model.dart'; import 'metadata_reader.dart'; import 'metadata_normalizer.dart'; import 'metadata_cache.dart'; class MetadataService { static final MetadataService _instance = MetadataService._internal(); factory MetadataService() => _instance; MetadataService._internal(); final MetadataReader _reader = MetadataReader(); final MetadataNormalizer _normalizer = MetadataNormalizer(); final MetadataCache _cache = MetadataCache(); /// 获取歌曲的最终元数据(优先缓存,否则读取文件) Future getMetadata({ required String filePath, required String fileName, required String fileId, bool forceRefresh = false, }) async { // 1. 尝试从缓存读取 if (!forceRefresh) { final cached = await _cache.get(fileId); if (cached != null && cached.isNotEmpty) { return cached; } } // 2. 检查文件是否存在 final file = File(filePath); if (!await file.exists()) { // 文件不存在,返回基于文件名的推断 return _fallbackFromFileName(fileName); } // 3. 从文件读取原始元数据 final raw = await _reader.readRawMetadata(file); // 4. 标准化 final normalized = _normalizer.normalize( raw, fileName: fileName, filePath: filePath, ); // 5. 评估(第一阶段直接接受) final history = await _cache.getHistory(normalized.artist, limit: 10); final candidate = _normalizer.evaluate(normalized, history); // 6. 决策 final finalMetadata = _normalizer.decide(candidate); // 7. 写入缓存 if (finalMetadata.isNotEmpty) { await _cache.put(fileId, finalMetadata); } return finalMetadata; } /// Fallback:从文件名推断 FinalMetadata _fallbackFromFileName(String fileName) { final dotIndex = fileName.lastIndexOf('.'); final title = dotIndex > 0 ? fileName.substring(0, dotIndex) : fileName; return FinalMetadata( title: title, artist: '未知艺术家', source: 'filename', ); } }