Skip to content

Commit d74908f

Browse files
feat: ✨ Add a method to pause all players at once (#372)
1 parent d03efd7 commit d74908f

File tree

13 files changed

+157
-74
lines changed

13 files changed

+157
-74
lines changed

CHANGELOG.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1-
## 1.2.1 (Unreleased)
1+
## 1.3.0
22

33
- Fixed [#386](https://github.com/SimformSolutionsPvtLtd/audio_waveforms/pull/386) - On permission denied isRecording flag changed
44
- Fixed [#384](https://github.com/SimformSolutionsPvtLtd/audio_waveforms/issues/384) - Provide a callback of drag,tap,start and end details on user gesture
55
- Fixed [#309](https://github.com/SimformSolutionsPvtLtd/audio_waveforms/issues/309) - Added support for Liner PCM codec in iOS
66
- Fixed [#291](https://github.com/SimformSolutionsPvtLtd/audio_waveforms/issues/291) - Codec issue while recording audio on android
7-
- Fixed wrong codec selection on the platform side on both Android and iOS.
7+
- Fixed [#391](https://github.com/SimformSolutionsPvtLtd/audio_waveforms/pull/391) - Wrong codec selection on the platform side on Android
8+
- Fixed [#389](https://github.com/SimformSolutionsPvtLtd/audio_waveforms/pull/389) - Wrong codec selection on the platform side on iOS
9+
- Fixed [#325](https://github.com/SimformSolutionsPvtLtd/audio_waveforms/issues/325) - Added feature to pause all player controller at once.
10+
- Fixed [#373](https://github.com/SimformSolutionsPvtLtd/audio_waveforms/issues/373) - Getting error on dispose
811

912
## 1.2.0
1013

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,13 @@ playerController.release();
357357
playerController.stopAllPlayer();
358358
```
359359
There could be any number of players but you can just call this function from any **one** player and it will stop all the players.
360+
361+
#### Pausing players all at once
362+
```dart
363+
playerController.pauseAllPlayers();
364+
```
365+
This function works similar to stopAllPlayer but just pauses all players.
366+
360367
#### Disposing the controller
361368
```dart
362369
playerController.dispose();

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

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -129,26 +129,19 @@ class AudioPlayer(
129129
}
130130
}
131131

132-
fun stop(result: MethodChannel.Result) {
132+
fun stop() {
133133
stopListening()
134134
if (playerListener != null) {
135135
player?.removeListener(playerListener!!)
136136
}
137137
isPlayerPrepared = false
138138
player?.stop()
139-
result.success(true)
140139
}
141140

142141

143-
fun pause(result: MethodChannel.Result) {
144-
try {
145-
stopListening()
146-
player?.pause()
147-
result.success(true)
148-
} catch (e: Exception) {
149-
result.error(Constants.LOG_TAG, "Failed to pause the player", e.toString())
150-
}
151-
142+
fun pause() {
143+
stopListening()
144+
player?.pause()
152145
}
153146

154147
fun release(result: MethodChannel.Result) {

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

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import androidx.core.app.ActivityCompat
1313
import io.flutter.plugin.common.MethodChannel
1414
import io.flutter.plugin.common.PluginRegistry
1515
import java.io.IOException
16-
import java.lang.IllegalStateException
1716
import kotlin.math.log10
1817

1918
private const val LOG_TAG = "AudioWaveforms"
@@ -62,7 +61,7 @@ class AudioRecorder : PluginRegistry.RequestPermissionsResultListener {
6261

6362
fun stopRecording(result: MethodChannel.Result, recorder: MediaRecorder?, path: String) {
6463
try {
65-
val hashMap : HashMap<String,Any?> = HashMap()
64+
val hashMap: HashMap<String, Any?> = HashMap()
6665
try {
6766
recorder?.stop()
6867

@@ -132,9 +131,9 @@ class AudioRecorder : PluginRegistry.RequestPermissionsResultListener {
132131
}
133132

134133
override fun onRequestPermissionsResult(
135-
requestCode: Int,
136-
permissions: Array<out String>,
137-
grantResults: IntArray
134+
requestCode: Int,
135+
permissions: Array<out String>,
136+
grantResults: IntArray
138137
): Boolean {
139138
return if (requestCode == RECORD_AUDIO_REQUEST_CODE) {
140139
successCallback?.onSuccess(grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)
@@ -146,7 +145,7 @@ class AudioRecorder : PluginRegistry.RequestPermissionsResultListener {
146145

147146
private fun isPermissionGranted(activity: Activity?): Boolean {
148147
val result =
149-
ActivityCompat.checkSelfPermission(activity!!, permissions[0])
148+
ActivityCompat.checkSelfPermission(activity!!, permissions[0])
150149
return result == PackageManager.PERMISSION_GRANTED
151150
}
152151

@@ -155,8 +154,8 @@ class AudioRecorder : PluginRegistry.RequestPermissionsResultListener {
155154
if (!isPermissionGranted(activity)) {
156155
activity?.let {
157156
ActivityCompat.requestPermissions(
158-
it, permissions,
159-
RECORD_AUDIO_REQUEST_CODE
157+
it, permissions,
158+
RECORD_AUDIO_REQUEST_CODE
160159
)
161160
}
162161
} else {
@@ -179,6 +178,7 @@ class AudioRecorder : PluginRegistry.RequestPermissionsResultListener {
179178
MediaRecorder.AudioEncoder.AAC
180179
}
181180
}
181+
182182
Constants.vorbis -> return MediaRecorder.AudioEncoder.VORBIS
183183

184184
else -> return MediaRecorder.AudioEncoder.AAC
@@ -202,6 +202,7 @@ class AudioRecorder : PluginRegistry.RequestPermissionsResultListener {
202202
Constants.amr_nb -> return MediaRecorder.OutputFormat.AMR_NB
203203
Constants.webm ->
204204
return MediaRecorder.OutputFormat.WEBM
205+
205206
Constants.mpeg_2_ts -> {
206207
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
207208
MediaRecorder.OutputFormat.MPEG_2_TS
@@ -210,6 +211,7 @@ class AudioRecorder : PluginRegistry.RequestPermissionsResultListener {
210211
MediaRecorder.OutputFormat.MPEG_4
211212
}
212213
}
214+
213215
Constants.aac_adts -> return MediaRecorder.OutputFormat.AAC_ADTS
214216
else -> return MediaRecorder.OutputFormat.MPEG_4
215217
}

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

Lines changed: 80 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import android.os.Build
77
import android.util.Log
88
import androidx.annotation.NonNull
99
import androidx.annotation.RequiresApi
10-
1110
import io.flutter.embedding.engine.plugins.FlutterPlugin
1211
import io.flutter.embedding.engine.plugins.activity.ActivityAware
1312
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
@@ -18,7 +17,8 @@ import io.flutter.plugin.common.MethodChannel.Result
1817
import java.io.File
1918
import java.io.IOException
2019
import java.text.SimpleDateFormat
21-
import java.util.*
20+
import java.util.Date
21+
import java.util.Locale
2222

2323

2424
/** AudioWaveformsPlugin */
@@ -55,13 +55,17 @@ class AudioWaveformsPlugin : FlutterPlugin, MethodCallHandler, ActivityAware {
5555
recorderSettings
5656
)
5757
} else {
58-
result.error(Constants.LOG_TAG, "Failed to initialise Recorder", "Invalid Arguments")
58+
result.error(
59+
Constants.LOG_TAG,
60+
"Failed to initialise Recorder",
61+
"Invalid Arguments"
62+
)
5963
}
6064
}
6165

6266
Constants.startRecording -> {
6367
val useLegacyNormalization =
64-
(call.argument(Constants.useLegacyNormalization) as Boolean?) ?: false
68+
(call.argument(Constants.useLegacyNormalization) as Boolean?) ?: false
6569
audioRecorder.startRecorder(result, recorder, useLegacyNormalization)
6670
}
6771

@@ -77,7 +81,12 @@ class AudioWaveformsPlugin : FlutterPlugin, MethodCallHandler, ActivityAware {
7781
Constants.pauseRecording -> audioRecorder.pauseRecording(result, recorder)
7882
Constants.resumeRecording -> audioRecorder.resumeRecording(result, recorder)
7983
Constants.getDecibel -> audioRecorder.getDecibel(result, recorder)
80-
Constants.checkPermission -> audioRecorder.checkPermission(result, activity, result::success)
84+
Constants.checkPermission -> audioRecorder.checkPermission(
85+
result,
86+
activity,
87+
result::success
88+
)
89+
8190
Constants.preparePlayer -> {
8291
val audioPath = call.argument(Constants.path) as String?
8392
val volume = call.argument(Constants.volume) as Double?
@@ -109,7 +118,12 @@ class AudioWaveformsPlugin : FlutterPlugin, MethodCallHandler, ActivityAware {
109118
Constants.stopPlayer -> {
110119
val key = call.argument(Constants.playerKey) as String?
111120
if (key != null) {
112-
audioPlayers[key]?.stop(result)
121+
try {
122+
audioPlayers[key]?.stop()
123+
result.success(true)
124+
} catch (e: Exception) {
125+
result.error(Constants.LOG_TAG, "Failed to stop player", e.message)
126+
}
113127
} else {
114128
result.error(Constants.LOG_TAG, "Player key can't be null", "")
115129
}
@@ -118,7 +132,12 @@ class AudioWaveformsPlugin : FlutterPlugin, MethodCallHandler, ActivityAware {
118132
Constants.pausePlayer -> {
119133
val key = call.argument(Constants.playerKey) as String?
120134
if (key != null) {
121-
audioPlayers[key]?.pause(result)
135+
try {
136+
audioPlayers[key]?.pause()
137+
result.success(true)
138+
} catch (e: Exception) {
139+
result.error(Constants.LOG_TAG, "Failed to pause player", e.message)
140+
}
122141
} else {
123142
result.error(Constants.LOG_TAG, "Player key can't be null", "")
124143
}
@@ -140,8 +159,8 @@ class AudioWaveformsPlugin : FlutterPlugin, MethodCallHandler, ActivityAware {
140159
}
141160
} else {
142161
Log.e(
143-
Constants.LOG_TAG,
144-
"Minimum android O is required for seekTo function to works"
162+
Constants.LOG_TAG,
163+
"Minimum android O is required for seekTo function to works"
145164
)
146165
}
147166
}
@@ -168,7 +187,7 @@ class AudioWaveformsPlugin : FlutterPlugin, MethodCallHandler, ActivityAware {
168187

169188
Constants.getDuration -> {
170189
val type =
171-
if ((call.argument(Constants.durationType) as Int?) == 0) DurationType.Current else DurationType.Max
190+
if ((call.argument(Constants.durationType) as Int?) == 0) DurationType.Current else DurationType.Max
172191
val key = call.argument(Constants.playerKey) as String?
173192
if (key != null) {
174193
audioPlayers[key]?.getDuration(result, type)
@@ -183,22 +202,18 @@ class AudioWaveformsPlugin : FlutterPlugin, MethodCallHandler, ActivityAware {
183202
val noOfSample = call.argument(Constants.noOfSamples) as Int?
184203
if (key != null) {
185204
createOrUpdateExtractor(
186-
playerKey = key,
187-
result = result,
188-
path = path,
189-
noOfSamples = noOfSample ?: 100,
205+
playerKey = key,
206+
result = result,
207+
path = path,
208+
noOfSamples = noOfSample ?: 100,
190209
)
191210
} else {
192211
result.error(Constants.LOG_TAG, "Player key can't be null", "")
193212
}
194213
}
195214

196215
Constants.stopAllPlayers -> {
197-
for ((key, _) in audioPlayers) {
198-
audioPlayers[key]?.stop(result)
199-
audioPlayers[key] = null
200-
}
201-
result.success(true)
216+
stopAllPlayer(result)
202217
}
203218

204219
Constants.finishMode -> {
@@ -209,6 +224,10 @@ class AudioWaveformsPlugin : FlutterPlugin, MethodCallHandler, ActivityAware {
209224
}
210225
}
211226

227+
Constants.pauseAllPlayers -> {
228+
pauseAllPlayer(result)
229+
}
230+
212231
else -> result.notImplemented()
213232
}
214233
}
@@ -251,40 +270,40 @@ class AudioWaveformsPlugin : FlutterPlugin, MethodCallHandler, ActivityAware {
251270
private fun initPlayer(playerKey: String) {
252271
if (audioPlayers[playerKey] == null) {
253272
val newPlayer = AudioPlayer(
254-
context = applicationContext,
255-
channel = channel,
256-
playerKey = playerKey,
273+
context = applicationContext,
274+
channel = channel,
275+
playerKey = playerKey,
257276
)
258277
audioPlayers[playerKey] = newPlayer
259278
}
260279
return
261280
}
262281

263282
private fun createOrUpdateExtractor(
264-
playerKey: String,
265-
noOfSamples: Int,
266-
path: String?,
267-
result: Result,
283+
playerKey: String,
284+
noOfSamples: Int,
285+
path: String?,
286+
result: Result,
268287
) {
269288
if (path == null) {
270289
result.error(Constants.LOG_TAG, "Path can't be null", "")
271290
return
272291
}
273292
extractors[playerKey] = WaveformExtractor(
274-
context = applicationContext,
275-
methodChannel = channel,
276-
expectedPoints = noOfSamples,
277-
key = playerKey,
278-
path = path,
279-
result = result,
280-
extractorCallBack = object : ExtractorCallBack {
281-
override fun onProgress(value: Float) {
282-
if (value == 1.0F) {
283-
result.success(extractors[playerKey]?.sampleData)
284-
}
293+
context = applicationContext,
294+
methodChannel = channel,
295+
expectedPoints = noOfSamples,
296+
key = playerKey,
297+
path = path,
298+
result = result,
299+
extractorCallBack = object : ExtractorCallBack {
300+
override fun onProgress(value: Float) {
301+
if (value == 1.0F) {
302+
result.success(extractors[playerKey]?.sampleData)
285303
}
286-
287304
}
305+
306+
}
288307
)
289308
extractors[playerKey]?.startDecode()
290309
extractors[playerKey]?.stop()
@@ -319,4 +338,27 @@ class AudioWaveformsPlugin : FlutterPlugin, MethodCallHandler, ActivityAware {
319338
pluginBinding!!.removeRequestPermissionsResultListener(this.audioRecorder)
320339
}
321340
}
341+
342+
private fun stopAllPlayer(result: MethodChannel.Result) {
343+
try {
344+
for ((key, _) in audioPlayers) {
345+
audioPlayers[key]?.stop()
346+
audioPlayers[key] = null
347+
}
348+
result.success(true)
349+
} catch (e: Exception) {
350+
result.error(Constants.LOG_TAG, "Failed to stop players", e.message)
351+
}
352+
}
353+
354+
private fun pauseAllPlayer(result: MethodChannel.Result) {
355+
try {
356+
for ((key, _) in audioPlayers) {
357+
audioPlayers[key]?.pause()
358+
}
359+
result.success(true)
360+
} catch (e: Exception) {
361+
result.error(Constants.LOG_TAG, "Failed to pause players", e.message)
362+
}
363+
}
322364
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ object Constants {
6969

7070
const val resultFilePath = "resultFilePath"
7171
const val resultDuration = "resultDuration"
72+
const val pauseAllPlayers = "pauseAllPlayers"
7273
}
7374

7475
enum class FinishMode(val value: Int) {

ios/Classes/AudioPlayer.swift

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,17 +91,15 @@ class AudioPlayer: NSObject, AVAudioPlayerDelegate {
9191
}
9292

9393

94-
func pausePlayer(result: @escaping FlutterResult) {
94+
func pausePlayer() {
9595
stopListening()
9696
player?.pause()
97-
result(true)
9897
}
9998

100-
func stopPlayer(result: @escaping FlutterResult) {
99+
func stopPlayer() {
101100
stopListening()
102101
player?.stop()
103102
timer = nil
104-
result(true)
105103
}
106104

107105
func release(result: @escaping FlutterResult) {

0 commit comments

Comments
 (0)