Files
QingTing-Player/lib/controllers/playback_controller.dart
T

132 lines
5.5 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 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<void> playFromWebDAV({
required String directoryPath,
required String clickedSongPath,
required List<WebDAVItem> 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<Song> finalQueue = List<Song>.from(queue);
int startIndex = clickedIndex;
if (playMode == PlayMode.shuffle) {
final shuffled = List<Song>.from(queue)..shuffle();
startIndex = shuffled.indexWhere((s) => s.id == clickedSongPath);
if (startIndex == -1) startIndex = 0;
finalQueue = shuffled;
}
_audioService.setQueue(finalQueue, startIndex: startIndex);
}
// ════════════════════════════════════════════════════════════
// 播放整个目录(从第一首开始)
// ════════════════════════════════════════════════════════════
Future<void> playAllFromWebDAV({
required String directoryPath,
required List<WebDAVItem> allItems,
}) async {
final musicFiles = allItems.where((item) => !item.isDirectory).toList();
if (musicFiles.isEmpty) return;
final queue = await _buildSongQueue(musicFiles);
final playMode = _audioService.playMode;
// ⭐ 修复:显式指定类型
List<Song> finalQueue = List<Song>.from(queue);
if (playMode == PlayMode.shuffle) {
finalQueue = List<Song>.from(queue)..shuffle();
}
_audioService.setQueue(finalQueue, startIndex: 0);
}
// ════════════════════════════════════════════════════════════
// 播放单曲(fallback
// ════════════════════════════════════════════════════════════
Future<void> _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<List<Song>> _buildSongQueue(List<WebDAVItem> musicFiles) async {
final queue = <Song>[];
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;
}