refactor: Recording dialog
This commit is contained in:
parent
be0fbd5ab0
commit
3286b19387
2 changed files with 21 additions and 23 deletions
|
|
@ -621,10 +621,10 @@ class ChatController extends State<ChatPageWithRoom>
|
||||||
builder: (c) => const RecordingDialog(),
|
builder: (c) => const RecordingDialog(),
|
||||||
);
|
);
|
||||||
if (result == null) return;
|
if (result == null) return;
|
||||||
final audioFile = File(result.path);
|
final audioFile = XFile(result.path);
|
||||||
final file = MatrixAudioFile(
|
final file = MatrixAudioFile(
|
||||||
bytes: audioFile.readAsBytesSync(),
|
bytes: await audioFile.readAsBytes(),
|
||||||
name: audioFile.path,
|
name: result.fileName ?? audioFile.path,
|
||||||
);
|
);
|
||||||
await room.sendFileEvent(
|
await room.sendFileEvent(
|
||||||
file,
|
file,
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||||
|
import 'package:path/path.dart' as path_lib;
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
import 'package:record/record.dart';
|
import 'package:record/record.dart';
|
||||||
import 'package:wakelock_plus/wakelock_plus.dart';
|
import 'package:wakelock_plus/wakelock_plus.dart';
|
||||||
|
|
@ -26,10 +28,12 @@ class RecordingDialogState extends State<RecordingDialog> {
|
||||||
Duration _duration = Duration.zero;
|
Duration _duration = Duration.zero;
|
||||||
|
|
||||||
bool error = false;
|
bool error = false;
|
||||||
String? _recordedPath;
|
|
||||||
final _audioRecorder = AudioRecorder();
|
final _audioRecorder = AudioRecorder();
|
||||||
final List<double> amplitudeTimeline = [];
|
final List<double> amplitudeTimeline = [];
|
||||||
|
|
||||||
|
String? fileName;
|
||||||
|
|
||||||
static const int bitRate = 64000;
|
static const int bitRate = 64000;
|
||||||
static const int samplingRate = 44100;
|
static const int samplingRate = 44100;
|
||||||
|
|
||||||
|
|
@ -37,9 +41,13 @@ class RecordingDialogState extends State<RecordingDialog> {
|
||||||
try {
|
try {
|
||||||
final useOpus =
|
final useOpus =
|
||||||
await _audioRecorder.isEncoderSupported(AudioEncoder.opus);
|
await _audioRecorder.isEncoderSupported(AudioEncoder.opus);
|
||||||
final tempDir = await getTemporaryDirectory();
|
fileName =
|
||||||
final path = _recordedPath =
|
'recording${DateTime.now().microsecondsSinceEpoch}.${useOpus ? 'ogg' : 'm4a'}';
|
||||||
'${tempDir.path}/recording${DateTime.now().microsecondsSinceEpoch}.${useOpus ? 'ogg' : 'm4a'}';
|
String? path;
|
||||||
|
if (!kIsWeb) {
|
||||||
|
final tempDir = await getTemporaryDirectory();
|
||||||
|
path = path_lib.join(tempDir.path, fileName);
|
||||||
|
}
|
||||||
|
|
||||||
final result = await _audioRecorder.hasPermission();
|
final result = await _audioRecorder.hasPermission();
|
||||||
if (result != true) {
|
if (result != true) {
|
||||||
|
|
@ -58,7 +66,7 @@ class RecordingDialogState extends State<RecordingDialog> {
|
||||||
noiseSuppress: true,
|
noiseSuppress: true,
|
||||||
encoder: useOpus ? AudioEncoder.opus : AudioEncoder.aacLc,
|
encoder: useOpus ? AudioEncoder.opus : AudioEncoder.aacLc,
|
||||||
),
|
),
|
||||||
path: path,
|
path: path ?? '',
|
||||||
);
|
);
|
||||||
setState(() => _duration = Duration.zero);
|
setState(() => _duration = Duration.zero);
|
||||||
_recorderSubscription?.cancel();
|
_recorderSubscription?.cancel();
|
||||||
|
|
@ -94,8 +102,8 @@ class RecordingDialogState extends State<RecordingDialog> {
|
||||||
|
|
||||||
void _stopAndSend() async {
|
void _stopAndSend() async {
|
||||||
_recorderSubscription?.cancel();
|
_recorderSubscription?.cancel();
|
||||||
await _audioRecorder.stop();
|
final path = await _audioRecorder.stop();
|
||||||
final path = _recordedPath;
|
|
||||||
if (path == null) throw ('Recording failed!');
|
if (path == null) throw ('Recording failed!');
|
||||||
const waveCount = AudioPlayerWidget.wavesCount;
|
const waveCount = AudioPlayerWidget.wavesCount;
|
||||||
final step = amplitudeTimeline.length < waveCount
|
final step = amplitudeTimeline.length < waveCount
|
||||||
|
|
@ -110,6 +118,7 @@ class RecordingDialogState extends State<RecordingDialog> {
|
||||||
path: path,
|
path: path,
|
||||||
duration: _duration.inMilliseconds,
|
duration: _duration.inMilliseconds,
|
||||||
waveform: waveform,
|
waveform: waveform,
|
||||||
|
fileName: fileName,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -220,23 +229,12 @@ class RecordingResult {
|
||||||
final String path;
|
final String path;
|
||||||
final int duration;
|
final int duration;
|
||||||
final List<int> waveform;
|
final List<int> waveform;
|
||||||
|
final String? fileName;
|
||||||
|
|
||||||
const RecordingResult({
|
const RecordingResult({
|
||||||
required this.path,
|
required this.path,
|
||||||
required this.duration,
|
required this.duration,
|
||||||
required this.waveform,
|
required this.waveform,
|
||||||
|
required this.fileName,
|
||||||
});
|
});
|
||||||
|
|
||||||
factory RecordingResult.fromJson(Map<String, dynamic> json) =>
|
|
||||||
RecordingResult(
|
|
||||||
path: json['path'],
|
|
||||||
duration: json['duration'],
|
|
||||||
waveform: List<int>.from(json['waveform']),
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'path': path,
|
|
||||||
'duration': duration,
|
|
||||||
'waveform': waveform,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue