9 changed files with 359 additions and 104 deletions
Split View
Diff Options
-
67ios/Podfile.lock
-
8ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
-
8ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
-
96lib/controller/message/voice_player_manager.dart
-
104lib/pages/message/chat_page.dart
-
1lib/widget/message/message_item.dart
-
122lib/widget/message/voice_item.dart
-
56pubspec.lock
-
1pubspec.yaml
@ -1,8 +0,0 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> |
|||
<plist version="1.0"> |
|||
<dict> |
|||
<key>IDEDidComputeMac32BitWarning</key> |
|||
<true/> |
|||
</dict> |
|||
</plist> |
|||
@ -1,8 +0,0 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> |
|||
<plist version="1.0"> |
|||
<dict> |
|||
<key>PreviewsEnabled</key> |
|||
<false/> |
|||
</dict> |
|||
</plist> |
|||
@ -0,0 +1,96 @@ |
|||
import 'package:audioplayers/audioplayers.dart'; |
|||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; |
|||
import 'package:get/get.dart'; |
|||
|
|||
/// 语音播放管理器,单例模式,统一管理语音播放 |
|||
class VoicePlayerManager extends GetxController { |
|||
static VoicePlayerManager? _instance; |
|||
static VoicePlayerManager get instance { |
|||
_instance ??= Get.put(VoicePlayerManager()); |
|||
return _instance!; |
|||
} |
|||
|
|||
final AudioPlayer _audioPlayer = AudioPlayer(); |
|||
String? _currentPlayingId; |
|||
final Rx<String?> currentPlayingId = Rx<String?>(null); |
|||
final Rx<PlayerState> playerState = Rx<PlayerState>(PlayerState.stopped); |
|||
|
|||
VoicePlayerManager() { |
|||
// 监听播放状态变化 |
|||
_audioPlayer.onPlayerStateChanged.listen((state) { |
|||
playerState.value = state; |
|||
if (state == PlayerState.completed) { |
|||
// 播放完成,重置状态 |
|||
_currentPlayingId = null; |
|||
currentPlayingId.value = null; |
|||
} |
|||
}); |
|||
} |
|||
|
|||
/// 播放音频 |
|||
/// [audioId] 音频的唯一标识(通常是消息ID) |
|||
/// [filePath] 音频文件路径 |
|||
Future<void> play(String audioId, String filePath) async { |
|||
try { |
|||
// 如果正在播放其他音频,先停止 |
|||
if (_currentPlayingId != null && _currentPlayingId != audioId) { |
|||
await stop(); |
|||
} |
|||
|
|||
// 如果是同一个音频,则暂停/恢复 |
|||
if (_currentPlayingId == audioId) { |
|||
if (playerState.value == PlayerState.playing) { |
|||
await _audioPlayer.pause(); |
|||
} else { |
|||
await _audioPlayer.resume(); |
|||
} |
|||
return; |
|||
} |
|||
// 播放新音频 |
|||
_currentPlayingId = audioId; |
|||
currentPlayingId.value = audioId; |
|||
await _audioPlayer.play(DeviceFileSource(filePath)); |
|||
} catch (e) { |
|||
print('播放音频失败: $e'); |
|||
_currentPlayingId = null; |
|||
currentPlayingId.value = null; |
|||
} |
|||
} |
|||
|
|||
/// 停止播放 |
|||
Future<void> stop() async { |
|||
try { |
|||
await _audioPlayer.stop(); |
|||
_currentPlayingId = null; |
|||
currentPlayingId.value = null; |
|||
} catch (e) { |
|||
print('停止播放失败: $e'); |
|||
} |
|||
} |
|||
|
|||
/// 暂停播放 |
|||
Future<void> pause() async { |
|||
try { |
|||
await _audioPlayer.pause(); |
|||
} catch (e) { |
|||
print('暂停播放失败: $e'); |
|||
} |
|||
} |
|||
|
|||
/// 检查指定音频是否正在播放 |
|||
bool isPlaying(String audioId) { |
|||
return _currentPlayingId == audioId && |
|||
playerState.value == PlayerState.playing; |
|||
} |
|||
|
|||
/// 检查指定音频是否已加载 |
|||
bool isLoaded(String audioId) { |
|||
return _currentPlayingId == audioId; |
|||
} |
|||
|
|||
@override |
|||
void onClose() { |
|||
_audioPlayer.dispose(); |
|||
super.onClose(); |
|||
} |
|||
} |
|||
Write
Preview
Loading…
Cancel
Save