ToneSnap_FSX_Flutter/lib/modules/sidea/controllers/player_controller.dart
fengshengxiong 7611e78244 1.变声加入广告和Firebase
2.音乐播放器首页完成数据加载展示
2024-06-26 15:32:21 +08:00

183 lines
5.1 KiB
Dart

// Author: fengshengxiong
// Date: 2024/5/30
// Description: 播放器控制器
import 'dart:async';
import 'dart:io';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:just_audio/just_audio.dart';
import 'package:tone_snap/components/base_easyloading.dart';
import 'package:tone_snap/utils/audio_util.dart';
import 'package:tone_snap/utils/log_util.dart';
class PlayerController extends GetxController {
static PlayerController get to => Get.put(PlayerController());
StreamSubscription<PlayerState>? _playerStateSubscription;
StreamSubscription<Duration>? _durationSubscription;
final _player = AudioPlayer();
var filePath = '';
var isPlaying = false.obs;
var isCompleted = true.obs;
var positionValue = 0.0.obs;
var duration = const Duration().obs;
var positionDuration = const Duration().obs;
var isReady = false;
@override
void onInit() {
super.onInit();
AudioUtil.configAudioSession();
}
@override
void onClose() {
_stopListening();
_player.dispose();
super.onClose();
}
Future<void> setFilePath(String filePath) async {
if (!filePath.contains('assets') && !await _fileExists(filePath)) return;
if (this.filePath != filePath) {
this.filePath = filePath;
try {
isReady = false;
if (filePath.contains('assets')) {
duration.value = await _player.setAsset(filePath) ?? Duration.zero;
} else {
duration.value = await _player.setFilePath(filePath) ?? Duration.zero;
}
isReady = true;
} on PlayerException catch (e) {
LogUtil.e("Error code: ${e.code}");
LogUtil.e("Error message: ${e.message}");
BaseEasyLoading.toast("Error message: ${e.message}");
} on PlayerInterruptedException catch (e) {
LogUtil.e("Connection aborted: ${e.message}");
BaseEasyLoading.toast("Connection aborted: ${e.message}");
} catch (e) {
LogUtil.e('An error occured: $e');
BaseEasyLoading.toast('An error occured: $e');
}
}
}
/// 监听
void _startListening() {
_playerStateSubscription = _player.playerStateStream.listen((playerState) {
switch (playerState.processingState) {
case ProcessingState.idle:
break;
case ProcessingState.loading:
break;
case ProcessingState.buffering:
break;
case ProcessingState.ready:
break;
case ProcessingState.completed:
isCompleted.value = true;
_player.seek(Duration.zero);
pausePlay();
break;
}
});
_durationSubscription = _player.positionStream.listen((position) {
if (_player.duration != null) {
duration.value = _player.duration!;
positionDuration.value = position;
positionValue.value = position.inMilliseconds.toDouble() / _player.duration!.inMilliseconds.toDouble();
}
}, onError: (Object e, StackTrace st) {
if (e is PlatformException) {
LogUtil.e('Error code: ${e.code}');
LogUtil.e('Error message: ${e.message}');
LogUtil.e('AudioSource index: ${e.details?['index']}');
BaseEasyLoading.toast('Error message: ${e.message}');
} else {
LogUtil.e('An error occurred: $e');
BaseEasyLoading.toast('An error occurred: $e');
}
});
}
void _stopListening() {
_playerStateSubscription?.cancel();
_playerStateSubscription = null;
_durationSubscription?.cancel();
_durationSubscription = null;
}
/// 开始播放
Future<void> startPlay() async {
if (!filePath.contains('assets') && !await _fileExists(filePath)) return;
if (!isReady) {
BaseEasyLoading.toast('Loading audio source');
return;
}
_startListening();
_player.play();
isPlaying.value = true;
isCompleted.value = false;
}
/// 暂停播放
Future<void> pausePlay() async {
await _player.pause();
isPlaying.value = false;
_stopListening();
}
/// 停止播放并释放资源
Future<void> stopPlay() async {
await _player.stop();
_stopListening();
_player.seek(Duration.zero);
isPlaying.value = false;
isCompleted.value = true;
positionValue.value = 0.0;
// duration.value = Duration.zero;
positionDuration.value = Duration.zero;
}
String getDuration() {
return printDuration(duration.value);
}
String getPositionDuration() {
return printDuration(positionDuration.value);
}
/// 打印持续时间
String printDuration(Duration duration) {
String twoDigits(int n) => n.toString().padLeft(2, '0');
final minutes = twoDigits(duration.inMinutes.remainder(60));
final seconds = twoDigits(duration.inSeconds.remainder(60));
return '$minutes:$seconds';
}
/// 判断文件是否存在
Future<bool> _fileExists(String path) async {
if (await File(path).exists()) {
return true;
} else {
BaseEasyLoading.toast('Audio does not exist');
return false;
}
}
/// 设置声调
Future<void> setPitch(double setPitch) async {
await _player.setPitch(setPitch);
}
/// 设置声速
Future<void> setSpeed(double speed) async {
await _player.setSpeed(speed);
}
}