Browse Source

add

newdev_shunjiawei
fdp 1 year ago
parent
commit
50c3d1fc05
  1. 3
      devtools_options.yaml
  2. 2
      lib/data/services/music_manager.dart
  3. 19
      lib/modules/agent/controllers/agent_controller.dart
  4. 9
      lib/modules/agent/views/message_bubble.dart
  5. 6
      lib/modules/agent/views/music_card.dart
  6. 23
      local_plugins/music_service/android/src/main/kotlin/com/yunqiinnovation/music_service/MusicService.kt
  7. 5
      local_plugins/music_service/lib/music_service.dart

3
devtools_options.yaml

@ -0,0 +1,3 @@
description: This file stores settings for Dart & Flutter DevTools.
documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states
extensions:

2
lib/data/services/music_manager.dart

@ -105,7 +105,7 @@ class MusicManager extends GetxService {
required Function() onPrevious, required Function() onPrevious,
required Function(int) onSeekTo, required Function(int) onSeekTo,
required Function() onStop, required Function() onStop,
required Function(int, int, int, double) onStop1, required Function(String, int, int, double) onStop1,
}) async { }) async {
try { try {
await _musicService.setMediaSessionCallbacks( await _musicService.setMediaSessionCallbacks(

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

@ -1401,7 +1401,7 @@ class AgentController extends GetxController {
await _musiceManager.play(musicData); await _musiceManager.play(musicData);
// 更新媒体会话元数据和播放状态 // 更新媒体会话元数据和播放状态
await _updateMediaSessionMetadata(song); await _updateMediaSessionMetadata(musicData);
await _updateMediaSessionPlaybackState(true); await _updateMediaSessionPlaybackState(true);
// 启动进度定时器 // 启动进度定时器
@ -1514,11 +1514,12 @@ class AgentController extends GetxController {
} }
// 获取播放进度 // 获取播放进度
Future<void> updateMusicProgress1(int currentIdInternal, int newPosition, Future<void> updateMusicProgress1(String currentIdInternal, int newPosition,
int newDuration, double newProgress) async { int newDuration, double newProgress) async {
try { try {
if (!isPlaying.value || currentId.value == 0) { if (int.parse(currentIdInternal) != 0) {
return; // 如果没有在播放,直接返回 isPlaying.value = true;
// return; // 如果没有在播放,直接返回
} }
// // var progressInfo = await _musiceManager.getProgress(); // // var progressInfo = await _musiceManager.getProgress();
@ -1528,8 +1529,8 @@ class AgentController extends GetxController {
print( print(
"updateMusicProgress1:currentIdInternal:$currentIdInternal newPosition:$newPosition newDuration:$newDuration newProgress:$newProgress"); "updateMusicProgress1:currentIdInternal:$currentIdInternal newPosition:$newPosition newDuration:$newDuration newProgress:$newProgress");
bool hasUpdate = false; bool hasUpdate = false;
if (currentId.value != currentIdInternal && currentIdInternal != 0) { if (currentId.value != int.parse(currentIdInternal)) {
currentId.value = currentIdInternal; currentId.value = int.parse(currentIdInternal);
hasUpdate = true; hasUpdate = true;
} }
// 只有当值发生变化时才更新,避免不必要的UI刷新 // 只有当值发生变化时才更新,避免不必要的UI刷新
@ -1602,7 +1603,7 @@ class AgentController extends GetxController {
} }
// 跳转到指定位置 // 跳转到指定位置
Future<void> seekToPosition1(int currentIdInternal, int newPosition, Future<void> seekToPosition1(String currentIdInternal, int newPosition,
int newDuration, double newProgress) async { int newDuration, double newProgress) async {
try { try {
//await _musiceManager.seekTo(positionMs); //await _musiceManager.seekTo(positionMs);
@ -1829,10 +1830,10 @@ class AgentController extends GetxController {
} }
/// 处理来自系统通知栏的跳转操作 /// 处理来自系统通知栏的跳转操作
Future<void> onMediaSessionSeekTo1(int currentIdInternal, int newPosition, Future<void> onMediaSessionSeekTo1(String currentIdInternal, int newPosition,
int newDuration, double newProgress) async { int newDuration, double newProgress) async {
print( print(
"onMediaSessionSeekTo1 newPosition:$newPosition newDuration:$newDuration newProgress:$newProgress"); "onMediaSessionSeekTo1 currentIdInternal :$currentIdInternal ,newPosition:$newPosition newDuration:$newDuration newProgress:$newProgress");
await seekToPosition1( await seekToPosition1(
currentIdInternal, newPosition, newDuration, newProgress); currentIdInternal, newPosition, newDuration, newProgress);
} }

9
lib/modules/agent/views/message_bubble.dart

@ -240,9 +240,11 @@ class MessageBubble extends GetView<AgentController> {
final musicUrl = card_music['url'] as String? ?? ''; final musicUrl = card_music['url'] as String? ?? '';
final musicSinger = card_music['sgener'] as String? ?? '未知歌手'; final musicSinger = card_music['sgener'] as String? ?? '未知歌手';
final musicImage = card_music['image'] as String? ?? ''; final musicImage = card_music['image'] as String? ?? '';
final ts = card_music['ts'] as int? ?? 0;
print("music_play card_music: $card_music");
//音乐卡片 //音乐卡片
return buildMusicItem( return buildMusicItem(context, musicId, musicName, musicUrl,
context, musicId, musicName, musicUrl, musicSinger, musicImage); musicSinger, musicImage, ts);
} }
} else if (meta!.keys.contains('music_playlist')) { } else if (meta!.keys.contains('music_playlist')) {
final card_musiclist = final card_musiclist =
@ -281,7 +283,8 @@ class MessageBubble extends GetView<AgentController> {
final end = card_navigation['end'] as String? ?? ''; final end = card_navigation['end'] as String? ?? '';
final destination = card_navigation['destination'] as String? ?? ''; final destination = card_navigation['destination'] as String? ?? '';
final rawList = card_navigation['items'] as List? ?? []; final rawList = card_navigation['items'] as List? ?? [];
final list = rawList.map((e) => Map<String, dynamic>.from(e)).toList(); final list =
rawList.map((e) => Map<String, dynamic>.from(e)).toList();
final rawNavigation = card_navigation['navigation']; final rawNavigation = card_navigation['navigation'];
final Map<String, dynamic>? navigation = final Map<String, dynamic>? navigation =
rawNavigation is Map<String, dynamic> ? rawNavigation : null; rawNavigation is Map<String, dynamic> ? rawNavigation : null;

6
lib/modules/agent/views/music_card.dart

@ -6,7 +6,7 @@ import 'circular_progress_button.dart';
/// 构建音乐项目 /// 构建音乐项目
Widget buildMusicItem(BuildContext context, int id, String name, String url, Widget buildMusicItem(BuildContext context, int id, String name, String url,
String singer, String image) { String singer, String image, int ts) {
final controller = Get.find<AgentController>(); // 获取控制器 final controller = Get.find<AgentController>(); // 获取控制器
final isDarkMode = Theme.of(context).brightness == Brightness.dark; final isDarkMode = Theme.of(context).brightness == Brightness.dark;
Map<String, dynamic> song = { Map<String, dynamic> song = {
@ -15,6 +15,7 @@ Widget buildMusicItem(BuildContext context, int id, String name, String url,
'title': name, 'title': name,
'artist': singer, 'artist': singer,
'coverUrl': image, 'coverUrl': image,
'ts': ts,
}; };
controller.musicStatus(); //刷新状态 controller.musicStatus(); //刷新状态
@ -204,9 +205,10 @@ Widget buildMusicContent(
final url = item["url"] ?? ""; final url = item["url"] ?? "";
final singer = item["sgener"] ?? "未知歌手"; final singer = item["sgener"] ?? "未知歌手";
final image = item["image"] ?? ""; final image = item["image"] ?? "";
final ts = item["ts"] ?? 0;
return Column( return Column(
children: [ children: [
buildMusicItem(context, id, name, url, singer, image), buildMusicItem(context, id, name, url, singer, image, ts),
if (index != playlist.length - 1) if (index != playlist.length - 1)
Divider( Divider(
height: 1, height: 1,

23
local_plugins/music_service/android/src/main/kotlin/com/yunqiinnovation/music_service/MusicService.kt

@ -38,7 +38,7 @@ class MusicService : MediaBrowserServiceCompat() {
private const val DELETE_ACTION = "com.yunqiinnovation.music_service.DELETE_NOTIFICATION" private const val DELETE_ACTION = "com.yunqiinnovation.music_service.DELETE_NOTIFICATION"
private val isRunning = AtomicBoolean(false) private val isRunning = AtomicBoolean(false)
private var currentIdInternal: Int? = null private var currentIdInternal: String? = null
private var currentStatus = false private var currentStatus = false
private var playlist = mutableListOf<Map<String,Any>>() private var playlist = mutableListOf<Map<String,Any>>()
private var currentIndex = 0 private var currentIndex = 0
@ -48,7 +48,7 @@ class MusicService : MediaBrowserServiceCompat() {
fun isServiceRunning() = isRunning.get() fun isServiceRunning() = isRunning.get()
fun isPlaying() = currentStatus fun isPlaying() = currentStatus
fun getCurrentId(): Int? = currentIdInternal fun getCurrentId(): String? = currentIdInternal
// // 获取播放进度信息 // // 获取播放进度信息
// fun getProgress(): Map<String, Any> { // fun getProgress(): Map<String, Any> {
@ -121,7 +121,8 @@ class MusicService : MediaBrowserServiceCompat() {
val title = song["title"] as? String ?: song["name"] as? String ?: "未知标题" val title = song["title"] as? String ?: song["name"] as? String ?: "未知标题"
val artist = song["artist"] as? String ?: song["sgener"] as? String ?: "未知歌手" val artist = song["artist"] as? String ?: song["sgener"] as? String ?: "未知歌手"
val coverUrl = song["coverUrl"] as? String ?: song["image"] as? String ?: "" val coverUrl = song["coverUrl"] as? String ?: song["image"] as? String ?: ""
currentIdInternal = song["id"] as? Int ?: song["id"] as? Int ?: 0 currentIdInternal = song["id"] as? String ?: song["id"] as? String ?: "0"
Log.i(TAG, "updateMediaSessionMetadata currentIdInternal: $currentIdInternal")
val metadata = android.support.v4.media.MediaMetadataCompat.Builder() val metadata = android.support.v4.media.MediaMetadataCompat.Builder()
.putString(android.support.v4.media.MediaMetadataCompat.METADATA_KEY_TITLE, title) .putString(android.support.v4.media.MediaMetadataCompat.METADATA_KEY_TITLE, title)
.putString(android.support.v4.media.MediaMetadataCompat.METADATA_KEY_ARTIST, artist) .putString(android.support.v4.media.MediaMetadataCompat.METADATA_KEY_ARTIST, artist)
@ -238,8 +239,10 @@ private fun updateProgress() {
"play" -> intent.getSerializableExtra("song")?.let { url -> "play" -> intent.getSerializableExtra("song")?.let { url ->
val songMap = intent.getSerializableExtra("song") as? Map<String, Any> val songMap = intent.getSerializableExtra("song") as? Map<String, Any>
songMap?.let { song -> songMap?.let { song ->
val songId = song["id"] ?: return@let val songId = song["id"]as? String ?:"0"
// currentIdInternal = songId Log.i(TAG, "command songId: $songId")
currentIdInternal = songId
val existingIndex = playlist.indexOfFirst { it["id"] == songId } val existingIndex = playlist.indexOfFirst { it["id"] == songId }
if (existingIndex == -1) { if (existingIndex == -1) {
playlist.add(song) playlist.add(song)
@ -547,13 +550,15 @@ private fun updateProgress() {
private fun play(song: Map<String,Any>) { private fun play(song: Map<String,Any>) {
val url = song["url"] as? String ?: return val url = song["url"] as? String ?: return
Log.i(TAG, "开始播放: $url") Log.i(TAG, "开始播放: $url")
val id = song["id"] as? Int ?: 0 val id = song["id"] as? String ?: "0"
Log.i(TAG, "开始播放play id: $id")
val title = song["title"] as? String ?: "未知标题" val title = song["title"] as? String ?: "未知标题"
val artist = song["artist"] as? String ?: "未知歌手" val artist = song["artist"] as? String ?: "未知歌手"
val coverUrl = song["coverUrl"] as String val coverUrl = song["coverUrl"] as String
mediaPlayer?.release() mediaPlayer?.release()
currentStatus = true currentStatus = true
currentIdInternal = id currentIdInternal = id
Log.i(TAG, "开始播放play currentIdInternal: $currentIdInternal")
mediaPlayer = MediaPlayer().apply { mediaPlayer = MediaPlayer().apply {
setDataSource(url) setDataSource(url)
setAudioStreamType(AudioManager.STREAM_MUSIC) setAudioStreamType(AudioManager.STREAM_MUSIC)
@ -585,7 +590,8 @@ private fun updateProgress() {
val title = song["title"] as? String ?: "未知标题" val title = song["title"] as? String ?: "未知标题"
val artist = song["artist"] as? String ?: "未知歌手" val artist = song["artist"] as? String ?: "未知歌手"
val coverUrl = song["coverUrl"] as String val coverUrl = song["coverUrl"] as String
val id = song["id"] as? Int ?: 0 val id = song["id"] as? String ?: "0"
Log.i(TAG, "pause id: $id")
currentIdInternal = id currentIdInternal = id
updateNotification(title,artist,coverUrl) updateNotification(title,artist,coverUrl)
setPlaybackState(PlaybackStateCompat.STATE_PAUSED); setPlaybackState(PlaybackStateCompat.STATE_PAUSED);
@ -605,7 +611,8 @@ private fun updateProgress() {
val title = song["title"] as? String ?: "未知标题" val title = song["title"] as? String ?: "未知标题"
val artist = song["artist"] as? String ?: "未知歌手" val artist = song["artist"] as? String ?: "未知歌手"
val coverUrl = song["coverUrl"] as String val coverUrl = song["coverUrl"] as String
val id = song["id"] as? Int ?: 0 val id = song["id"] as? String ?: "0"
Log.i(TAG, "resume id: $id")
currentIdInternal = id currentIdInternal = id
updateNotification(title,artist,coverUrl) updateNotification(title,artist,coverUrl)
setPlaybackState(PlaybackStateCompat.STATE_PLAYING); setPlaybackState(PlaybackStateCompat.STATE_PLAYING);

5
local_plugins/music_service/lib/music_service.dart

@ -101,7 +101,7 @@ class MusicService {
required Function() onPrevious, required Function() onPrevious,
required Function(int) onSeekTo, required Function(int) onSeekTo,
required Function() onStop, required Function() onStop,
required Function(int, int, int, double) onStop1, required Function(String, int, int, double) onStop1,
}) async { }) async {
// 设置方法调用处理器来处理来自原生平台的回调 // 设置方法调用处理器来处理来自原生平台的回调
_methodChannel.setMethodCallHandler((call) async { _methodChannel.setMethodCallHandler((call) async {
@ -126,7 +126,8 @@ class MusicService {
onStop(); onStop();
break; break;
case 'onMediaSessionSeekTo1': case 'onMediaSessionSeekTo1':
final currentIdInternal = call.arguments['currentIdInternal'] as int; final currentIdInternal =
call.arguments['currentIdInternal'] as String;
final currentPosition = call.arguments['currentPosition'] as int; final currentPosition = call.arguments['currentPosition'] as int;
final duration = call.arguments['duration'] as int; final duration = call.arguments['duration'] as int;
final progress = call.arguments['progress'] as double; final progress = call.arguments['progress'] as double;

Loading…
Cancel
Save