Skip to content

Commit 8e276f9

Browse files
🔨 Fixed player button not showing up and made bitrate nullable and update default recording extension to m4a (#140)
Co-authored-by: ujas-m-simformsolutions <ujasthakkar54@gmail.com>
1 parent 685cd80 commit 8e276f9

File tree

8 files changed

+60
-35
lines changed

8 files changed

+60
-35
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
- **BREAKING**: Replaced `normalizationFactor` with `scaleFactor`and with this fixed [#43](https://github.com/SimformSolutionsPvtLtd/audio_waveforms/issues/43)
1414
- Updated default values for bitRate and sampleRate
1515
- Encoders, sample rate and bit rate can now Directly be set from `record` function.
16+
- Bitrate is now nullable and default audio extension is now `m4a`.
1617
- Updated example app
1718

1819
## 0.1.5+1

android/src/main/kotlin/com/simform/audio_waveforms/AudioRecorder.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,22 +22,23 @@ class AudioRecorder : PluginRegistry.RequestPermissionsResultListener {
2222
result.success(recorder?.maxAmplitude?.toDouble() ?: 0.0)
2323
}
2424

25-
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
2625
fun initRecorder(
2726
path: String,
2827
result: MethodChannel.Result,
2928
recorder: MediaRecorder?,
3029
encoder: Int,
3130
outputFormat: Int,
3231
sampleRate: Int,
33-
bitRate: Int
32+
bitRate: Int?
3433
) {
3534
recorder?.apply {
3635
setAudioSource(MediaRecorder.AudioSource.MIC)
3736
setOutputFormat(getOutputFormat(outputFormat))
3837
setAudioEncoder(getEncoder(encoder))
3938
setAudioSamplingRate(sampleRate)
40-
setAudioEncodingBitRate(bitRate)
39+
if (bitRate != null) {
40+
setAudioEncodingBitRate(bitRate)
41+
}
4142
setOutputFile(path)
4243
try {
4344
recorder.prepare()

android/src/main/kotlin/com/simform/audio_waveforms/AudioWaveformsPlugin.kt

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ class AudioWaveformsPlugin : FlutterPlugin, MethodCallHandler, ActivityAware {
3030
private var path: String? = null
3131
private var encoder: Int = 0
3232
private var outputFormat: Int = 0
33-
private var sampleRate: Int = 16000
34-
private var bitRate: Int = 64000
33+
private var sampleRate: Int = 44100
34+
private var bitRate: Int? = null
3535
private lateinit var applicationContext: Context
3636

3737
//Todo: bitrate
@@ -51,8 +51,8 @@ class AudioWaveformsPlugin : FlutterPlugin, MethodCallHandler, ActivityAware {
5151
path = call.argument(Constants.path) as String?
5252
encoder = (call.argument(Constants.encoder) as Int?) ?: 0
5353
outputFormat = (call.argument(Constants.outputFormat) as Int?) ?: 0
54-
sampleRate = (call.argument(Constants.sampleRate) as Int?) ?: 16000
55-
bitRate = (call.argument(Constants.bitRate) as Int?) ?: 64000
54+
sampleRate = (call.argument(Constants.sampleRate) as Int?) ?: 44100
55+
bitRate = (call.argument(Constants.bitRate) as Int?)
5656
checkPathAndInitialiseRecorder(result, encoder, outputFormat, sampleRate, bitRate)
5757
}
5858
Constants.startRecording -> audioRecorder.startRecorder(result, recorder)
@@ -160,13 +160,12 @@ class AudioWaveformsPlugin : FlutterPlugin, MethodCallHandler, ActivityAware {
160160
}
161161
}
162162

163-
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
164163
private fun checkPathAndInitialiseRecorder(
165164
result: Result,
166165
encoder: Int,
167166
outputFormat: Int,
168167
sampleRate: Int,
169-
bitRate: Int
168+
bitRate: Int?
170169
) {
171170
try {
172171
recorder = MediaRecorder()
@@ -179,7 +178,7 @@ class AudioWaveformsPlugin : FlutterPlugin, MethodCallHandler, ActivityAware {
179178
val dateTimeInstance = SimpleDateFormat(Constants.fileNameFormat, Locale.US)
180179
val currentDate = dateTimeInstance.format(Date())
181180
try {
182-
outputFile = File.createTempFile(currentDate, ".aac", outputDir)
181+
outputFile = File.createTempFile(currentDate, ".m4a", outputDir)
183182
path = outputFile.path
184183
audioRecorder.initRecorder(
185184
path!!,

example/lib/chat_bubble.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ class _WaveBubbleState extends State<WaveBubble> {
150150
child: Row(
151151
mainAxisSize: MainAxisSize.min,
152152
children: [
153-
if (controller.playerState.isStopped)
153+
if (!controller.playerState.isStopped)
154154
IconButton(
155155
onPressed: () async {
156156
controller.playerState.isPlaying

example/lib/main.dart

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class _HomeState extends State<Home> with WidgetsBindingObserver {
4747

4848
void _getDir() async {
4949
appDirectory = await getApplicationDocumentsDirectory();
50-
path = "${appDirectory.path}/recording.mp3";
50+
path = "${appDirectory.path}/recording.m4a";
5151
isLoading = false;
5252
setState(() {});
5353
}
@@ -57,8 +57,7 @@ class _HomeState extends State<Home> with WidgetsBindingObserver {
5757
..androidEncoder = AndroidEncoder.aac
5858
..androidOutputFormat = AndroidOutputFormat.mpeg4
5959
..iosEncoder = IosEncoder.kAudioFormatMPEG4AAC
60-
..sampleRate = 44100
61-
..bitRate = 48000;
60+
..sampleRate = 44100;
6261
}
6362

6463
void _pickFile() async {
@@ -114,7 +113,8 @@ class _HomeState extends State<Home> with WidgetsBindingObserver {
114113
index: index + 1,
115114
isSender: index.isOdd,
116115
width: MediaQuery.of(context).size.width / 2,
117-
isLastWidget: !isRecordingCompleted || musicFile == null,
116+
isLastWidget:
117+
!isRecordingCompleted || musicFile == null,
118118
appDirectory: appDirectory,
119119
);
120120
},
@@ -212,21 +212,27 @@ class _HomeState extends State<Home> with WidgetsBindingObserver {
212212
}
213213

214214
void _startOrStopRecording() async {
215-
if (isRecording) {
216-
recorderController.reset();
217-
final path = await recorderController.stop(false);
218-
219-
if (path != null) {
220-
isRecordingCompleted = true;
221-
debugPrint("Recorded file size: ${File(path).lengthSync()}");
222-
debugPrint(path);
215+
try {
216+
if (isRecording) {
217+
recorderController.reset();
218+
219+
final path = await recorderController.stop(false);
220+
221+
if (path != null) {
222+
isRecordingCompleted = true;
223+
debugPrint("Recorded file size: ${File(path).lengthSync()}");
224+
debugPrint(path);
225+
}
226+
} else {
227+
await recorderController.record();
223228
}
224-
} else {
225-
await recorderController.record(path: path);
229+
} catch (e) {
230+
debugPrint(e.toString());
231+
} finally {
232+
setState(() {
233+
isRecording = !isRecording;
234+
});
226235
}
227-
setState(() {
228-
isRecording = !isRecording;
229-
});
230236
}
231237

232238
void _refreshWave() {

ios/Classes/AudioRecorder.swift

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,26 @@ public class AudioRecorder: NSObject, AVAudioRecorderDelegate{
99

1010
public func startRecording(_ result: @escaping FlutterResult,_ path: String?,_ encoder : Int?,_ sampleRate : Int?,_ bitRate : Int?,_ fileNameFormat: String){
1111
let settings = [
12-
AVEncoderBitRateKey: bitRate ?? 48000,
1312
AVFormatIDKey: getEncoder(encoder ?? 0),
1413
AVSampleRateKey: sampleRate ?? 44100,
1514
AVNumberOfChannelsKey: 1,
1615
AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue
1716
]
17+
let settingsWithBitrate = [
18+
AVEncoderBitRateKey: bitRate,
19+
AVFormatIDKey: getEncoder(encoder ?? 0),
20+
AVSampleRateKey: sampleRate ?? 44100,
21+
AVNumberOfChannelsKey: 1,
22+
AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue
23+
]
24+
1825
let options: AVAudioSession.CategoryOptions = [.defaultToSpeaker, .allowBluetooth]
1926
if (path == nil) {
2027
let directory = NSTemporaryDirectory()
2128
let date = Date()
2229
let dateFormatter = DateFormatter()
2330
dateFormatter.dateFormat = fileNameFormat
24-
let fileName = dateFormatter.string(from: date) + ".aac"
31+
let fileName = dateFormatter.string(from: date) + ".m4a"
2532

2633
self.path = NSURL.fileURL(withPathComponents: [directory, fileName])?.absoluteString
2734
} else {
@@ -34,7 +41,7 @@ public class AudioRecorder: NSObject, AVAudioRecorderDelegate{
3441
try AVAudioSession.sharedInstance().setActive(true)
3542

3643
let url = URL(string: self.path!) ?? URL(fileURLWithPath: self.path!)
37-
audioRecorder = try AVAudioRecorder(url: url, settings: settings)
44+
audioRecorder = try AVAudioRecorder(url: url, settings: bitRate != nil ? settingsWithBitrate as [String : Any] : settings as [String : Any])
3845
audioRecorder?.delegate = self
3946
audioRecorder?.isMeteringEnabled = true
4047
audioRecorder?.record()

lib/src/base/audio_waveforms_interface.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class AudioWaveformsInterface {
1212
Future<bool> record({
1313
required int audioFormat,
1414
required int sampleRate,
15-
required int bitRate,
15+
int? bitRate,
1616
String? path,
1717
}) async {
1818
final isRecording = await _methodChannel.invokeMethod(
@@ -35,7 +35,7 @@ class AudioWaveformsInterface {
3535
required int encoder,
3636
required int outputFormat,
3737
required int sampleRate,
38-
required int bitRate,
38+
int? bitRate,
3939
}) async {
4040
final initialized = await _methodChannel.invokeMethod(
4141
Constants.initRecorder,

lib/src/controllers/recorder_controller.dart

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,14 @@ class RecorderController extends ChangeNotifier {
2121

2222
int sampleRate = 44100;
2323

24-
int bitRate = 48000;
24+
int? bitRate;
2525

2626
/// Current maximum peak power for ios and peak amplitude android.
2727
double _maxPeak = Platform.isIOS ? 1 : 32786.0;
2828

29+
/// Current min value.
30+
double _currentMin = 0;
31+
2932
/// Current list of scaled waves. For IOS, this list contains normalised
3033
/// peak power and for Android, this list contains normalised peak
3134
/// amplitude.
@@ -279,7 +282,15 @@ class RecorderController extends ChangeNotifier {
279282
void _normalise(double peak) {
280283
final absDb = peak.abs();
281284
_maxPeak = max(absDb, _maxPeak);
282-
final scaledWave = (absDb / _maxPeak);
285+
286+
// calculates min value
287+
_currentMin = _waveData.fold(
288+
0,
289+
(previousValue, element) =>
290+
element < previousValue ? element : previousValue,
291+
);
292+
293+
final scaledWave = (absDb - _currentMin) / (_maxPeak - _currentMin);
283294
_waveData.add(scaledWave);
284295
notifyListeners();
285296
}

0 commit comments

Comments
 (0)