From 3a60cabca54b42d24a56b776e305c5d194f77157 Mon Sep 17 00:00:00 2001 From: lxh2875931338 Date: Sun, 1 Nov 2026 16:34:44 +0800 Subject: [PATCH] =?UTF-8?q?fix(playback):=20=E6=AD=8C=E5=8D=95/=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E5=88=97=E8=A1=A8=E6=92=AD=E6=94=BE=E6=97=B6=E6=A0=87?= =?UTF-8?q?=E9=A2=98=E4=B8=8D=E5=86=8D=E6=98=BE=E7=A4=BA=E7=99=BE=E5=88=86?= =?UTF-8?q?=E5=8F=B7=E7=BC=96=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 播放路径是编码的,无元数据时直接截取文件名会显示 "%E6%9C%AA%E5%88%86..." 这种串。 - playPlaylist:统一解码后再去扩展名,DB 标题为空也回退到解码名 - PlaybackController:单曲与队列构建同样走 _displayName() - 有标签时仍优先用标签标题 --- lib/controllers/playback_controller.dart | 23 ++++++++++---- lib/services/audio_service.dart | 38 ++++++++++++++---------- 2 files changed, 40 insertions(+), 21 deletions(-) diff --git a/lib/controllers/playback_controller.dart b/lib/controllers/playback_controller.dart index 1605de0..c4962af 100644 --- a/lib/controllers/playback_controller.dart +++ b/lib/controllers/playback_controller.dart @@ -92,6 +92,17 @@ class PlaybackController { // ════════════════════════════════════════════════════════════ // 单曲播放(fallback) // ════════════════════════════════════════════════════════════ + /// 播放路径/文件名是百分号编码的,展示前必须解码 + String _displayName(String pathOrName) { + final raw = pathOrName.split('/').last; + String decoded; + try { + decoded = Uri.decodeComponent(raw); + } catch (_) { + decoded = raw; + } + return decoded.replaceAll(RegExp(r'\.[^.]*$'), ''); + } Future _playSingleSong(String songPath) async { debugPrint('🎯 [PlaybackController] _playSingleSong: $songPath'); final url = WebDAVService.instance.getFileUrl(songPath); @@ -99,8 +110,9 @@ class PlaybackController { final song = Song( id: songPath, artworkPath: dbSong?['artwork_path'] as String?, - title: dbSong?['title'] as String? ?? - songPath.split('/').last.replaceAll(RegExp(r'\.[^.]*$'), ''), + title: (dbSong?['title'] as String?)?.trim().isNotEmpty == true + ? dbSong!['title'] as String + : _displayName(songPath), artist: dbSong?['artist'] as String? ?? '未知艺术家', url: url, ); @@ -119,15 +131,16 @@ class PlaybackController { queue.add(Song( id: item.path, artworkPath: dbSong['artwork_path'] as String?, - title: dbSong['title'] as String? ?? - item.name.replaceAll(RegExp(r'\.[^.]*$'), ''), + title: (dbSong['title'] as String?)?.trim().isNotEmpty == true + ? dbSong['title'] as String + : _displayName(item.path), artist: dbSong['artist'] as String? ?? '未知艺术家', url: url, )); } else { queue.add(Song( id: item.path, - title: item.name.replaceAll(RegExp(r'\.[^.]*$'), ''), + title: _displayName(item.path), artist: '未知艺术家', url: url, )); diff --git a/lib/services/audio_service.dart b/lib/services/audio_service.dart index e591648..41d2d74 100644 --- a/lib/services/audio_service.dart +++ b/lib/services/audio_service.dart @@ -300,23 +300,29 @@ class AudioService extends ChangeNotifier { final songs = []; for (final id in songIds) { final dbSong = await _db.getSongByPath(id); - if (dbSong != null) { - final path = dbSong['remote_path'] as String; - songs.add(Song( - id: path, - artworkPath: dbSong['artwork_path'] as String?, - title: dbSong['title'] as String? ?? '', - artist: dbSong['artist'] as String? ?? '未知艺术家', - url: WebDAVService.instance.getFileUrl(path), - )); - } else { - songs.add(Song( - id: id, - title: id.split('/').last.replaceAll(RegExp(r'\.[^.]*$'), ''), - artist: '未知艺术家', - url: WebDAVService.instance.getFileUrl(id), - )); + final path = (dbSong?['remote_path'] as String?) ?? id; + + // 没有标签时回退文件名,必须解码:id 是百分号编码的播放路径, + // 直接展示会变成 "%E6%9C%AA..." 这种不可读串。 + final rawName = path.split('/').last; + String displayName; + try { + displayName = Uri.decodeComponent(rawName); + } catch (_) { + displayName = rawName; } + displayName = displayName.replaceAll(RegExp(r'\.[^.]*$'), ''); + + final dbTitle = (dbSong?['title'] as String?)?.trim() ?? ''; + final dbArtist = (dbSong?['artist'] as String?)?.trim() ?? ''; + + songs.add(Song( + id: path, + artworkPath: dbSong?['artwork_path'] as String?, + title: dbTitle.isNotEmpty ? dbTitle : displayName, + artist: dbArtist.isNotEmpty ? dbArtist : '未知艺术家', + url: WebDAVService.instance.getFileUrl(path), + )); } if (songs.isNotEmpty) {