Files
QingTing-Player/lib/services/audio_service.dart
T

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();
}
}