Operationg multiple flutter_sound instance independently
See original GitHub issueVersion of flutter_sound
flutter_sound: ^2.0.4
flutter doctor
[√] Flutter (Channel stable, v1.12.13+hotfix.8, on Microsoft Windows [Version 10.0.17763.1039], locale ja-JP)
[√] Android toolchain - develop for Android devices (Android SDK version 29.0.3) [√] Android Studio (version 3.6) [√] VS Code, 64-bit edition (version 1.42.1) [√] Connected device (1 available)
Platforms you faced the error (IOS or Android or both?)
Tested on Android
Expected behavior
- Call only one
onRecorderDbPeakChanged
callback within the multipleFlutterSound
instances. - Able to stop any recorder one of them.
Actual behavior
onRecorderDbPeakChanged
for allFlutterSound
instances.- Can only control the recorder that started last.
Restarted application in 1,157ms.
D/FlutterSoundPlugin(11332): rawAmplitude: 0.0 Base DB: 0.0
I/flutter (11332): startRecorder: /data/user/0/com.dooboolab.fluttersoundexample/cache/file_dbLevel_disable.aac
D/FlutterSoundPlugin(11332): rawAmplitude: 0.0 Base DB: 0.0
I/flutter (11332):
I/flutter (11332): got dB update of file_dbLevel_disable -> 0.0
I/flutter (11332): 2020-03-04T15:24:33.141111
I/flutter (11332): startRecorder: /data/user/0/com.dooboolab.fluttersoundexample/cache/file_dbLevel_enable.aac
D/FlutterSoundPlugin(11332): rawAmplitude: 1410.0 Base DB: 42.67625931342095
I/flutter (11332):
I/flutter (11332): got dB update of file_dbLevel_disable -> 42.67625931342095
I/flutter (11332): 2020-03-04T15:24:34.111216
I/flutter (11332):
I/flutter (11332): got dB update of file_dbLevel_enable -> 42.67625931342095
I/flutter (11332): 2020-03-04T15:24:34.111296
D/FlutterSoundPlugin(11332): rawAmplitude: 1175.0 Base DB: 41.09263439246845
I/flutter (11332):
I/flutter (11332): got dB update of file_dbLevel_disable -> 41.09263439246845
I/flutter (11332): 2020-03-04T15:24:35.112086
I/flutter (11332):
I/flutter (11332): got dB update of file_dbLevel_enable -> 41.09263439246845
I/flutter (11332): 2020-03-04T15:24:35.112165
I/flutter (11332): STOP!!!
I/flutter (11332): stopRecorder: /data/user/0/com.dooboolab.fluttersoundexample/cache/file_dbLevel_enable.aac
Tested environment (Emulator? Real Device?)
- Android API 29 (Emulator)
Steps to reproduce the behavior
-
l.29 Declare two instances with
FlutterSound
member.- One of them is set to
flutterSound.setDbLevelEnabled(false)
, another isflutterSound.setDbLevelEnabled(true)
.
- One of them is set to
-
l.39 Execute
flutterSound.startRecorder
against both instance.- The order of execution is ‘
setDbLevelEnabled(false)
one’ -> ‘setDbLevelEnabled(true)
one’ .
- The order of execution is ‘
-
Result of two
onRecorderDbPeakChanged
callback are shown. -
l.57 Call
flutterSound.stopRecorder()
of the dBLevel Disabled instance. -
flutterSound.stopRecorder()
of the dBLevel Enabled instance is called.- The audio recorder in
FlutterSound
is overwritten?
- The audio recorder in
-
Exception has occurred due to _recorderSubscription of the dBLevel Enabled instance called against null recorder.
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart' show DateFormat;
import 'package:intl/date_symbol_data_local.dart';
import 'dart:async';
import 'package:flutter_sound/flutter_sound.dart';
import 'package:path_provider/path_provider.dart' show getTemporaryDirectory;
void main() async {
runApp(new MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
home: new MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key}) : super(key: key);
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
var recorder_dbLevel_disable = AudioRecorder(isEnableDbPeak: false); //iInstance DbLevel Disabled
var recorder_dbLevel_enable = AudioRecorder(isEnableDbPeak: true); //Instance DbLevel Enabled
@override
void initState() {
// TODO: implement initState
super.initState();
recorder_dbLevel_disable.startRecorder(fileName: "file_dbLevel_disable"); //Start recording from DbLevel Disabled instance
recorder_dbLevel_enable.startRecorder(fileName: "file_dbLevel_enable");
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('App Name'),
),
floatingActionButton: new FloatingActionButton(
child: new Icon(Icons.add_circle), onPressed: fabPressed),
);
}
void fabPressed() {
print("STOP!!!");
recorder_dbLevel_disable.stopRecorder();
}
}
class AudioRecorder {
StreamSubscription _dbPeakSubscription;
StreamSubscription _recorderSubscription;
FlutterSound flutterSound;
t_CODEC _codec = t_CODEC.CODEC_AAC;
AudioRecorder({bool isEnableDbPeak}) {
flutterSound = new FlutterSound();
flutterSound.setDbPeakLevelUpdate(1.0);
flutterSound.setDbLevelEnabled(isEnableDbPeak);
flutterSound.setSubscriptionDuration(1.0);
initializeDateFormatting();
}
void startRecorder({String fileName}) async {
try {
Directory tempDir = await getTemporaryDirectory();
String path = await flutterSound.startRecorder(
uri: '${tempDir.path}/' + fileName + '.aac',
codec: _codec,
);
print('startRecorder: $path');
_dbPeakSubscription =
flutterSound.onRecorderDbPeakChanged.listen((value) {
print("\ngot dB update of "+ fileName +" -> $value");
print("\t" + DateTime.now().toIso8601String());
});
_recorderSubscription = flutterSound.onRecorderStateChanged.listen((e) {
DateTime date = new DateTime.fromMillisecondsSinceEpoch(
e.currentPosition.toInt(),
isUtc: true);
String txt = DateFormat('mm:ss:SS', 'en_GB').format(date);
//print(fileName + ":" + txt);
});
} catch (err) {
print('startRecorder error: $err');
}
}
void stopRecorder() async {
try {
String result = await flutterSound.stopRecorder();
print('stopRecorder: $result');
if (_dbPeakSubscription != null) {
_dbPeakSubscription.cancel();
_dbPeakSubscription = null;
}
if ( _recorderSubscription != null ) {
_recorderSubscription.cancel ();
_recorderSubscription = null;
}
} catch (err) {
print('stopRecorder error: $err');
}
}
}
It seems that onRecorderDbPeakChanged
is excused against all FlutterSound
instances, because of _dbPeakController
is static. I avoid this problem by changing _dbPeakController
to non-static (I’m not sure this solution is safe or not… ). However I have not resolved ‘recorder overwritten problem’ yet.
Is there any reason FlutterSound
does not support the multiple audio recording?
Issue Analytics
- State:
- Created 4 years ago
- Reactions:1
- Comments:5
Top GitHub Comments
PR #257 is a major re-design of flutter_sound architecture. flutter_sound module is now split into :
Complete backward compatibility is provided by two deprecated modules :
@kiha-la : This PR is still in beta-version, and is still not merged in Flutter-Sound Master branch. In the meantime, it will be great if you can test it.
The new flutter_sound version has two different modules:
flutter_sound
with some improvments like some tools to control the Audio-focusFlauto
, wich adds @salvatore373 improvements .Those two modules are completely separated. This has two benefits:
flutter_sound
module is totally backward compatibleMy project would be to split again the legacy
flutter_sound
module into two different modules :For having backward compatibility, the
FlutterSoundPlayer
module will be called simplyFlutterSound
and will inherit fromflutterSoundRecorder
. But new developer will be encouraged to use theFlutterSoundRecorder
module for recording.Then, we will have three modules :
Flauto
(which inherit from `FlutterSoundPlayer)FlutterSoundPlayer
(which inherit fromFlutterSoundRecorder
for backward compatibility)FlutterSoundRecorder
Then, I think it will be easier to address #232 (which has been closed by its creator, but for me this issue is still valid and interesting).