// lib/controllers/playback_controller.dart import '../services/audio_service.dart'; import '../services/webdav_service.dart'; import '../database/song_database.dart'; class PlaybackController { static final PlaybackController _instance = PlaybackController._internal(); factory PlaybackController() => _instance; PlaybackController._internal(); final AudioService _audioService = AudioService(); final SongDatabase _db = SongDatabase(); // ════════════════════════════════════════════════════════════ // 播放 WebDAV 目录中的歌曲(从点击歌曲开始) // ════════════════════════════════════════════════════════════ Future playFromWebDAV({ required String directoryPath, required String clickedSongPath, required List allItems, }) async { final musicFiles = allItems.where((item) => !item.isDirectory).toList(); if (musicFiles.isEmpty) return; final clickedIndex = musicFiles.indexWhere((item) => item.path == clickedSongPath); if (clickedIndex == -1) { await _playSingleSong(clickedSongPath); return; } final queue = await _buildSongQueue(musicFiles); final playMode = _audioService.playMode; // ⭐ 修复:显式指定类型 List finalQueue = List.from(queue); int startIndex = clickedIndex; if (playMode == PlayMode.shuffle) { final shuffled = List.from(queue)..shuffle(); startIndex = shuffled.indexWhere((s) => s.id == clickedSongPath); if (startIndex == -1) startIndex = 0; finalQueue = shuffled; } _audioService.setQueue(finalQueue, startIndex: startIndex); } // ════════════════════════════════════════════════════════════ // 播放整个目录(从第一首开始) // ════════════════════════════════════════════════════════════ Future playAllFromWebDAV({ required String directoryPath, required List allItems, }) async { final musicFiles = allItems.where((item) => !item.isDirectory).toList(); if (musicFiles.isEmpty) return; final queue = await _buildSongQueue(musicFiles); final playMode = _audioService.playMode; // ⭐ 修复:显式指定类型 List finalQueue = List.from(queue); if (playMode == PlayMode.shuffle) { finalQueue = List.from(queue)..shuffle(); } _audioService.setQueue(finalQueue, startIndex: 0); } // ════════════════════════════════════════════════════════════ // 播放单曲(fallback) // ════════════════════════════════════════════════════════════ Future _playSingleSong(String songPath) async { final url = WebDAVService.instance.getFileUrl(songPath); final dbSong = await _db.getSongByPath(songPath); final song = Song( id: songPath, title: dbSong?['title'] as String? ?? songPath.split('/').last.replaceAll(RegExp(r'\.[^.]*$'), ''), artist: dbSong?['artist'] as String? ?? '未知艺术家', url: url, ); _audioService.playSong(song); } // ════════════════════════════════════════════════════════════ // 辅助方法:从音乐文件列表构建 Song 队列 // ════════════════════════════════════════════════════════════ Future> _buildSongQueue(List musicFiles) async { final queue = []; for (final item in musicFiles) { final dbSong = await _db.getSongByPath(item.path); final url = WebDAVService.instance.getFileUrl(item.path); if (dbSong != null) { queue.add(Song( id: item.path, title: dbSong['title'] as String? ?? item.name.replaceAll(RegExp(r'\.[^.]*$'), ''), artist: dbSong['artist'] as String? ?? '未知艺术家', url: url, )); } else { queue.add(Song( id: item.path, title: item.name.replaceAll(RegExp(r'\.[^.]*$'), ''), artist: '未知艺术家', url: url, )); } } return queue; } // ════════════════════════════════════════════════════════════ // 播放控制(透传到 AudioService) // ════════════════════════════════════════════════════════════ void next() { _audioService.next(); } void previous() { _audioService.previous(); } void togglePlayMode() { _audioService.togglePlayMode(); } PlayMode get playMode => _audioService.playMode; }