Browse Source

优化音乐播放状态同步逻辑

newdev_shunjiawei
liwei1dao 1 year ago
parent
commit
a9100f6df8
  1. 10
      lib/data/services/qq_music.dart
  2. 24
      lib/modules/agent/controllers/agent_controller.dart
  3. 64
      local_plugins/qq_music/ios/qq_music/Sources/qq_music/QPlayAutoManager.swift

10
lib/data/services/qq_music.dart

@ -37,7 +37,7 @@ class QqMusicService extends GetxService {
if (result['success'] == true) { if (result['success'] == true) {
print('QQ音乐自动登录成功: ${result['openId']}'); print('QQ音乐自动登录成功: ${result['openId']}');
Future.delayed(Duration(milliseconds: 1000), () { Future.delayed(Duration(milliseconds: 1000), () {
syncCurrentPlayInfo(isFrest: true); syncCurrentPlayInfo();
}); });
} else { } else {
print('QQ音乐自动登录失败: ${result['error']}'); print('QQ音乐自动登录失败: ${result['error']}');
@ -422,7 +422,7 @@ class QqMusicService extends GetxService {
/// 同步当前播放信息 - 统一接口 /// 同步当前播放信息 - 统一接口
Future<Map<String, dynamic>> syncCurrentPlayInfo( Future<Map<String, dynamic>> syncCurrentPlayInfo(
{bool isFrest = false}) async { {bool isOpenPlay = false}) async {
try { try {
_stateMonitorTimer?.cancel(); //先关闭计时器 _stateMonitorTimer?.cancel(); //先关闭计时器
final result = await _qqMusic.syncCurrentPlayInfo(); final result = await _qqMusic.syncCurrentPlayInfo();
@ -473,6 +473,12 @@ class QqMusicService extends GetxService {
} else { } else {
stopPlaybackStateMonitor(); stopPlaybackStateMonitor();
currentSong.value = null; currentSong.value = null;
if (isOpenPlay) {
Future.delayed(Duration(seconds: 2), () {
syncCurrentPlayInfo();
});
}
} }
// 通知所有监听器 // 通知所有监听器
_notifyListeners(); _notifyListeners();

24
lib/modules/agent/controllers/agent_controller.dart

@ -780,16 +780,20 @@ class AgentController extends GetxController {
); );
} }
} }
if (metaResult.containsKey("qqmusic_searchandplay_songs")) { final musicKey = metaResult.keys.firstWhere(
final qqmusic_search_songs = (key) => key.contains("music"),
metaResult['qqmusic_searchandplay_songs'] orElse: () => "",
as Map<String, dynamic>; );
final data = qqmusic_search_songs['data']; if (musicKey.isNotEmpty) {
if (data != null && data is List) { // final qqmusic_search_songs =
Future.delayed(Duration(seconds: 1), () { // metaResult['qqmusic_searchandplay_songs']
_qqmusicManager.syncCurrentPlayInfo(); // as Map<String, dynamic>;
}); // final data = qqmusic_search_songs['data'];
} // if (data != null && data is List) {
Future.delayed(Duration(seconds: 2), () {
_qqmusicManager.syncCurrentPlayInfo(isOpenPlay: true);
});
// }
} else if (metaResult.containsKey("maps_route_navigation")) { } else if (metaResult.containsKey("maps_route_navigation")) {
//导航 //导航
final start = metaResult["maps_route_navigation"] final start = metaResult["maps_route_navigation"]

64
local_plugins/qq_music/ios/qq_music/Sources/qq_music/QPlayAutoManager.swift

@ -492,8 +492,13 @@ import QPlayAutoSDK
print("QPlayAutoManager: 播放歌曲失败 - 登录失败") print("QPlayAutoManager: 播放歌曲失败 - 登录失败")
} }
} }
private var pendingPlayCompletion: ((Bool, String?) -> Void)?
private var playVerificationTimer: Timer?
@objc public func playSongs(mids: [String], index: Int = 0, completion: @escaping (Bool, String?) -> Void) { @objc public func playSongs(mids: [String], index: Int = 0, completion: @escaping (Bool, String?) -> Void) {
playSongsWithRetry(mids: mids, index: index, retryCount: 0, maxRetries: 3, completion: completion)
}
private func playSongsWithRetry(mids: [String], index: Int, retryCount: Int, maxRetries: Int, completion: @escaping (Bool, String?) -> Void) {
guard !mids.isEmpty else { guard !mids.isEmpty else {
completion(false, "歌曲列表为空") completion(false, "歌曲列表为空")
return return
@ -504,16 +509,47 @@ import QPlayAutoSDK
return return
} }
// 修改:使用 ensureQQMusicInstalledAndLoginAndExecute 替代 ensureLoginAndExecute
ensureQQMusicInstalledAndLoginAndExecute { ensureQQMusicInstalledAndLoginAndExecute {
QPlayAutoSDK.playSongMid(atIndex: mids, play: index) { errorCode in QPlayAutoSDK.playSongMid(atIndex: mids, play: index) { errorCode in
if errorCode == 0 { if errorCode == 0 {
completion(true, nil) // 不立即返回成功,而是等待播放状态确认
print("QQ音乐播放列表启动成功,共\(mids.count)首歌曲") self.pendingPlayCompletion = completion
// 设置超时检查
self.playVerificationTimer = Timer.scheduledTimer(withTimeInterval: 2.0, repeats: false) { _ in
if let pendingCompletion = self.pendingPlayCompletion {
self.pendingPlayCompletion = nil
// 检查当前播放状态
let currentState = self.currentPlayState
if currentState == .playing {
pendingCompletion(true, nil)
print("QQ音乐播放列表验证成功,共\(mids.count)首歌曲")
} else {
// 播放验证失败,尝试重试
if retryCount < maxRetries {
print("QQ音乐播放验证失败,第\(retryCount + 1)次重试...")
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
self.playSongsWithRetry(mids: mids, index: index, retryCount: retryCount + 1, maxRetries: maxRetries, completion: completion)
}
} else {
pendingCompletion(false, "播放验证超时,已重试\(maxRetries)次,当前状态: \(currentState.rawValue)")
}
}
}
}
} else { } else {
let errorMessage = "QQ音乐播放列表启动失败,错误码: \(errorCode)" // SDK调用失败,尝试重试
completion(false, errorMessage) if retryCount < maxRetries {
print(errorMessage) let errorMessage = "QQ音乐播放列表启动失败,错误码: \(errorCode),第\(retryCount + 1)次重试..."
print(errorMessage)
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
self.playSongsWithRetry(mids: mids, index: index, retryCount: retryCount + 1, maxRetries: maxRetries, completion: completion)
}
} else {
let errorMessage = "QQ音乐播放列表启动失败,已重试\(maxRetries)次,错误码: \(errorCode)"
completion(false, errorMessage)
print(errorMessage)
}
} }
} }
} onQQMusicNotInstalled: { } onQQMusicNotInstalled: {
@ -522,7 +558,6 @@ import QPlayAutoSDK
completion(false, "登录失败,无法播放歌曲列表") completion(false, "登录失败,无法播放歌曲列表")
} }
} }
@objc public func next() { @objc public func next() {
ensureQQMusicInstalledAndLoginAndExecute { ensureQQMusicInstalledAndLoginAndExecute {
QPlayAutoSDK.playerPlayNext { errorCode in QPlayAutoSDK.playerPlayNext { errorCode in
@ -803,6 +838,19 @@ extension QPlayAutoManager: QPlayAutoSDKDelegate {
for weakDelegate in delegates { for weakDelegate in delegates {
weakDelegate.delegate?.onPlayStateChanged?(playState, song: song, position: position) weakDelegate.delegate?.onPlayStateChanged?(playState, song: song, position: position)
} }
// 检查是否有待验证的播放请求
if let pendingCompletion = pendingPlayCompletion {
if playState == .playing {
pendingPlayCompletion = nil
playVerificationTimer?.invalidate()
pendingCompletion(true, nil)
print("QQ音乐播放状态确认:真正开始播放")
} else {
pendingPlayCompletion = nil
playVerificationTimer?.invalidate()
pendingCompletion(false, "播放失败,歌曲可能不可用")
}
}
} }
public func onQPlayAutoPlayProgressChanged(_ song: QPlayAutoListItem, progress: TimeInterval, duration: TimeInterval) { public func onQPlayAutoPlayProgressChanged(_ song: QPlayAutoListItem, progress: TimeInterval, duration: TimeInterval) {

Loading…
Cancel
Save