|
|
@@ -6,8 +6,9 @@ import 'package:electronic_assistant/data/repositories/talk_repository.dart';
|
|
|
import 'package:electronic_assistant/dialog/alert_dialog.dart';
|
|
|
import 'package:electronic_assistant/module/record/constants.dart';
|
|
|
import 'package:electronic_assistant/module/talk/view.dart';
|
|
|
+import 'package:electronic_assistant/utils/http_handler.dart';
|
|
|
import 'package:electronic_assistant/utils/mmkv_util.dart';
|
|
|
-import 'package:flutter/cupertino.dart';
|
|
|
+import 'package:electronic_assistant/utils/toast_util.dart';
|
|
|
import 'package:get/get.dart';
|
|
|
import 'package:path_provider/path_provider.dart';
|
|
|
import 'package:record/record.dart';
|
|
|
@@ -23,13 +24,13 @@ class RecordController extends BaseController {
|
|
|
FrameAnimationController(autoPlay: false);
|
|
|
final Rx<RecordStatus> currentStatus = RecordStatus.pending.obs;
|
|
|
final RxDouble currentDuration = 0.0.obs;
|
|
|
- final AudioRecorder record = AudioRecorder();
|
|
|
- final RecordConfig recordConfig = const RecordConfig(
|
|
|
+ final AudioRecorder _record = AudioRecorder();
|
|
|
+ final RecordConfig _recordConfig = const RecordConfig(
|
|
|
encoder: AudioEncoder.pcm16bits,
|
|
|
bitRate: 128000,
|
|
|
sampleRate: 44100,
|
|
|
numChannels: 2);
|
|
|
- late final String lastRecordId;
|
|
|
+ late final String _lastRecordId;
|
|
|
|
|
|
@override
|
|
|
void onInit() {
|
|
|
@@ -38,13 +39,19 @@ class RecordController extends BaseController {
|
|
|
_initLastRecordStatus();
|
|
|
}
|
|
|
|
|
|
+ @override
|
|
|
+ void onClose() {
|
|
|
+ super.onClose();
|
|
|
+ _record.dispose();
|
|
|
+ }
|
|
|
+
|
|
|
void _initLastRecordId() {
|
|
|
String? lastRecordId = KVUtil.getString(keyLastRecordId, null);
|
|
|
if (lastRecordId == null || lastRecordId.isEmpty) {
|
|
|
- this.lastRecordId = const Uuid().v4();
|
|
|
- KVUtil.putString(keyLastRecordId, this.lastRecordId);
|
|
|
+ _lastRecordId = const Uuid().v4();
|
|
|
+ KVUtil.putString(keyLastRecordId, _lastRecordId);
|
|
|
} else {
|
|
|
- this.lastRecordId = lastRecordId;
|
|
|
+ _lastRecordId = lastRecordId;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -53,8 +60,8 @@ class RecordController extends BaseController {
|
|
|
var fileLength = currentRecordFile.lengthSync();
|
|
|
if (currentRecordFile.existsSync() && fileLength > 0) {
|
|
|
_changeRecordStatus(RecordStatus.paused);
|
|
|
- currentDuration.value = await _getPcmDuration(
|
|
|
- fileLength, recordConfig.sampleRate, 16, recordConfig.numChannels);
|
|
|
+ currentDuration.value = _getPcmDuration(
|
|
|
+ fileLength, _recordConfig.sampleRate, 16, _recordConfig.numChannels);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -116,19 +123,19 @@ class RecordController extends BaseController {
|
|
|
}
|
|
|
|
|
|
Future<void> _startOrContinueRecord() async {
|
|
|
- bool hasPermission = await record.hasPermission();
|
|
|
+ bool hasPermission = await _record.hasPermission();
|
|
|
if (!hasPermission) {
|
|
|
_onRecordPermissionDenied();
|
|
|
return;
|
|
|
}
|
|
|
File targetFile = await _getCurrentRecordFile();
|
|
|
- Stream<Uint8List> recordStream = await record.startStream(recordConfig);
|
|
|
+ Stream<Uint8List> recordStream = await _record.startStream(_recordConfig);
|
|
|
_changeRecordStatus(RecordStatus.recording);
|
|
|
recordStream.listen((data) async {
|
|
|
targetFile.writeAsBytesSync(data, mode: FileMode.append);
|
|
|
currentDuration.value = currentDuration.value +
|
|
|
- await _getPcmDuration(data.length, recordConfig.sampleRate, 16,
|
|
|
- recordConfig.numChannels);
|
|
|
+ _getPcmDuration(data.length, _recordConfig.sampleRate, 16,
|
|
|
+ _recordConfig.numChannels);
|
|
|
}, onDone: () {
|
|
|
_changeRecordStatus(RecordStatus.paused);
|
|
|
}, onError: (error) {
|
|
|
@@ -139,20 +146,20 @@ class RecordController extends BaseController {
|
|
|
_onRecordPermissionDenied() {}
|
|
|
|
|
|
Future<void> _stopRecord() {
|
|
|
- return record.stop().then((_) => _changeRecordStatus(RecordStatus.paused));
|
|
|
+ return _record.pause().then((_) => _changeRecordStatus(RecordStatus.paused));
|
|
|
}
|
|
|
|
|
|
Future<File> _getCurrentRecordFile() async {
|
|
|
Directory documentDir = await getApplicationDocumentsDirectory();
|
|
|
- File file = File("${documentDir.path}/.atmob/record/$lastRecordId");
|
|
|
+ File file = File("${documentDir.path}/.atmob/record/$_lastRecordId");
|
|
|
if (!file.existsSync()) {
|
|
|
file.createSync(recursive: true);
|
|
|
}
|
|
|
return file;
|
|
|
}
|
|
|
|
|
|
- Future<double> _getPcmDuration(
|
|
|
- int fileSize, int sampleRate, int bitDepth, int channels) async {
|
|
|
+ double _getPcmDuration(
|
|
|
+ int fileSize, int sampleRate, int bitDepth, int channels) {
|
|
|
final bytesPerSecond = sampleRate * (bitDepth / 8) * channels;
|
|
|
final durationInSeconds = fileSize / bytesPerSecond;
|
|
|
return durationInSeconds;
|
|
|
@@ -173,13 +180,13 @@ class RecordController extends BaseController {
|
|
|
Future<void> _saveCurrentRecord() async {
|
|
|
await _stopRecord();
|
|
|
talkRepository
|
|
|
- .talkCreate(lastRecordId, currentDuration.value.toInt())
|
|
|
+ .talkCreate(_lastRecordId, currentDuration.value.toInt())
|
|
|
.then((talkInfo) async {
|
|
|
File pcmFile = await _getCurrentRecordFile();
|
|
|
if (pcmFile.existsSync()) {
|
|
|
File wavFile = await getRecordFile(talkInfo.id);
|
|
|
- PcmWavConverter.convert(pcmFile, wavFile, recordConfig.sampleRate,
|
|
|
- recordConfig.numChannels, 16);
|
|
|
+ PcmWavConverter.convert(pcmFile, wavFile, _recordConfig.sampleRate,
|
|
|
+ _recordConfig.numChannels, 16);
|
|
|
pcmFile.delete();
|
|
|
Get.back();
|
|
|
TalkPage.start(talkInfo);
|
|
|
@@ -187,7 +194,11 @@ class RecordController extends BaseController {
|
|
|
throw Exception("pcm file not found");
|
|
|
}
|
|
|
}).catchError((error) {
|
|
|
- debugPrint(error);
|
|
|
+ if (error is ServerErrorException) {
|
|
|
+ ToastUtil.showToast("${error.message}");
|
|
|
+ } else {
|
|
|
+ ToastUtil.showToast("保存失败, 请重试");
|
|
|
+ }
|
|
|
});
|
|
|
}
|
|
|
|