Browse Source

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

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

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

@ -780,16 +780,20 @@ class AgentController extends GetxController {
);
}
}
if (metaResult.containsKey("qqmusic_searchandplay_songs")) {
final qqmusic_search_songs =
metaResult['qqmusic_searchandplay_songs']
as Map<String, dynamic>;
final data = qqmusic_search_songs['data'];
if (data != null && data is List) {
Future.delayed(Duration(seconds: 1), () {
_qqmusicManager.syncCurrentPlayInfo();
});
}
final musicKey = metaResult.keys.firstWhere(
(key) => key.contains("music"),
orElse: () => "",
);
if (musicKey.isNotEmpty) {
// final qqmusic_search_songs =
// metaResult['qqmusic_searchandplay_songs']
// 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")) {
//导航
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: 播放歌曲失败 - 登录失败")
}
}
private var pendingPlayCompletion: ((Bool, String?) -> Void)?
private var playVerificationTimer: Timer?
@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 {
completion(false, "歌曲列表为空")
return
@ -504,16 +509,47 @@ import QPlayAutoSDK
return
}
// 修改:使用 ensureQQMusicInstalledAndLoginAndExecute 替代 ensureLoginAndExecute
ensureQQMusicInstalledAndLoginAndExecute {
QPlayAutoSDK.playSongMid(atIndex: mids, play: index) { errorCode in
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 {
let errorMessage = "QQ音乐播放列表启动失败,错误码: \(errorCode)"
completion(false, errorMessage)
print(errorMessage)
// SDK调用失败,尝试重试
if retryCount < maxRetries {
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: {
@ -522,7 +558,6 @@ import QPlayAutoSDK
completion(false, "登录失败,无法播放歌曲列表")
}
}
@objc public func next() {
ensureQQMusicInstalledAndLoginAndExecute {
QPlayAutoSDK.playerPlayNext { errorCode in
@ -803,6 +838,19 @@ extension QPlayAutoManager: QPlayAutoSDKDelegate {
for weakDelegate in delegates {
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) {

Loading…
Cancel
Save