Browse Source

feat(音乐服务): 添加多音乐服务类型支持并优化音乐控制逻辑

实现根据配置选择不同的音乐服务类型(WY/QQ/AUTO)
在Android和iOS平台添加音乐服务类型初始化日志
重构音乐控制逻辑,统一处理暂停和恢复操作
newdev_shunjiawei
liwei1dao 10 months ago
parent
commit
a6ba9d434d
  1. 1
      lib/data/services/ble_manager.dart
  2. 16
      lib/modules/agent/controllers/agent_controller.dart
  3. 58
      local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/AgentService.kt
  4. 1
      local_plugins/chat_api/android/src/main/kotlin/com/yunqiinnovation/chat_api/MCPClient.kt
  5. 1
      local_plugins/chat_api/ios/chat_api/Sources/chat_api/ChatApiService.swift

1
lib/data/services/ble_manager.dart

@ -207,7 +207,6 @@ class BleManager extends GetxService {
final _isConnected = false.obs; final _isConnected = false.obs;
bool get isConnected => _isConnected.value; bool get isConnected => _isConnected.value;
bool get isCall => _isCall.value; bool get isCall => _isCall.value;
// 设备信息缓存 // 设备信息缓存
final deviceInfo = Rx<DeviceInfo?>(null); // 使用 Rx 包装 final deviceInfo = Rx<DeviceInfo?>(null); // 使用 Rx 包装

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

@ -2,6 +2,7 @@ import 'dart:async';
import 'dart:convert'; import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'package:amap_service/amap_service.dart'; import 'package:amap_service/amap_service.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:package_info_plus/package_info_plus.dart'; import 'package:package_info_plus/package_info_plus.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
import 'package:uuid/uuid.dart'; import 'package:uuid/uuid.dart';
@ -13,7 +14,6 @@ import '/data/services/bluetooth_manager.dart';
import '/data/services/qq_music.dart'; import '/data/services/qq_music.dart';
import 'package:flutter_intro/flutter_intro.dart'; import 'package:flutter_intro/flutter_intro.dart';
import '../../../data/services/novice_guide_service.dart'; import '../../../data/services/novice_guide_service.dart';
import '../../../routes/app_routes.dart';
import '/core/utils/upload_oss.dart'; import '/core/utils/upload_oss.dart';
import '/data/models/user_Info.dart'; import '/data/models/user_Info.dart';
import '/data/services/music_manager.dart'; import '/data/services/music_manager.dart';
@ -144,6 +144,8 @@ class AgentController extends GetxController with WidgetsBindingObserver {
// 会话ID // 会话ID
final String agentId = 'default_agent'; final String agentId = 'default_agent';
var musicServiceType = 'WY';
// 分页加载相关状态 // 分页加载相关状态
final isLoadingMore = false.obs; // 是否正在加载更多消息 final isLoadingMore = false.obs; // 是否正在加载更多消息
final hasMoreMessages = true.obs; // 是否还有更多消息 final hasMoreMessages = true.obs; // 是否还有更多消息
@ -167,6 +169,10 @@ class AgentController extends GetxController with WidgetsBindingObserver {
@override @override
void onInit() { void onInit() {
super.onInit(); super.onInit();
musicServiceType = AppConfig.env('APP_ANDROID_MUSICSERVICE_TYPE') ?? 'AUTO';
if (Platform.isIOS) {
musicServiceType = AppConfig.env('APP_IOS_MUSICSERVICE_TYPE') ?? 'AUTO';
}
vipExpiryTime.value = User.isLoggedIn() ? User.instance.vipexptime : 0; vipExpiryTime.value = User.isLoggedIn() ? User.instance.vipexptime : 0;
ever<int>(User.refreshTick, (_) { ever<int>(User.refreshTick, (_) {
vipExpiryTime.value = User.instance.vipexptime; vipExpiryTime.value = User.instance.vipexptime;
@ -1023,8 +1029,12 @@ class AgentController extends GetxController with WidgetsBindingObserver {
} }
if (function_name.contains("music")) { if (function_name.contains("music")) {
Future.delayed(Duration(seconds: 1), () { Future.delayed(Duration(seconds: 1), () {
_qqmusicManager.syncCurrentPlayInfo(isOpenPlay: false); Logger.i(TAG, '音乐服务 $musicServiceType');
musicStatus(); if (musicServiceType == "QQ") {
_qqmusicManager.syncCurrentPlayInfo(isOpenPlay: false);
} else {
musicStatus();
}
}); });
// } // }
} }

58
local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/AgentService.kt

@ -13,6 +13,7 @@ import com.yunqiinnovation.chat_api.ChatApiService
import com.yunqiinnovation.chat_api.StreamCallback import com.yunqiinnovation.chat_api.StreamCallback
import com.yunqiinnovation.chat_storage.ChatStorageHelper import com.yunqiinnovation.chat_storage.ChatStorageHelper
import com.yunqiinnovation.music_service.MusicSingleton import com.yunqiinnovation.music_service.MusicSingleton
import com.yunqiinnovation.music_service.MusicService
import com.yunqiinnovation.amap_service.NavigationServiceHelper import com.yunqiinnovation.amap_service.NavigationServiceHelper
import com.yunqiinnovation.user_portrait.UserPortrait import com.yunqiinnovation.user_portrait.UserPortrait
import com.yunqiinnovation.location_service.LocationService import com.yunqiinnovation.location_service.LocationService
@ -160,6 +161,7 @@ object AgentService : CoroutineScope {
var audioSourceType = AzureAsrHelper.AudioSourceType.MICROPHONE var audioSourceType = AzureAsrHelper.AudioSourceType.MICROPHONE
var navigationMode = "" var navigationMode = ""
var musicServiceType = ""
// 语气词过滤列表(中英文) // 语气词过滤列表(中英文)
private val FILLER_WORDS = setOf( private val FILLER_WORDS = setOf(
// 中文语气词 // 中文语气词
@ -270,7 +272,8 @@ object AgentService : CoroutineScope {
// 初始化TTS服务 // 初始化TTS服务
initializeTtsEngine(config) initializeTtsEngine(config)
navigationMode = config["navigationMode"]?.toString() ?: "" navigationMode = config["navigationMode"]?.toString() ?: ""
musicServiceType = config["musicServiceType"]?.toString() ?: ""
// 初始化ChatAPI服务 // 初始化ChatAPI服务
chatApiService.initialize( chatApiService.initialize(
config["openaiApiKey"]?.toString() ?: "", config["openaiApiKey"]?.toString() ?: "",
@ -415,11 +418,12 @@ object AgentService : CoroutineScope {
} }
context.sendBroadcast(intent) context.sendBroadcast(intent)
Log.e(TAG, "QQ 音乐暂停播放") Log.e(TAG, "QQ 音乐暂停播放")
QQMusicSingleton.getInstance().autopauseMusic { result -> autopauseMusic()
if (result.isSuccess) { // QQMusicSingleton.getInstance().autopauseMusic { result ->
isplaymusic = true // if (result.isSuccess) {
} // isplaymusic = true
} // }
// }
} }
TtsEventType.PLAYBACK_COMPLETED -> { //结束AI播报内容 TtsEventType.PLAYBACK_COMPLETED -> { //结束AI播报内容
@ -434,11 +438,12 @@ object AgentService : CoroutineScope {
if(currentRecognitionMode == "ble_wakeup"&&_isInterrupt.get()){ if(currentRecognitionMode == "ble_wakeup"&&_isInterrupt.get()){
BleService.openB1Encoder() BleService.openB1Encoder()
} }
if(isplaymusic){ resumeMusic()
isplaymusic = false // if(isplaymusic){
Log.e(TAG, "QQ 音乐恢复播放") // isplaymusic = false
QQMusicSingleton.getInstance().resumeMusic { } // Log.e(TAG, "QQ 音乐恢复播放")
} // QQMusicSingleton.getInstance().resumeMusic { }
// }
} }
TtsEventType.ERROR -> { TtsEventType.ERROR -> {
@ -919,6 +924,7 @@ object AgentService : CoroutineScope {
} }
} }
/** /**
* 处理文本输入 * 处理文本输入
*/ */
@ -2729,4 +2735,34 @@ object AgentService : CoroutineScope {
Log.e(TAG, "保存 _isInterrupt 缓存状态时发生异常: ${e.message}", e) Log.e(TAG, "保存 _isInterrupt 缓存状态时发生异常: ${e.message}", e)
} }
} }
/*
* 自动暂停音乐
*/
private fun autopauseMusic(){
if ( musicServiceType == "QQ" ){
QQMusicSingleton.getInstance().autopauseMusic { result ->
if (result.isSuccess) {
isplaymusic = true
}
}
}else{
if (MusicService.isPlaying()){
MusicSingleton.startServiceWithCommand(context, "pause")
isplaymusic = true
}
}
}
private fun resumeMusic() {
if ( isplaymusic ){
Log.d(TAG, "音乐恢复 : $musicServiceType")
isplaymusic = false
if ( musicServiceType == "QQ" ){
QQMusicSingleton.getInstance().resumeMusic {}
}else{
MusicSingleton.startServiceWithCommand(context, "resume")
}
}
}
} }

1
local_plugins/chat_api/android/src/main/kotlin/com/yunqiinnovation/chat_api/MCPClient.kt

@ -54,6 +54,7 @@ class MCPClient(private val context: Context? = null,musicType: String = "AUTO")
init { init {
initializeSystemFunctions() initializeSystemFunctions()
Log.d(TAG, "初始化音乐服务: $musicType")
when (musicType) { when (musicType) {
"WY" -> initializeMusiceFunctions() //网易 "WY" -> initializeMusiceFunctions() //网易
"QQ" -> initializeQQMusiceFunctions() //QQ "QQ" -> initializeQQMusiceFunctions() //QQ

1
local_plugins/chat_api/ios/chat_api/Sources/chat_api/ChatApiService.swift

@ -96,6 +96,7 @@ public class ChatApiService: NSObject {
/// 初始化ChatAPI服务 /// 初始化ChatAPI服务
public func initialize(apiKey: String, baseUrl: String, model: String, visionModel:String, mcpServer: String,musicServiceType:String) -> Bool { public func initialize(apiKey: String, baseUrl: String, model: String, visionModel:String, mcpServer: String,musicServiceType:String) -> Bool {
print("[ChatApiService] 初始化 ChatAPI 服务 musicServiceType: \(musicServiceType)")
self.apiKey = apiKey self.apiKey = apiKey
if !baseUrl.isEmpty { if !baseUrl.isEmpty {
self.baseUrl = baseUrl self.baseUrl = baseUrl

Loading…
Cancel
Save