From 63b44e72ab1e83e112167e90dded8bbe94d6de10 Mon Sep 17 00:00:00 2001 From: liwei1dao Date: Wed, 23 Apr 2025 17:23:20 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E8=81=8A=E5=A4=A9=E8=AF=AD?= =?UTF-8?q?=E9=9F=B3=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../deepsound/VoiceInteractionHandler.kt | 19 ++++++- .../chat/controllers/chat_controller.dart | 7 +-- ...otifySdkService.kt => SpotifySdkHelper.kt} | 51 +++++++------------ 3 files changed, 40 insertions(+), 37 deletions(-) rename local_plugins/spotify_sdk/android/src/main/kotlin/de/minimalme/spotify_sdk/{SpotifySdkService.kt => SpotifySdkHelper.kt} (81%) diff --git a/android/app/src/main/kotlin/com/yunqiinnovation/deepsound/VoiceInteractionHandler.kt b/android/app/src/main/kotlin/com/yunqiinnovation/deepsound/VoiceInteractionHandler.kt index 881b9dc84..f0a7d6d86 100644 --- a/android/app/src/main/kotlin/com/yunqiinnovation/deepsound/VoiceInteractionHandler.kt +++ b/android/app/src/main/kotlin/com/yunqiinnovation/deepsound/VoiceInteractionHandler.kt @@ -12,6 +12,7 @@ import com.yunqiinnovation.azure_speech.AzureAsrHelper import com.yunqiinnovation.azure_speech.AzureTtsHelper import com.yunqiinnovation.open_ai_service.OpenAIService import com.yunqiinnovation.open_ai_service.SystemFunctionHandler +import de.minimalme.spotify_sdk.SpotifySdkHelper /** @@ -38,7 +39,9 @@ class VoiceInteractionHandler( // OpenAI服务 private val openAIService = OpenAIService(context.applicationContext) - + + private var spotifyHelper: SpotifySdkHelper? = null + // 当前用户输入 private var currentUserInput = "" @@ -314,7 +317,19 @@ class VoiceInteractionHandler( notifyStateChanged() } } - + + /* + * 播放音乐。Spotify + * */ + fun playSpotifyMusic(url:String){ + if (spotifyHelper == null){ + spotifyHelper = SpotifySdkHelper(context).apply { + initialize(spotifyclientid,spotifyRedirectUrl) + } + } + spotifyHelper?.play(url) + } + /** * 播放AI回复 */ diff --git a/lib/modules/chat/controllers/chat_controller.dart b/lib/modules/chat/controllers/chat_controller.dart index 997ef0fbb..8bd00e873 100644 --- a/lib/modules/chat/controllers/chat_controller.dart +++ b/lib/modules/chat/controllers/chat_controller.dart @@ -414,7 +414,7 @@ class ChatController extends GetxController { if (chunk['card_spotify'] != null) { play(chunk['card_spotify']); } - } else { + } else if (chunk is String) { fullResponse += chunk; // 更新中间状态的消息内容 @@ -422,7 +422,8 @@ class ChatController extends GetxController { // 如果TTS启用,使用流式处理发送到TTS if (isTtsEnabled.value) { - _ttsService.speakStream(chunk); + String str = chunk.replaceAll('*', ''); + _ttsService.speakStream(str); } } }, @@ -456,7 +457,7 @@ class ChatController extends GetxController { final List> messageHistory = []; // 只取最近的10条消息作为上下文 - final recentMessages = messages.where((m) => !m.isIntermediate).toList(); + final recentMessages = messages.where((m) => m.role == "user").toList(); final startIndex = recentMessages.length > 10 ? recentMessages.length - 10 : 0; diff --git a/local_plugins/spotify_sdk/android/src/main/kotlin/de/minimalme/spotify_sdk/SpotifySdkService.kt b/local_plugins/spotify_sdk/android/src/main/kotlin/de/minimalme/spotify_sdk/SpotifySdkHelper.kt similarity index 81% rename from local_plugins/spotify_sdk/android/src/main/kotlin/de/minimalme/spotify_sdk/SpotifySdkService.kt rename to local_plugins/spotify_sdk/android/src/main/kotlin/de/minimalme/spotify_sdk/SpotifySdkHelper.kt index b5b551219..7ae21f8fe 100644 --- a/local_plugins/spotify_sdk/android/src/main/kotlin/de/minimalme/spotify_sdk/SpotifySdkService.kt +++ b/local_plugins/spotify_sdk/android/src/main/kotlin/de/minimalme/spotify_sdk/SpotifySdkHelper.kt @@ -2,7 +2,6 @@ package de.minimalme.spotify_sdk import android.app.Activity import android.content.Context -import android.content.Intent import android.util.Log import com.spotify.android.appremote.api.ConnectionParams import com.spotify.android.appremote.api.Connector @@ -20,45 +19,33 @@ import com.spotify.android.appremote.api.error.UserNotAuthorizedException import com.spotify.sdk.android.auth.AuthorizationClient import com.spotify.sdk.android.auth.AuthorizationRequest import com.spotify.sdk.android.auth.AuthorizationResponse -import de.minimalme.spotify_sdk.subscriptions.CapabilitiesChannel -import de.minimalme.spotify_sdk.subscriptions.ConnectionStatusChannel -import de.minimalme.spotify_sdk.subscriptions.PlayerContextChannel -import de.minimalme.spotify_sdk.subscriptions.PlayerStateChannel -import de.minimalme.spotify_sdk.subscriptions.UserStatusChannel -import io.flutter.embedding.engine.plugins.FlutterPlugin -import io.flutter.embedding.engine.plugins.activity.ActivityAware -import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding -import io.flutter.plugin.common.EventChannel -import io.flutter.plugin.common.MethodCall -import io.flutter.plugin.common.MethodChannel -import io.flutter.plugin.common.PluginRegistry -import kotlinx.event.SetEvent -import kotlinx.event.event -class SpotifySdkService(private val context: Context? = null) { + +class SpotifySdkHelper(private val context: Context? = null) { // application context private var applicationContext : Context? = null private var applicationActivity : Activity? = null // method channel - private lateinit var methodChannel : MethodChannel - private val channelName = "spotify_sdk" - private val loggingTag = "spotify_sdk" + private val loggingTag = "spotify_sdk" - private val errorConnecting = "errorConnecting" - private val errorDisconnecting = "errorDisconnecting" private val errorConnection = "errorConnection" - private val errorAuthenticationToken = "authenticationTokenError" private val requestCodeAuthentication = 1337 private var spotifyAppRemote: SpotifyAppRemote? = null private var playerApi: PlayerApi? = null - public fun connectToSpotify(clientId: String?, redirectUrl: String?, result: MethodChannel.Result) { + fun initialize(clientId: String, redirectUrl: String): Boolean { + getAccessToken(clientId,redirectUrl,""); + connectToSpotify(clientId,redirectUrl) + return true; + } + + public fun connectToSpotify(clientId: String?, redirectUrl: String?) { if (clientId.isNullOrBlank() || redirectUrl.isNullOrBlank()) { - result.error(errorConnecting, "client id or redirectUrl are not set or have invalid format", "") +// result.error(errorConnecting, "client id or redirectUrl are not set or have invalid format", "") } else { val connectionParams = ConnectionParams.Builder(clientId) .setRedirectUri(redirectUrl) @@ -74,7 +61,7 @@ class SpotifySdkService(private val context: Context? = null) { initiallyConnected = true Log.i(loggingTag, "App Remote successfully connected") - result.success(true) +// result.success(true) } override fun onFailure(throwable: Throwable) { @@ -154,20 +141,20 @@ class SpotifySdkService(private val context: Context? = null) { // ) } else { // throw exception as the connect method - result.error(errorCode, errorMessage, errorDetails) +// result.error(errorCode, errorMessage, errorDetails) } } }) } } - public fun getAccessToken(clientId: String?, redirectUrl: String?, scope: String?, result: MethodChannel.Result) { + public fun getAccessToken(clientId: String?, redirectUrl: String?, scope: String?) { if (applicationActivity == null) { throw IllegalStateException("getAccessToken needs a foreground activity") } if (clientId.isNullOrBlank() || redirectUrl.isNullOrBlank()) { - result.error(errorConnecting, "client id or redirectUrl are not set or have invalid format", "") +// result.error(errorConnecting, "client id or redirectUrl are not set or have invalid format", "") } else { //Convert String? scope to Array. Delimiter set as comma "," val scopeArray = scope?.split(",")?.toTypedArray() @@ -187,14 +174,14 @@ class SpotifySdkService(private val context: Context? = null) { } } - public fun disconnectFromSpotify(result: MethodChannel.Result) { + public fun disconnectFromSpotify() { if (spotifyAppRemote != null && spotifyAppRemote!!.isConnected) { SpotifyAppRemote.disconnect(spotifyAppRemote) - result.success(true) +// result.success(true) } else if (!spotifyAppRemote!!.isConnected) { - result.error(errorDisconnecting, "could not disconnect spotify remote", "you are not connected, no need to disconnect") +// result.error(errorDisconnecting, "could not disconnect spotify remote", "you are not connected, no need to disconnect") } else { - result.error(errorDisconnecting, "could not disconnect spotify remote", "spotifyAppRemote is not set") +// result.error(errorDisconnecting, "could not disconnect spotify remote", "spotifyAppRemote is not set") } }