|
|
|
@ -4,6 +4,8 @@ import android.content.Context |
|
|
|
import android.util.Log |
|
|
|
import kotlinx.coroutines.delay |
|
|
|
import com.yunqiinnovation.qq_music.QQMusicSingleton |
|
|
|
import kotlin.coroutines.suspendCoroutine |
|
|
|
import kotlin.coroutines.resume |
|
|
|
/** |
|
|
|
* QQ音乐系统功能处理器 |
|
|
|
* 负责注册QQ音乐相关的MCP函数 |
|
|
|
@ -195,24 +197,22 @@ private class QQMusicLoginHandler(private val context: Context?) : FunctionHandl |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private class QQMusicSearchHandler(private val context: Context?) : FunctionHandler { |
|
|
|
override suspend fun handle(arguments: Map<String, Any>): String { |
|
|
|
return try { |
|
|
|
val keyword = arguments["keyword"] as? String ?: return "{\"success\": false, \"message\": \"缺少搜索关键词\"}" |
|
|
|
val searchType = arguments["searchType"] as? Int ?: 0 // 默认搜索歌曲 |
|
|
|
val qqMusicSingleton = QQMusicSingleton.getInstance() |
|
|
|
var result = "" |
|
|
|
|
|
|
|
// 直接调用搜索,内部会自动处理登录检查 |
|
|
|
// 使用 suspendCoroutine 将回调转换为协程 |
|
|
|
suspendCoroutine { continuation -> |
|
|
|
qqMusicSingleton.searchSongs(keyword) { searchResult -> |
|
|
|
result = if (searchResult.isSuccess) { |
|
|
|
val result = if (searchResult.isSuccess) { |
|
|
|
val songs = searchResult.getOrNull() ?: emptyList() |
|
|
|
|
|
|
|
// 根据搜索类型处理结果 |
|
|
|
val processedSongs = when (searchType) { |
|
|
|
0 -> { // 歌曲搜索,只返回第一个结果 |
|
|
|
// if (songs.isNotEmpty()) listOf(songs.first()) else emptyList() |
|
|
|
0 -> { // 歌曲搜索,返回所有结果 |
|
|
|
songs |
|
|
|
} |
|
|
|
else -> { // 专辑、歌手等其他类型,返回所有结果 |
|
|
|
@ -233,22 +233,74 @@ private class QQMusicSearchHandler(private val context: Context?) : FunctionHand |
|
|
|
val duration = songMap["duration"] ?: 0 |
|
|
|
"{\"mid\": \"$mid\", \"name\": \"$name\", \"artist\": \"$artist\", \"album\": \"$album\", \"duration\":$duration,\"pic\": \"$pic\"}" |
|
|
|
} |
|
|
|
"{\"success\": true, \"broadcast\": false, \"message\": \"搜索成功,增在播放\", \"data\": [$songsJson]}" |
|
|
|
"{\"success\": true, \"broadcast\": false, \"message\": \"搜索成功,正在播放\", \"data\": [$songsJson]}" |
|
|
|
} else { |
|
|
|
val error = searchResult.exceptionOrNull() |
|
|
|
"{\"success\": false, \"message\": \"搜索失败: ${error?.message}\"}" |
|
|
|
} |
|
|
|
// 恢复协程执行 |
|
|
|
continuation.resume(result) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 等待回调完成 |
|
|
|
delay(5000) |
|
|
|
result.ifEmpty { "{\"success\": false, \"message\": \"搜索超时\"}" } |
|
|
|
} catch (e: Exception) { |
|
|
|
Log.e("QQMusicSearchHandler", "QQ音乐搜索失败", e) |
|
|
|
"{\"success\": false, \"message\": \"搜索异常: ${e.message}\"}" |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
//private class QQMusicSearchHandler(private val context: Context?) : FunctionHandler { |
|
|
|
// override suspend fun handle(arguments: Map<String, Any>): String { |
|
|
|
// return try { |
|
|
|
// val keyword = arguments["keyword"] as? String ?: return "{\"success\": false, \"message\": \"缺少搜索关键词\"}" |
|
|
|
// val searchType = arguments["searchType"] as? Int ?: 0 // 默认搜索歌曲 |
|
|
|
// val qqMusicSingleton = QQMusicSingleton.getInstance() |
|
|
|
// var result = "" |
|
|
|
// |
|
|
|
// // 直接调用搜索,内部会自动处理登录检查 |
|
|
|
// qqMusicSingleton.searchSongs(keyword) { searchResult -> |
|
|
|
// result = if (searchResult.isSuccess) { |
|
|
|
// val songs = searchResult.getOrNull() ?: emptyList() |
|
|
|
// |
|
|
|
// // 根据搜索类型处理结果 |
|
|
|
// val processedSongs = when (searchType) { |
|
|
|
// 0 -> { // 歌曲搜索,只返回第一个结果 |
|
|
|
//// if (songs.isNotEmpty()) listOf(songs.first()) else emptyList() |
|
|
|
// songs |
|
|
|
// } |
|
|
|
// else -> { // 专辑、歌手等其他类型,返回所有结果 |
|
|
|
// songs |
|
|
|
// } |
|
|
|
// } |
|
|
|
// |
|
|
|
// val songsJson = processedSongs.joinToString(",") { song -> |
|
|
|
// val songMap = song as Map<String, Any?> |
|
|
|
// // 添加调试日志 |
|
|
|
// Log.d("QQMusicSearchHandler", "原始数据: $songMap") |
|
|
|
// // 修正字段名映射 |
|
|
|
// val mid = songMap["mid"] ?: "unknown" |
|
|
|
// val name = songMap["name"] ?: "unknown" |
|
|
|
// val artist = songMap["singer"] ?: "unknown" |
|
|
|
// val album = songMap["album"] ?: "" |
|
|
|
// val pic = songMap["pic"] ?: "" |
|
|
|
// val duration = songMap["duration"] ?: 0 |
|
|
|
// "{\"mid\": \"$mid\", \"name\": \"$name\", \"artist\": \"$artist\", \"album\": \"$album\", \"duration\":$duration,\"pic\": \"$pic\"}" |
|
|
|
// } |
|
|
|
// "{\"success\": true, \"broadcast\": false, \"message\": \"搜索成功,增在播放\", \"data\": [$songsJson]}" |
|
|
|
// } else { |
|
|
|
// val error = searchResult.exceptionOrNull() |
|
|
|
// "{\"success\": false, \"message\": \"搜索失败: ${error?.message}\"}" |
|
|
|
// } |
|
|
|
// } |
|
|
|
// |
|
|
|
// // 等待回调完成 |
|
|
|
// delay(5000) |
|
|
|
// result.ifEmpty { "{\"success\": false, \"message\": \"搜索超时\"}" } |
|
|
|
// } catch (e: Exception) { |
|
|
|
// Log.e("QQMusicSearchHandler", "QQ音乐搜索失败", e) |
|
|
|
// "{\"success\": false, \"message\": \"搜索异常: ${e.message}\"}" |
|
|
|
// } |
|
|
|
// } |
|
|
|
//} |
|
|
|
|
|
|
|
private class QQMusicPlaySongsHandler(private val context: Context?) : FunctionHandler { |
|
|
|
override suspend fun handle(arguments: Map<String, Any>): String { |
|
|
|
@ -310,7 +362,7 @@ private class QQMusicPauseHandler(private val context: Context?) : FunctionHandl |
|
|
|
|
|
|
|
qqMusicSingleton.pauseMusic { pauseResult -> |
|
|
|
result = if (pauseResult.isSuccess) { |
|
|
|
"{\"notreply\": true, \"success\": true, \"message\": \"暂停播放\"}" |
|
|
|
"{\"broadcast\": false, \"success\": true, \"message\": \"暂停播放\"}" |
|
|
|
} else { |
|
|
|
val error = pauseResult.exceptionOrNull() |
|
|
|
"{\"success\": false, \"message\": \"暂停失败: ${error?.message}\"}" |
|
|
|
@ -334,7 +386,7 @@ private class QQMusicResumeHandler(private val context: Context?) : FunctionHand |
|
|
|
|
|
|
|
qqMusicSingleton.resumeMusic { resumeResult -> |
|
|
|
result = if (resumeResult.isSuccess) { |
|
|
|
"{\"notreply\": true, \"success\": true, \"message\": \"恢复播放\"}" |
|
|
|
"{\"broadcast\": false, \"success\": true, \"message\": \"恢复播放\"}" |
|
|
|
} else { |
|
|
|
val error = resumeResult.exceptionOrNull() |
|
|
|
"{\"success\": false, \"message\": \"恢复播放失败: ${error?.message}\"}" |
|
|
|
@ -358,7 +410,7 @@ private class QQMusicStopHandler(private val context: Context?) : FunctionHandle |
|
|
|
|
|
|
|
qqMusicSingleton.stopMusic { stopResult -> |
|
|
|
result = if (stopResult.isSuccess) { |
|
|
|
"{\"notreply\": true, \"success\": true, \"message\": \"停止播放\"}" |
|
|
|
"{\"broadcast\": false, \"success\": true, \"message\": \"停止播放\"}" |
|
|
|
} else { |
|
|
|
val error = stopResult.exceptionOrNull() |
|
|
|
"{\"success\": false, \"message\": \"停止失败: ${error?.message}\"}" |
|
|
|
@ -382,7 +434,7 @@ private class QQMusicNextHandler(private val context: Context?) : FunctionHandle |
|
|
|
|
|
|
|
qqMusicSingleton.skipToNext { nextResult -> |
|
|
|
result = if (nextResult.isSuccess) { |
|
|
|
"{\"notreply\": true, \"success\": true, \"message\": \"切换到下一首\"}" |
|
|
|
"{\"broadcast\": false, \"success\": true, \"message\": \"切换到下一首\"}" |
|
|
|
} else { |
|
|
|
val error = nextResult.exceptionOrNull() |
|
|
|
"{\"success\": false, \"message\": \"切换失败: ${error?.message}\"}" |
|
|
|
@ -406,7 +458,7 @@ private class QQMusicPreviousHandler(private val context: Context?) : FunctionHa |
|
|
|
|
|
|
|
qqMusicSingleton.skipToPrevious { previousResult -> |
|
|
|
result = if (previousResult.isSuccess) { |
|
|
|
"{\"notreply\": true, \"success\": true, \"message\": \"切换到上一首\"}" |
|
|
|
"{\"broadcast\": false, \"success\": true, \"message\": \"切换到上一首\"}" |
|
|
|
} else { |
|
|
|
val error = previousResult.exceptionOrNull() |
|
|
|
"{\"success\": false, \"message\": \"切换失败: ${error?.message}\"}" |
|
|
|
@ -434,7 +486,7 @@ private class QQMusicGetPlaybackStateHandler(private val context: Context?) : Fu |
|
|
|
val stateJson = state.entries.joinToString(",") { (key, value) -> |
|
|
|
"\"$key\": \"$value\"" |
|
|
|
} |
|
|
|
"{\"notreply\": true, \"success\": true, \"message\": \"获取播放状态成功\", \"data\": {$stateJson}}" |
|
|
|
"{\"broadcast\": false, \"success\": true, \"message\": \"获取播放状态成功\", \"data\": {$stateJson}}" |
|
|
|
} else { |
|
|
|
val error = stateResult.exceptionOrNull() |
|
|
|
"{\"success\": false, \"message\": \"获取播放状态失败: ${error?.message}\"}" |
|
|
|
|