Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.
 
 
 
 
 
 

117 рядки
3.5 KiB

  1. import 'dart:async';
  2. import 'dart:io';
  3. import 'dart:typed_data';
  4. import 'package:audioplayers/audioplayers.dart';
  5. import 'package:get/get.dart';
  6. import 'package:logger/logger.dart';
  7. import 'package:path_provider/path_provider.dart';
  8. class AudioTool {
  9. AudioTool._();
  10. static final AudioTool share = AudioTool._();
  11. factory AudioTool() => share;
  12. ///所有的音频数据
  13. List<Uint8List> _audioChunks = [];
  14. ///分断合并的数组,达到一定数量后合并去播放
  15. List<Uint8List> _playTemps = [];
  16. ///存放合并后的音频数组用于播放,播放完一个删除一个直到播放全部
  17. // List<Uint8List> _playBuff = [];
  18. ///是否已经播放了,play只被主动调用一次,然后根据_playBuff的数组递归
  19. bool isPlaying = false;
  20. final player = AudioPlayer();
  21. void dispose() async {
  22. await player.stop();
  23. await player.dispose();
  24. }
  25. void addAudioChunk({required AudioModel model, required Function(String) onPath, required Function() onPlaying, required Function() onPlayEnd}) async {
  26. if (model.status == 0 || model.status == 1) {
  27. _audioChunks.add(model.data);
  28. _playTemps.add(model.data);
  29. } else if (model.status == 2) {
  30. _audioChunks.add(model.data);
  31. _playTemps.add(model.data);
  32. final path = await mergeAudioChunks(sid: model.sid, chunks: _playTemps, onPlaying: onPlaying, onPlayEnd: onPlayEnd);
  33. onPath(path);
  34. }
  35. }
  36. Future<String> mergeAudioChunks({required String sid, required List<Uint8List> chunks, required Function() onPlaying, required Function() onPlayEnd}) async {
  37. // 计算总长度
  38. int totalLength = chunks.fold(0, (sum, chunk) => sum + chunk.length);
  39. // 创建合并后的 Uint8List
  40. final mergedData = Uint8List(totalLength);
  41. int offset = 0;
  42. for (var chunk in chunks) {
  43. mergedData.setRange(offset, offset + chunk.length, chunk);
  44. offset += chunk.length;
  45. }
  46. ///保存到文件或上传
  47. // Logger().f('------isFinal--------保存文件');
  48. _audioChunks = [];
  49. _playTemps = [];
  50. // _playBuff.add(mergedData);
  51. // if (!isPlaying) {
  52. // isPlaying = true;
  53. // play(bytes: mergedData, onPlaying: onPlaying, onPlayEnd: onPlayEnd);
  54. // }
  55. final dir = await getApplicationSupportDirectory();
  56. final path = dir.path + '/$sid.mp3';
  57. File file = File(path);
  58. await file.writeAsBytes(mergedData);
  59. return path;
  60. }
  61. void play({required Uint8List bytes, required Function() onPlaying, required Function() onPlayEnd}) async {
  62. // Logger().f('------_playBuff--------${_playBuff.length}');
  63. // if (_playBuff.isNotEmpty) {
  64. await player.onPlayerStateChanged.listen((sta) async {
  65. if (sta == PlayerState.completed) {
  66. isPlaying = false;
  67. // if (_playBuff.isNotEmpty) {
  68. // _playBuff.removeAt(0);
  69. // }
  70. onPlayEnd();
  71. }
  72. });
  73. final source = BytesSource(bytes, mimeType: 'audio/mp3');
  74. onPlaying();
  75. await player.play(source);
  76. // } else {
  77. // isPlaying = false;
  78. // }
  79. }
  80. static Uint8List mergeAudio({required List<Uint8List> chunks}) {
  81. // 计算总长度
  82. int totalLength = chunks.fold(0, (sum, chunk) => sum + chunk.length);
  83. // 创建合并后的 Uint8List
  84. final mergedData = Uint8List(totalLength);
  85. int offset = 0;
  86. for (var chunk in chunks) {
  87. mergedData.setRange(offset, offset + chunk.length, chunk);
  88. offset += chunk.length;
  89. }
  90. return mergedData;
  91. }
  92. }
  93. class AudioModel {
  94. int status;
  95. String sid;
  96. Uint8List data;
  97. AudioModel({required this.status, required this.sid, required this.data});
  98. }