|
|
@ -1,5 +1,4 @@ |
|
|
import 'dart:async'; |
|
|
import 'dart:async'; |
|
|
import 'dart:ffi'; |
|
|
|
|
|
import 'package:get/get.dart'; |
|
|
import 'package:get/get.dart'; |
|
|
import 'package:qq_music/qq_music.dart'; |
|
|
import 'package:qq_music/qq_music.dart'; |
|
|
import '../models/song_model.dart'; |
|
|
import '../models/song_model.dart'; |
|
|
@ -17,36 +16,10 @@ class QqMusicService extends GetxService { |
|
|
final currentPosition = 0.obs; // 毫秒 |
|
|
final currentPosition = 0.obs; // 毫秒 |
|
|
final totalDuration = 0.obs; // 毫秒 |
|
|
final totalDuration = 0.obs; // 毫秒 |
|
|
final currentSong = Rxn<SongModel>(); |
|
|
final currentSong = Rxn<SongModel>(); |
|
|
// final playlist = <SongModel>[].obs; |
|
|
|
|
|
// final currentIndex = 0.obs; |
|
|
|
|
|
|
|
|
|
|
|
// 状态监听定时器 |
|
|
// 状态监听定时器 |
|
|
Timer? _stateMonitorTimer; |
|
|
Timer? _stateMonitorTimer; |
|
|
|
|
|
|
|
|
// 监听器列表 - 用于通知页面状态变化 |
|
|
|
|
|
final List<Function()> _listeners = []; |
|
|
|
|
|
|
|
|
|
|
|
/// 初始化插件并尝试自动登录 |
|
|
|
|
|
Future<void> initializePlugin() async { |
|
|
|
|
|
try { |
|
|
|
|
|
// 先触发插件注册 |
|
|
|
|
|
// await _qqMusic.getPlatformVersion(); |
|
|
|
|
|
|
|
|
|
|
|
// 尝试自动登录 |
|
|
|
|
|
final result = await _qqMusic.login(); |
|
|
|
|
|
if (result['success'] == true) { |
|
|
|
|
|
print('QQ音乐自动登录成功: ${result['openId']}'); |
|
|
|
|
|
Future.delayed(Duration(milliseconds: 1000), () { |
|
|
|
|
|
syncCurrentPlayInfo(); |
|
|
|
|
|
}); |
|
|
|
|
|
} else { |
|
|
|
|
|
print('QQ音乐自动登录失败: ${result['error']}'); |
|
|
|
|
|
} |
|
|
|
|
|
} catch (e) { |
|
|
|
|
|
print('QQ音乐插件初始化失败: $e'); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@override |
|
|
@override |
|
|
void onInit() { |
|
|
void onInit() { |
|
|
super.onInit(); |
|
|
super.onInit(); |
|
|
@ -58,32 +31,11 @@ class QqMusicService extends GetxService { |
|
|
@override |
|
|
@override |
|
|
void onClose() { |
|
|
void onClose() { |
|
|
_stateMonitorTimer?.cancel(); |
|
|
_stateMonitorTimer?.cancel(); |
|
|
_listeners.clear(); |
|
|
|
|
|
print('🎵 [QQMusicService] 全局音乐服务销毁'); |
|
|
print('🎵 [QQMusicService] 全局音乐服务销毁'); |
|
|
super.onClose(); |
|
|
super.onClose(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/// 添加状态监听器 |
|
|
|
|
|
void addListener(Function() listener) { |
|
|
|
|
|
_listeners.add(listener); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// 移除状态监听器 |
|
|
|
|
|
void removeListener(Function() listener) { |
|
|
|
|
|
_listeners.remove(listener); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// 通知所有监听器 |
|
|
|
|
|
void _notifyListeners() { |
|
|
|
|
|
for (final listener in _listeners) { |
|
|
|
|
|
try { |
|
|
|
|
|
listener(); |
|
|
|
|
|
} catch (e) { |
|
|
|
|
|
print('🔥 [QQMusicService] 监听器回调异常: $e'); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// 启动播放状态监控 |
|
|
/// 启动播放状态监控 |
|
|
void startPlaybackStateMonitor() { |
|
|
void startPlaybackStateMonitor() { |
|
|
// 取消之前的定时器 |
|
|
// 取消之前的定时器 |
|
|
@ -141,7 +93,6 @@ class QqMusicService extends GetxService { |
|
|
if (wasPlaying && !newIsPlaying) { |
|
|
if (wasPlaying && !newIsPlaying) { |
|
|
print('⏹️ [QQMusicService] 检测到播放停止,自动停止全局监听'); |
|
|
print('⏹️ [QQMusicService] 检测到播放停止,自动停止全局监听'); |
|
|
stopPlaybackStateMonitor(); |
|
|
stopPlaybackStateMonitor(); |
|
|
_notifyListeners(); |
|
|
|
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -149,7 +100,6 @@ class QqMusicService extends GetxService { |
|
|
if (!newIsPlaying) { |
|
|
if (!newIsPlaying) { |
|
|
print('⏸️ [QQMusicService] 当前未在播放,停止全局监听以节省资源'); |
|
|
print('⏸️ [QQMusicService] 当前未在播放,停止全局监听以节省资源'); |
|
|
stopPlaybackStateMonitor(); |
|
|
stopPlaybackStateMonitor(); |
|
|
_notifyListeners(); |
|
|
|
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -185,9 +135,6 @@ class QqMusicService extends GetxService { |
|
|
currentSong.value = newSong; |
|
|
currentSong.value = newSong; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 通知所有监听器 |
|
|
|
|
|
_notifyListeners(); |
|
|
|
|
|
} else { |
|
|
} else { |
|
|
// 同步失败时停止监听 |
|
|
// 同步失败时停止监听 |
|
|
print('❌ [QQMusicService] 全局同步失败,停止监听'); |
|
|
print('❌ [QQMusicService] 全局同步失败,停止监听'); |
|
|
@ -276,7 +223,6 @@ class QqMusicService extends GetxService { |
|
|
Future.delayed(Duration(seconds: 1), () { |
|
|
Future.delayed(Duration(seconds: 1), () { |
|
|
syncCurrentPlayInfo(); |
|
|
syncCurrentPlayInfo(); |
|
|
}); |
|
|
}); |
|
|
_notifyListeners(); |
|
|
|
|
|
} else { |
|
|
} else { |
|
|
isPlaying.value = false; |
|
|
isPlaying.value = false; |
|
|
currentPosition.value = 0; |
|
|
currentPosition.value = 0; |
|
|
@ -300,8 +246,6 @@ class QqMusicService extends GetxService { |
|
|
Future.delayed(Duration(milliseconds: 500), () { |
|
|
Future.delayed(Duration(milliseconds: 500), () { |
|
|
syncCurrentPlayInfo(); |
|
|
syncCurrentPlayInfo(); |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
_notifyListeners(); |
|
|
|
|
|
} |
|
|
} |
|
|
return result; |
|
|
return result; |
|
|
} catch (e) { |
|
|
} catch (e) { |
|
|
@ -315,7 +259,6 @@ class QqMusicService extends GetxService { |
|
|
final result = await _qqMusic.pauseMusic(); |
|
|
final result = await _qqMusic.pauseMusic(); |
|
|
if (result['success'] == true) { |
|
|
if (result['success'] == true) { |
|
|
isPlaying.value = false; |
|
|
isPlaying.value = false; |
|
|
_notifyListeners(); |
|
|
|
|
|
} |
|
|
} |
|
|
return result; |
|
|
return result; |
|
|
} catch (e) { |
|
|
} catch (e) { |
|
|
@ -330,7 +273,6 @@ class QqMusicService extends GetxService { |
|
|
if (result['success'] == true) { |
|
|
if (result['success'] == true) { |
|
|
isPlaying.value = true; |
|
|
isPlaying.value = true; |
|
|
startPlaybackStateMonitor(); |
|
|
startPlaybackStateMonitor(); |
|
|
_notifyListeners(); |
|
|
|
|
|
} |
|
|
} |
|
|
return result; |
|
|
return result; |
|
|
} catch (e) { |
|
|
} catch (e) { |
|
|
@ -346,7 +288,6 @@ class QqMusicService extends GetxService { |
|
|
isPlaying.value = false; |
|
|
isPlaying.value = false; |
|
|
currentPosition.value = 0; |
|
|
currentPosition.value = 0; |
|
|
stopPlaybackStateMonitor(); |
|
|
stopPlaybackStateMonitor(); |
|
|
_notifyListeners(); |
|
|
|
|
|
} |
|
|
} |
|
|
return result; |
|
|
return result; |
|
|
} catch (e) { |
|
|
} catch (e) { |
|
|
@ -358,14 +299,7 @@ class QqMusicService extends GetxService { |
|
|
Future<Map<String, dynamic>> skipToNext() async { |
|
|
Future<Map<String, dynamic>> skipToNext() async { |
|
|
try { |
|
|
try { |
|
|
final result = await _qqMusic.skipToNext(); |
|
|
final result = await _qqMusic.skipToNext(); |
|
|
if (result['success'] == true) { |
|
|
if (result['success'] == true) {} |
|
|
// 更新当前索引 |
|
|
|
|
|
// if (currentIndex.value < playlist.length - 1) { |
|
|
|
|
|
// currentIndex.value++; |
|
|
|
|
|
// currentSong.value = playlist[currentIndex.value]; |
|
|
|
|
|
// } |
|
|
|
|
|
_notifyListeners(); |
|
|
|
|
|
} |
|
|
|
|
|
return result; |
|
|
return result; |
|
|
} catch (e) { |
|
|
} catch (e) { |
|
|
return {'success': false, 'error': '下一首失败: ${e.toString()}'}; |
|
|
return {'success': false, 'error': '下一首失败: ${e.toString()}'}; |
|
|
@ -376,14 +310,7 @@ class QqMusicService extends GetxService { |
|
|
Future<Map<String, dynamic>> skipToPrevious() async { |
|
|
Future<Map<String, dynamic>> skipToPrevious() async { |
|
|
try { |
|
|
try { |
|
|
final result = await _qqMusic.skipToPrevious(); |
|
|
final result = await _qqMusic.skipToPrevious(); |
|
|
if (result['success'] == true) { |
|
|
if (result['success'] == true) {} |
|
|
// 更新当前索引 |
|
|
|
|
|
// if (currentIndex.value > 0) { |
|
|
|
|
|
// currentIndex.value--; |
|
|
|
|
|
// currentSong.value = playlist[currentIndex.value]; |
|
|
|
|
|
// } |
|
|
|
|
|
_notifyListeners(); |
|
|
|
|
|
} |
|
|
|
|
|
return result; |
|
|
return result; |
|
|
} catch (e) { |
|
|
} catch (e) { |
|
|
return {'success': false, 'error': '上一首失败: ${e.toString()}'}; |
|
|
return {'success': false, 'error': '上一首失败: ${e.toString()}'}; |
|
|
@ -480,8 +407,6 @@ class QqMusicService extends GetxService { |
|
|
}); |
|
|
}); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
// 通知所有监听器 |
|
|
|
|
|
_notifyListeners(); |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
return result; |
|
|
return result; |
|
|
|