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.
 
 
 
 
 
 

185 lines
5.6 KiB

  1. import 'dart:convert';
  2. import 'dart:io';
  3. import 'dart:typed_data';
  4. import 'package:demo001/scenes/translate/TranslateState.dart';
  5. import 'package:demo001/tools/audio_tool.dart';
  6. import 'package:demo001/xunfei/phonetic_dictation/phonetic_dictaion_model/w.dart';
  7. import 'package:demo001/xunfei/recognition_result/recognition_content/recognition_content.dart';
  8. import 'package:demo001/xunfei/xunfei_translate.dart';
  9. import 'package:get/get.dart';
  10. import 'package:logger/logger.dart';
  11. import 'package:path_provider/path_provider.dart';
  12. import 'package:permission_handler/permission_handler.dart';
  13. import 'package:record/record.dart';
  14. class TranslateLogic extends GetxController {
  15. late Directory savedirectory;
  16. final state = TranslateState();
  17. late XunFeiTranslate xunfei;
  18. late AudioRecorder _recorder;
  19. @override
  20. void onInit() {
  21. super.onInit();
  22. _requestPermissions();
  23. _recorder = AudioRecorder();
  24. xunfei = XunFeiTranslate(
  25. appId: "137dc132",
  26. apiKey: "1c1891a475e71250ecd1320303ad6545",
  27. apiSecret: "MjZhNDA1NTI1NWZkZDQxOTMxYzMyN2Yw",
  28. onRecognitionResult: _handleRecognaitionData,
  29. onStreamtransResult: _handleTranslateData,
  30. onAudioResult: _handleAudioData);
  31. }
  32. // 初始化录音器
  33. void _initRecorder() async {
  34. try {
  35. // 获取外部存储目录路径
  36. savedirectory = (await getExternalStorageDirectory())!;
  37. state.isRecorderReady.value = true;
  38. _log('录音器初始化成功');
  39. } catch (e) {
  40. _log('初始化录音器失败: $e');
  41. state.isRecorderReady.value = false;
  42. }
  43. }
  44. // 请求麦克风权限
  45. void _requestPermissions() async {
  46. try {
  47. if (await Permission.microphone.request().isGranted) {
  48. _log('麦克风权限已授予');
  49. } else {
  50. _log('麦克风权限被拒绝');
  51. }
  52. } catch (e) {
  53. _log('请求麦克风权限失败: $e');
  54. }
  55. }
  56. // 切换按钮状态
  57. void toggleCallStatus() {
  58. if (!state.isRecording.value) {
  59. //开始通话
  60. _startRecorder();
  61. } else {
  62. //结束通话
  63. _stopRecorder();
  64. }
  65. state.isRecording.value = !state.isRecording.value;
  66. }
  67. //开始录音
  68. void _startRecorder() async {
  69. try {
  70. if (!state.isRecorderReady.value) {
  71. _initRecorder();
  72. }
  73. if (state.isRecording.value) return; // 防止重复调用
  74. Stream<Uint8List> dataStream = await _recorder.startStream(RecordConfig(
  75. sampleRate: 16000, encoder: AudioEncoder.pcm16bits, numChannels: 1));
  76. xunfei.starttranslate(dataStream);
  77. state.isRecording.value = true;
  78. _log('录音开始');
  79. } catch (e) {
  80. _log('录音开始 异常: $e');
  81. }
  82. }
  83. //结束录音
  84. void _stopRecorder() async {
  85. try {
  86. if (!state.isRecording.value) return; // 防止重复调用
  87. await _recorder.stop();
  88. await _recorder.cancel();
  89. xunfei.stoptranslate();
  90. state.isRecorderReady.value = false;
  91. state.isRecording.value = false;
  92. _log('录音停止');
  93. } catch (e) {
  94. _log('录音停止 异常: $e');
  95. }
  96. }
  97. void _handleRecognaitionData(result) {
  98. KDXFSentenceModel model;
  99. String text = "";
  100. try {
  101. final index = state.kdxfSentenceList.indexWhere((KDXFSentenceModel e) {
  102. return e.sid == result.header?.sid;
  103. });
  104. if (index != -1) {
  105. model = state.kdxfSentenceList[index];
  106. final recogContextStr = utf8.decode(
  107. base64Decode(result.payload?.recognitionResults?.text ?? ''));
  108. final ctx = RecognitionContent.fromJson(jsonDecode(recogContextStr));
  109. if (ctx.pgs == 'apd') {
  110. String text = state.kdxfSentenceList[index].content;
  111. state.kdxfSentenceList[index].contentList.add(ctx);
  112. ctx.ws!.forEach((e) {
  113. e.cw?.forEach((e2) {
  114. text = text + (e2.w ?? '');
  115. });
  116. });
  117. if (text.trim() == '') return;
  118. state.kdxfSentenceList[index].content = text;
  119. state.kdxfSentenceList.refresh();
  120. } else if (ctx.pgs == 'rpl') {
  121. String text = '';
  122. for (var i = ctx.rg?[0]; i! <= ctx.rg![1]; i++) {
  123. state.kdxfSentenceList[index].contentList.removeWhere((ee) {
  124. return ee.sn == i;
  125. });
  126. }
  127. state.kdxfSentenceList[index].contentList.add(ctx);
  128. state.kdxfSentenceList[index].contentList.forEach((e) {
  129. e.ws?.forEach((ee) {
  130. ee.cw?.forEach((e2) {
  131. text = text + (e2.w ?? '');
  132. });
  133. });
  134. });
  135. if (text.trim() == '') return;
  136. state.kdxfSentenceList[index].content = text;
  137. state.kdxfSentenceList.refresh();
  138. // }
  139. }
  140. } else {
  141. final recogContextStr = utf8.decode(
  142. base64Decode(result.payload?.recognitionResults?.text ?? ''));
  143. final ctx = RecognitionContent.fromJson(jsonDecode(recogContextStr));
  144. ctx.ws!.forEach((e) {
  145. e.cw?.forEach((e2) {
  146. text = text + (e2.w ?? '');
  147. });
  148. });
  149. if (text == '') return;
  150. model = KDXFSentenceModel(
  151. content: text,
  152. sid: result.header?.sid ?? '',
  153. transResult: '',
  154. audioPath: '',
  155. perviousWs: (ctx.ws ?? []) as List<W>,
  156. );
  157. state.kdxfSentenceList.add(model);
  158. state.kdxfSentenceList.refresh();
  159. }
  160. } catch (e) {
  161. print("接收识别结果异常 $e");
  162. }
  163. }
  164. void _handleTranslateData(result) {}
  165. void _handleAudioData(AudioModel model) {}
  166. void kdxfPlayAudio(KDXFSentenceModel model) async {
  167. model.playerController.startPlayer();
  168. }
  169. void _log(String msg) {
  170. Logger().f("LIWEI---------------:$msg");
  171. }
  172. }