You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

326 lines
9.0 KiB

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:qq_music/qq_music.dart';
import 'package:voitrans/data/services/qq_musoc.dart';
import '../models/song_model.dart';
class QQMusicController extends GetxController {
final QqMusocService _qqMusic = Get.find<QqMusocService>();
// 登录状态
final isLoggedIn = false.obs;
final userInfo = Rxn<QQMusicLoginResult>();
// 搜索相关
final searchResults = <SongModel>[].obs;
final isSearching = false.obs;
final searchKeyword = ''.obs;
// 播放相关
final currentSong = Rxn<SongModel>();
final isPlaying = false.obs;
final currentPosition = 0.obs;
final totalDuration = 0.obs;
final playlist = <SongModel>[].obs;
final currentIndex = 0.obs;
@override
void onInit() {
super.onInit();
_checkLoginStatus();
_startPlaybackStateMonitor();
}
/// 检查登录状态
void _checkLoginStatus() {
// 这里可以检查本地存储的登录信息
// 暂时设为未登录状态
isLoggedIn.value = false;
}
/// QQ音乐登录
Future<void> login() async {
try {
print('开始QQ音乐登录...');
Get.dialog(
const Center(
child: CircularProgressIndicator(),
),
barrierDismissible: false,
);
// 添加超时处理
final result = await _qqMusic.login().timeout(
const Duration(seconds: 30),
onTimeout: () {
print('QQ音乐登录超时');
return {'success': false, 'error': '登录超时,请重试'};
},
);
print('QQ音乐登录结果: $result');
Get.back(); // 关闭加载对话框
if (result['success'] == true) {
userInfo.value = QQMusicLoginResult.fromMap(result);
isLoggedIn.value = true;
print('QQ音乐登录成功: ${result['openId']}');
Get.snackbar('登录成功', '欢迎使用QQ音乐');
} else {
print('QQ音乐登录失败: ${result['error']}');
Get.snackbar('登录失败', result['error'] ?? '未知错误');
}
} catch (e) {
print('QQ音乐登录异常: $e');
Get.back();
Get.snackbar('登录失败', e.toString());
}
}
/// 退出登录
void logout() {
userInfo.value = null;
isLoggedIn.value = false;
currentSong.value = null;
isPlaying.value = false;
playlist.clear();
Get.snackbar('已退出', '已退出QQ音乐登录');
}
/// 搜索歌曲
Future<void> searchSongs(String keyword) async {
if (keyword.trim().isEmpty) return;
print('开始搜索歌曲: $keyword');
searchKeyword.value = keyword;
isSearching.value = true;
try {
// 检查登录状态
if (!isLoggedIn.value) {
print('用户未登录,无法搜索');
Get.snackbar('搜索失败', '请先登录QQ音乐');
return;
}
print('调用搜索接口...');
final result = await _qqMusic.searchSongs(keyword: keyword).timeout(
const Duration(seconds: 15),
onTimeout: () {
print('搜索超时');
return {'success': false, 'error': '搜索超时,请重试'};
},
);
print('搜索结果: $result');
if (result['success'] == true && result['songs'] != null) {
final List<dynamic> songsData = result['songs'];
print('找到 ${songsData.length} 首歌曲');
final songs = songsData.map((songData) {
return SongModel(
mid: songData['mid'] ?? '',
name: songData['name'] ?? '',
artist: songData['singer'] ?? '',
album: songData['album'] ?? '',
albumPic: songData['pic'],
duration: songData['duration'] ?? 0,
);
}).toList();
searchResults.assignAll(songs);
print('搜索成功,更新UI');
} else {
print('搜索失败: ${result['error']}');
Get.snackbar('搜索失败', result['error'] ?? '搜索结果为空');
searchResults.clear();
}
} catch (e) {
print('搜索异常: $e');
Get.snackbar('搜索失败', e.toString());
searchResults.clear();
} finally {
print('搜索完成,重置状态');
isSearching.value = false;
}
}
/// 播放歌曲
Future<void> playSong(SongModel song, {List<SongModel>? songList}) async {
try {
currentSong.value = song;
if (songList != null) {
playlist.assignAll(songList);
currentIndex.value = songList.indexOf(song);
} else {
playlist.assignAll([song]);
currentIndex.value = 0;
}
// 获取歌曲MID列表
final songMids = playlist.map((s) => s.mid).toList();
final playIndex = currentIndex.value;
// 调用QQ音乐播放接口
final result = await _qqMusic.playSongs(
songMids: songMids,
index: playIndex,
);
if (result['success'] == true) {
isPlaying.value = true;
totalDuration.value = song.duration;
currentPosition.value = 0;
Get.snackbar('开始播放', song.name);
} else {
Get.snackbar('播放失败', result['error'] ?? '未知错误');
}
} catch (e) {
Get.snackbar('播放失败', e.toString());
}
}
/// 暂停/继续播放
Future<void> togglePlayPause() async {
try {
if (isPlaying.value) {
final result = await _qqMusic.pauseMusic();
if (result['success'] == true) {
isPlaying.value = false;
}
} else {
final result = await _qqMusic.resumeMusic();
if (result['success'] == true) {
isPlaying.value = true;
}
}
} catch (e) {
Get.snackbar('操作失败', e.toString());
}
}
/// 上一首
Future<void> previousSong() async {
try {
final result = await _qqMusic.skipToPrevious();
if (result['success'] == true) {
if (playlist.isNotEmpty) {
int newIndex = currentIndex.value - 1;
if (newIndex < 0) newIndex = playlist.length - 1;
currentIndex.value = newIndex;
currentSong.value = playlist[newIndex];
}
await _updateCurrentSong();
}
} catch (e) {
Get.snackbar('切换失败', e.toString());
}
}
/// 下一首
Future<void> nextSong() async {
try {
final result = await _qqMusic.skipToNext();
if (result['success'] == true) {
if (playlist.isNotEmpty) {
int newIndex = currentIndex.value + 1;
if (newIndex >= playlist.length) newIndex = 0;
currentIndex.value = newIndex;
currentSong.value = playlist[newIndex];
}
await _updateCurrentSong();
}
} catch (e) {
Get.snackbar('切换失败', e.toString());
}
}
/// 停止播放
Future<void> stopMusic() async {
try {
final result = await _qqMusic.stopMusic();
if (result['success'] == true) {
isPlaying.value = false;
currentPosition.value = 0;
}
} catch (e) {
Get.snackbar('停止失败', e.toString());
}
}
/// 更新当前播放歌曲信息
Future<void> _updateCurrentSong() async {
try {
final result = await _qqMusic.getCurrentSong();
if (result['success'] == true && result['song'] != null) {
final songData = result['song'];
final song = SongModel(
mid: songData['mid'] ?? '',
name: songData['name'] ?? '',
artist: songData['singer'] ?? '',
album: songData['album'] ?? '',
albumPic: songData['pic'],
duration: songData['duration'] ?? 0,
);
currentSong.value = song;
}
} catch (e) {
print('更新当前歌曲信息失败: $e');
}
}
/// 启动播放状态监控
void _startPlaybackStateMonitor() {
// 每秒检查一次播放状态和时间
Stream.periodic(const Duration(seconds: 1)).listen((_) async {
if (isLoggedIn.value) {
await _updatePlaybackState();
await _updatePlayTime();
}
});
}
/// 更新播放状态
Future<void> _updatePlaybackState() async {
try {
final result = await _qqMusic.getPlaybackState();
if (result['success'] == true && result['state'] != null) {
final state = result['state'];
// QQ音乐播放状态:0-停止,1-播放,2-暂停
isPlaying.value = state == 1;
}
} catch (e) {
// 静默处理错误,避免频繁弹窗
}
}
/// 更新播放时间
Future<void> _updatePlayTime() async {
try {
final result = await _qqMusic.getPlayTime();
if (result['success'] == true) {
currentPosition.value = result['currentTime'] ?? 0;
totalDuration.value = result['totalTime'] ?? 0;
}
} catch (e) {
// 静默处理错误,避免频繁弹窗
}
}
/// 跳转到指定位置(暂时保留,QQ音乐可能不支持)
void seekTo(int position) {
currentPosition.value = position;
// QQ音乐SDK可能不支持跳转功能
Get.snackbar('提示', '当前版本不支持跳转功能');
}
@override
void onClose() {
// 清理资源
super.onClose();
}
}