Skip to content

Commit ac810e1

Browse files
committed
fix(Linux): Bad state: StreamSink is bound to a stream error when stopping recording.
fixes #530
1 parent fe1d09a commit ac810e1

File tree

3 files changed

+16
-22
lines changed

3 files changed

+16
-22
lines changed

record_linux/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
## 1.2.1
2+
* fix: Bad state: StreamSink is bound to a stream error when stopping recording.
3+
14
## 1.2.0
25
* feat: Implement amplitude (dBFS)
36

record_linux/lib/record_linux.dart

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ class RecordLinux extends RecordPlatform {
1919
StreamController<RecordState>? _stateStreamCtrl;
2020
Process? _parecordProcess;
2121
Process? _ffmpegProcess;
22-
StreamController<List<int>>? _amplitudeStreamController;
22+
StreamController<List<int>>? _inputPcmController;
2323
double _currentAmplitude = -160.0;
2424
double _maxAmplitude = -160.0;
2525

@@ -138,18 +138,17 @@ class RecordLinux extends RecordPlatform {
138138
final path = _path;
139139

140140
// Close amplitude stream controller
141-
await _amplitudeStreamController?.close();
142-
_amplitudeStreamController = null;
141+
await _inputPcmController?.close();
142+
_inputPcmController = null;
143143

144144
// Kill parecord first
145145
_parecordProcess?.kill();
146146
_parecordProcess = null;
147147

148148
// Close ffmpeg stdin and wait for it to finish
149-
if (_ffmpegProcess != null) {
150-
await _ffmpegProcess!.stdin.close();
149+
if (_ffmpegProcess case final process?) {
151150
// Wait for ffmpeg to finish writing
152-
await _ffmpegProcess!.exitCode;
151+
await process.exitCode;
153152
_ffmpegProcess = null;
154153
}
155154

@@ -377,7 +376,7 @@ class RecordLinux extends RecordPlatform {
377376
}
378377
}
379378

380-
// Calculate dBFS (same formula as other platforms)
379+
// Calculate dBFS
381380
if (maxSample > 0) {
382381
_currentAmplitude = 20 * (log(maxSample / 32767.0) / ln10);
383382
} else {
@@ -415,30 +414,22 @@ class RecordLinux extends RecordPlatform {
415414

416415
_ffmpegProcess = await Process.start(_ffmpegBin, ffmpegArgs);
417416

418-
// Log ffmpeg stderr for debugging (remove this after testing)
419-
_ffmpegProcess!.stderr.transform(utf8.decoder).listen((data) {
420-
if (data.isNotEmpty) {
421-
debugPrint('FFmpeg: $data');
422-
}
423-
});
424-
425417
// Create a passthrough stream controller to intercept audio data
426-
_amplitudeStreamController = StreamController<List<int>>();
418+
_inputPcmController = StreamController<List<int>>();
427419

428420
// Listen to raw PCM data from parecord:
429421
// 1. Calculate amplitude for VU meter
430422
// 2. Forward the unchanged PCM data to our stream controller
431423
parecordProc.stdout.listen((data) {
432424
_calculateAmplitude(Uint8List.fromList(data));
433-
if (!_amplitudeStreamController!.isClosed) {
434-
_amplitudeStreamController!.add(data);
425+
426+
if (_inputPcmController case final ctrl? when !ctrl.isClosed) {
427+
ctrl.add(data);
435428
}
436-
}, onDone: () {
437-
_amplitudeStreamController?.close();
438-
});
429+
}, onDone: () => _inputPcmController?.close());
439430

440431
// Pipe the PCM data from our controller to ffmpeg for encoding
441432
// This uses pipe() for proper backpressure handling
442-
_amplitudeStreamController!.stream.pipe(_ffmpegProcess!.stdin);
433+
_inputPcmController!.stream.pipe(_ffmpegProcess!.stdin);
443434
}
444435
}

record_linux/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: record_linux
22
description: Linux specific implementation for record package called by record_platform_interface.
3-
version: 1.2.0
3+
version: 1.2.1
44
homepage: https://github.com/llfbandit/record/tree/master/record_linux
55

66
environment:

0 commit comments

Comments
 (0)