121 lines
2.6 KiB
Dart
121 lines
2.6 KiB
Dart
// lib/services/audio_service.dart
|
|
import 'dart:async'; // ⬅️ 添加这个导入
|
|
import 'package:flutter/material.dart';
|
|
import 'playback_service.dart';
|
|
|
|
class Song {
|
|
final String id;
|
|
final String title;
|
|
final String artist;
|
|
final String? url;
|
|
|
|
Song({
|
|
required this.id,
|
|
required this.title,
|
|
required this.artist,
|
|
this.url,
|
|
});
|
|
}
|
|
|
|
class AudioService extends ChangeNotifier {
|
|
Song? _currentSong;
|
|
bool _isPlaying = false;
|
|
Duration _position = Duration.zero;
|
|
Duration _duration = Duration.zero;
|
|
|
|
bool _listening = false;
|
|
final List<StreamSubscription> _subscriptions = [];
|
|
|
|
Song? get currentSong => _currentSong;
|
|
bool get isPlaying => _isPlaying;
|
|
Duration get position => _position;
|
|
Duration get duration => _duration;
|
|
|
|
// ✅ 完整的播放入口
|
|
Future<void> playSong(Song song) async {
|
|
_currentSong = song;
|
|
_position = Duration.zero;
|
|
_duration = Duration.zero;
|
|
|
|
_startListening();
|
|
notifyListeners();
|
|
|
|
if (song.url == null || song.url!.isEmpty) {
|
|
return;
|
|
}
|
|
|
|
// 播放由 PlaybackService 执行,状态由 stream 更新
|
|
await PlaybackService().play(song.url!);
|
|
}
|
|
|
|
// ✅ 只调用播放器方法,不手动修改 _isPlaying
|
|
void togglePlay() {
|
|
if (_currentSong == null) return;
|
|
|
|
if (_isPlaying) {
|
|
PlaybackService().pause();
|
|
} else {
|
|
PlaybackService().resume();
|
|
}
|
|
// _isPlaying 由 player.stream.playing 更新
|
|
}
|
|
|
|
void stopPlay() {
|
|
_currentSong = null;
|
|
_isPlaying = false;
|
|
_position = Duration.zero;
|
|
_duration = Duration.zero;
|
|
_stopListening();
|
|
notifyListeners();
|
|
}
|
|
|
|
void seekTo(Duration position) {
|
|
PlaybackService().seek(position);
|
|
_position = position;
|
|
notifyListeners();
|
|
}
|
|
|
|
// ✅ 直接监听 media_kit 的三个独立 Stream
|
|
void _startListening() {
|
|
if (_listening) return;
|
|
_listening = true;
|
|
|
|
final player = PlaybackService().player;
|
|
|
|
_subscriptions.add(
|
|
player.stream.playing.listen((playing) {
|
|
if (_isPlaying != playing) {
|
|
_isPlaying = playing;
|
|
notifyListeners();
|
|
}
|
|
}),
|
|
);
|
|
|
|
_subscriptions.add(
|
|
player.stream.position.listen((position) {
|
|
if (_position != position) {
|
|
_position = position;
|
|
notifyListeners();
|
|
}
|
|
}),
|
|
);
|
|
|
|
_subscriptions.add(
|
|
player.stream.duration.listen((duration) {
|
|
if (_duration != duration) {
|
|
_duration = duration;
|
|
notifyListeners();
|
|
}
|
|
}),
|
|
);
|
|
}
|
|
|
|
void _stopListening() {
|
|
_listening = false;
|
|
for (final subscription in _subscriptions) {
|
|
subscription.cancel();
|
|
}
|
|
_subscriptions.clear();
|
|
}
|
|
}
|