From fe3b7de20aca078ccc67265244e14d9343c99543 Mon Sep 17 00:00:00 2001 From: lxh2875931338 Date: Sun, 23 Aug 2026 17:55:04 +0800 Subject: [PATCH] =?UTF-8?q?=E5=85=A8=E9=83=A8=E5=8C=85=E5=90=8D=E4=B8=8E?= =?UTF-8?q?=E5=90=8D=E7=A7=B0=E7=A1=AE=E5=AE=9A=EF=BC=8C=E5=90=8E=E5=8F=B0?= =?UTF-8?q?=E6=92=AD=E6=94=BE=E8=83=BD=E5=8A=9B=E5=B7=B2=E5=AE=8C=E6=95=B4?= =?UTF-8?q?=EF=BC=8C=E5=87=86=E5=A4=87=E8=BF=9B=E5=85=A5=E5=AA=92=E4=BD=93?= =?UTF-8?q?=E4=BF=A1=E6=81=AF=E6=8E=A8=E9=80=81=E9=83=A8=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- android/app/src/main/AndroidManifest.xml | 2 +- lib/main.dart | 6 ++-- lib/services/audio_player_handler.dart | 37 ++++++++++-------------- lib/services/audio_service.dart | 27 ++++++++++++----- pubspec.yaml | 2 +- 5 files changed, 39 insertions(+), 35 deletions(-) diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index bfeb3ed..9c4617e 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -8,7 +8,7 @@ { builder: () => _audioHandler!, config: const audio_service.AudioServiceConfig( androidNotificationChannelId: 'com.lxh.qingting_player.music', - androidNotificationChannelName: '清听音乐播放', - androidNotificationOngoing: true, - androidStopForegroundOnPause: true, + androidNotificationChannelName: '清听', + androidNotificationOngoing: false, + androidStopForegroundOnPause: false, ), ); debugPrint('✅ AudioService 初始化完成'); diff --git a/lib/services/audio_player_handler.dart b/lib/services/audio_player_handler.dart index 0620bc5..dd32d65 100644 --- a/lib/services/audio_player_handler.dart +++ b/lib/services/audio_player_handler.dart @@ -1,15 +1,17 @@ // lib/services/audio_player_handler.dart + import 'package:flutter/foundation.dart'; import 'package:audio_service/audio_service.dart' as audio_service; import '../audio/player_controller.dart'; import '../audio/playback_state_manager.dart'; -import '../services/audio_service.dart'; // 你的业务 AudioService +import '../services/audio_service.dart'; // 你自己的业务 AudioService class AudioPlayerHandler extends audio_service.BaseAudioHandler { final PlayerController _player = PlayerController(); final PlaybackStateManager _state = PlaybackStateManager(); AudioPlayerHandler() { + // ---- 监听播放状态变化,同步到通知栏 ---- _player.playingStream.listen((playing) { _state.updatePlaying(playing); _publishState(); @@ -32,22 +34,12 @@ class AudioPlayerHandler extends audio_service.BaseAudioHandler { _publishState(); }); - _player.completedStream.listen((_) { - debugPrint('⏭️ [handler] completed, auto next'); - AudioService().next(); - }); + // ⭐ 已删除 completed 监听,交由 AudioService 统一处理 + // _player.completedStream.listen((_) { ... }); } void _publishState() { - final state = _state.playbackState; - - debugPrint( - '📡 [publish] ' - 'playing=${state.playing}, ' - 'controls=${state.controls.map((e) => e.action).toList()}', - ); - - playbackState.add(state); + playbackState.add(_state.playbackState); } void updateNotification({ @@ -64,17 +56,17 @@ class AudioPlayerHandler extends audio_service.BaseAudioHandler { )); } - // ---- 控制命令(系统回调) ---- + // ---- 系统控制命令 ---- @override Future play() async { debugPrint('▶️ [handler] play() called'); - await _player.play(); + _player.play(); } @override Future pause() async { debugPrint('⏸️ [handler] pause() called'); - await _player.pause(); + _player.pause(); } @override @@ -101,7 +93,6 @@ class AudioPlayerHandler extends audio_service.BaseAudioHandler { AudioService().previous(); } - // ⭐ 统一点击处理(仅使用 MediaButton 存在的枚举) @override Future click( [audio_service.MediaButton button = @@ -115,7 +106,6 @@ class AudioPlayerHandler extends audio_service.BaseAudioHandler { await skipToPrevious(); break; case audio_service.MediaButton.media: - // 播放/暂停切换 if (_player.isPlaying) { await pause(); } else { @@ -123,9 +113,12 @@ class AudioPlayerHandler extends audio_service.BaseAudioHandler { } break; default: - // 其他按钮(fastForward, rewind等)忽略或fallback - debugPrint('⚠️ [handler] unhandled MediaButton: $button'); - break; + // 其他按钮 fallback + if (_player.isPlaying) { + await pause(); + } else { + await play(); + } } } } diff --git a/lib/services/audio_service.dart b/lib/services/audio_service.dart index 94319c8..3c81af7 100644 --- a/lib/services/audio_service.dart +++ b/lib/services/audio_service.dart @@ -48,6 +48,9 @@ class AudioService extends ChangeNotifier { bool _listening = false; final List _subscriptions = []; + // ⭐ 防重入标志 + bool _handlingCompletion = false; + // ---- Getter(高频字段不走 ChangeNotifier) ---- Song? get currentSong => _currentSong; bool get isPlaying => _isPlaying; @@ -240,12 +243,11 @@ class AudioService extends ChangeNotifier { player.stream.playing.listen((playing) { if (_isPlaying != playing) { _isPlaying = playing; - notifyListeners(); // 只有播放状态变化才刷新 + notifyListeners(); } }), ); - // ⭐ 进度更新:只更新 ValueNotifier,不触发全局重建 _subscriptions.add( player.stream.position.listen((position) { positionNotifier.value = position; @@ -264,6 +266,7 @@ class AudioService extends ChangeNotifier { }), ); + // ⭐ 唯一监听 completed 的地方 _subscriptions.add( player.stream.completed.listen((_) { _onPlaybackCompleted(); @@ -279,15 +282,23 @@ class AudioService extends ChangeNotifier { _subscriptions.clear(); } + // ⭐ 防重入 void _onPlaybackCompleted() { - if (_queue.isEmpty) return; - - if (_playMode == PlayMode.repeatOne) { - _playCurrent(); + if (_handlingCompletion) { + debugPrint('⚠️ [service] completed ignored: already handling'); return; } - - next(); + _handlingCompletion = true; + try { + if (_queue.isEmpty) return; + if (_playMode == PlayMode.repeatOne) { + _playCurrent(); + return; + } + next(); + } finally { + _handlingCompletion = false; + } } @override diff --git a/pubspec.yaml b/pubspec.yaml index 376d56a..d9abdb2 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,4 +1,4 @@ -name: qt_player +name: qingting_player description: "清听 - 纯粹的自用音乐播放器" # The following line prevents the package from being accidentally published to # pub.dev using `flutter pub publish`. This is preferred for private packages.