diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a1852ae..4bbaa599 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ - Fixed [#386](https://github.com/SimformSolutionsPvtLtd/audio_waveforms/pull/386) - On permission denied isRecording flag changed - Fixed [#384](https://github.com/SimformSolutionsPvtLtd/audio_waveforms/issues/384) - Provide a callback of drag,tap,start and end details on user gesture - Fixed [#309](https://github.com/SimformSolutionsPvtLtd/audio_waveforms/issues/309) - Added support for Liner PCM codec in iOS +- Fixes [#325](https://github.com/SimformSolutionsPvtLtd/audio_waveforms/issues/325) - Added feature to pause all player controller at once. ## 1.2.0 diff --git a/README.md b/README.md index 1d671e8f..2a309b9e 100644 --- a/README.md +++ b/README.md @@ -357,6 +357,13 @@ playerController.release(); playerController.stopAllPlayer(); ``` 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. + +#### Pausing players all at once +```dart +playerController.pauseAllPlayers(); +``` +There could be any number of players but you can just call this function from any **one** player and it will pause all the players. + #### Disposing the controller ```dart playerController.dispose(); diff --git a/android/src/main/kotlin/com/simform/audio_waveforms/AudioPlayer.kt b/android/src/main/kotlin/com/simform/audio_waveforms/AudioPlayer.kt index 3b937cb7..2f5f76d5 100644 --- a/android/src/main/kotlin/com/simform/audio_waveforms/AudioPlayer.kt +++ b/android/src/main/kotlin/com/simform/audio_waveforms/AudioPlayer.kt @@ -129,26 +129,19 @@ class AudioPlayer( } } - fun stop(result: MethodChannel.Result) { + fun stop() { stopListening() if (playerListener != null) { player?.removeListener(playerListener!!) } isPlayerPrepared = false player?.stop() - result.success(true) } - fun pause(result: MethodChannel.Result) { - try { - stopListening() - player?.pause() - result.success(true) - } catch (e: Exception) { - result.error(Constants.LOG_TAG, "Failed to pause the player", e.toString()) - } - + fun pause() { + stopListening() + player?.pause() } fun release(result: MethodChannel.Result) { diff --git a/android/src/main/kotlin/com/simform/audio_waveforms/AudioWaveformsPlugin.kt b/android/src/main/kotlin/com/simform/audio_waveforms/AudioWaveformsPlugin.kt index c3811881..93f63ea2 100644 --- a/android/src/main/kotlin/com/simform/audio_waveforms/AudioWaveformsPlugin.kt +++ b/android/src/main/kotlin/com/simform/audio_waveforms/AudioWaveformsPlugin.kt @@ -102,7 +102,8 @@ class AudioWaveformsPlugin : FlutterPlugin, MethodCallHandler, ActivityAware { Constants.stopPlayer -> { val key = call.argument(Constants.playerKey) as String? if (key != null) { - audioPlayers[key]?.stop(result) + audioPlayers[key]?.stop() + result.success(true) } else { result.error(Constants.LOG_TAG, "Player key can't be null", "") } @@ -111,7 +112,8 @@ class AudioWaveformsPlugin : FlutterPlugin, MethodCallHandler, ActivityAware { Constants.pausePlayer -> { val key = call.argument(Constants.playerKey) as String? if (key != null) { - audioPlayers[key]?.pause(result) + audioPlayers[key]?.pause() + result.success(true) } else { result.error(Constants.LOG_TAG, "Player key can't be null", "") } @@ -188,7 +190,7 @@ class AudioWaveformsPlugin : FlutterPlugin, MethodCallHandler, ActivityAware { Constants.stopAllPlayers -> { for ((key, _) in audioPlayers) { - audioPlayers[key]?.stop(result) + audioPlayers[key]?.stop() audioPlayers[key] = null } result.success(true) @@ -202,6 +204,13 @@ class AudioWaveformsPlugin : FlutterPlugin, MethodCallHandler, ActivityAware { } } + Constants.pauseAllPlayers -> { + for ((key, _) in audioPlayers) { + audioPlayers[key]?.pause() + } + result.success(true) + } + else -> result.notImplemented() } } diff --git a/android/src/main/kotlin/com/simform/audio_waveforms/Utils.kt b/android/src/main/kotlin/com/simform/audio_waveforms/Utils.kt index 63977db8..d3d02371 100644 --- a/android/src/main/kotlin/com/simform/audio_waveforms/Utils.kt +++ b/android/src/main/kotlin/com/simform/audio_waveforms/Utils.kt @@ -69,6 +69,7 @@ object Constants { const val resultFilePath = "resultFilePath" const val resultDuration = "resultDuration" + const val pauseAllPlayers = "pauseAllPlayers" } enum class FinishMode(val value: Int) { diff --git a/example/lib/chat_bubble.dart b/example/lib/chat_bubble.dart index 1f20e4e7..6dfd13f1 100644 --- a/example/lib/chat_bubble.dart +++ b/example/lib/chat_bubble.dart @@ -152,7 +152,7 @@ class _WaveBubbleState extends State { IconButton( onPressed: () async { controller.playerState.isPlaying - ? await controller.pausePlayer() + ? await controller.stopAllPlayers() : await controller.startPlayer(); controller.setFinishMode(finishMode: FinishMode.loop); }, diff --git a/example/lib/main.dart b/example/lib/main.dart index fd1f3c95..79bcba79 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -52,12 +52,20 @@ class _HomeState extends State { setState(() {}); } + var recordAudioListener; void _initialiseControllers() { recorderController = RecorderController() ..androidEncoder = AndroidEncoder.aac ..androidOutputFormat = AndroidOutputFormat.mpeg4 ..iosEncoder = IosEncoder.kAudioFormatMPEG4AAC ..sampleRate = 44100; + + recordAudioListener = () { + var ab = recorderController.elapsedDuration.inSeconds ?? 0; + print('object-----> $ab'); + }; + + recorderController.addListener(recordAudioListener); } void _pickFile() async { @@ -214,14 +222,26 @@ class _HomeState extends State { try { if (isRecording) { recorderController.reset(); + await recorderController.pause(); + final audioFile = await recorderController.stop(); + final time = recorderController.recordedDuration.inSeconds; + recorderController.removeListener(recordAudioListener!); + + print('Duration ======> $audioFile $time'); - path = await recorderController.stop(false); + if (audioFile != null && (time ?? 0) > 0) { + print('object ---> Upload image'); + } + recorderController.dispose(); + + /* path = await recorderController.stop(false); if (path != null) { isRecordingCompleted = true; debugPrint(path); debugPrint("Recorded file size: ${File(path!).lengthSync()}"); - } + recorderController.dispose(); + }*/ } else { await recorderController.record(path: path); // Path is optional } diff --git a/ios/Classes/AudioPlayer.swift b/ios/Classes/AudioPlayer.swift index d9094b8c..f95b1938 100644 --- a/ios/Classes/AudioPlayer.swift +++ b/ios/Classes/AudioPlayer.swift @@ -91,17 +91,15 @@ class AudioPlayer: NSObject, AVAudioPlayerDelegate { } - func pausePlayer(result: @escaping FlutterResult) { + func pausePlayer() { stopListening() player?.pause() - result(true) } - func stopPlayer(result: @escaping FlutterResult) { + func stopPlayer() { stopListening() player?.stop() timer = nil - result(true) } func release(result: @escaping FlutterResult) { diff --git a/ios/Classes/SwiftAudioWaveformsPlugin.swift b/ios/Classes/SwiftAudioWaveformsPlugin.swift index 2b86ff2e..4b0ad386 100644 --- a/ios/Classes/SwiftAudioWaveformsPlugin.swift +++ b/ios/Classes/SwiftAudioWaveformsPlugin.swift @@ -79,7 +79,8 @@ public class SwiftAudioWaveformsPlugin: NSObject, FlutterPlugin { case Constants.pausePlayer: let key = args?[Constants.playerKey] as? String if(key != nil){ - audioPlayers[key!]?.pausePlayer(result: result) + audioPlayers[key!]?.pausePlayer() + result(true) } else { result(FlutterError(code: Constants.audioWaveforms, message: "Can not pause player", details: "Player key is null")) } @@ -87,7 +88,8 @@ public class SwiftAudioWaveformsPlugin: NSObject, FlutterPlugin { case Constants.stopPlayer: let key = args?[Constants.playerKey] as? String if(key != nil){ - audioPlayers[key!]?.stopPlayer(result: result) + audioPlayers[key!]?.stopPlayer() + result(true) } else { result(FlutterError(code: Constants.audioWaveforms, message: "Can not stop player", details: "Player key is null")) } @@ -136,8 +138,8 @@ public class SwiftAudioWaveformsPlugin: NSObject, FlutterPlugin { result(FlutterError(code: Constants.audioWaveforms, message: "Can not get duration", details: "Player key is null")) } case Constants.stopAllPlayers: - for (playerKey,_) in audioPlayers{ - audioPlayers[playerKey]?.stopPlayer(result: result) + for (playerKey,_) in audioPlayers { + audioPlayers[playerKey]?.stopPlayer() audioPlayers[playerKey] = nil } result(true) @@ -150,6 +152,12 @@ public class SwiftAudioWaveformsPlugin: NSObject, FlutterPlugin { } else { result(FlutterError(code: Constants.audioWaveforms, message: "Can not get waveform data", details: "Player key is null")) } + case Constants.pauseAllPlayers: + for(playerKey,_) in audioPlayers { + audioPlayers[playerKey]?.pausePlayer() + } + result(true) + break default: result(FlutterMethodNotImplemented) break diff --git a/ios/Classes/Utils.swift b/ios/Classes/Utils.swift index 96711f4d..f9c4e0b6 100644 --- a/ios/Classes/Utils.swift +++ b/ios/Classes/Utils.swift @@ -66,6 +66,7 @@ struct Constants { static let linearPCMBitDepth = "linearPCMBitDepth"; static let linearPCMIsBigEndian = "linearPCMIsBigEndian"; static let linearPCMIsFloat = "linearPCMIsFloat"; + static let pauseAllPlayers = "pauseAllPlayers" } diff --git a/lib/src/base/audio_waveforms_interface.dart b/lib/src/base/audio_waveforms_interface.dart index 7cccf049..e7d2b81e 100644 --- a/lib/src/base/audio_waveforms_interface.dart +++ b/lib/src/base/audio_waveforms_interface.dart @@ -209,6 +209,11 @@ class AudioWaveformsInterface { return result ?? false; } + Future pauseAllPlayers() async { + var result = await _methodChannel.invokeMethod(Constants.pauseAllPlayers); + return result ?? false; + } + Future setMethodCallHandler() async { _methodChannel.setMethodCallHandler((call) async { switch (call.method) { diff --git a/lib/src/base/constants.dart b/lib/src/base/constants.dart index 81785cbc..7405137d 100644 --- a/lib/src/base/constants.dart +++ b/lib/src/base/constants.dart @@ -39,6 +39,7 @@ class Constants { static const String current = "current"; static const String onCurrentDuration = "onCurrentDuration"; static const String stopAllPlayers = "stopAllPlayers"; + static const String pauseAllPlayers = "pauseAllPlayers"; static const String onDidFinishPlayingAudio = "onDidFinishPlayingAudio"; static const String extractWaveformData = "extractWaveformData"; static const String noOfSamples = "noOfSamples"; diff --git a/lib/src/controllers/player_controller.dart b/lib/src/controllers/player_controller.dart index 25a723e0..6276f3c3 100644 --- a/lib/src/controllers/player_controller.dart +++ b/lib/src/controllers/player_controller.dart @@ -318,10 +318,37 @@ class PlayerController extends ChangeNotifier { /// /// This method will close the stream and free resources taken by all /// players. This method will not dispose controller. - Future stopAllPlayers() async { + /// + /// Returns true if all player stopped otherwise return false. + Future stopAllPlayers() async { PlatformStreams.instance.dispose(); - await AudioWaveformsInterface.instance.stopAllPlayers(); + var isAllPlayersStopped = + await AudioWaveformsInterface.instance.stopAllPlayers(); + if (isAllPlayersStopped) { + PlatformStreams.instance.playerControllerFactory + .forEach((playKey, controller) { + controller._setPlayerState(PlayerState.stopped); + }); + } PlatformStreams.instance.playerControllerFactory.clear(); + return isAllPlayersStopped; + } + + /// This method is to pause all players at once. + /// + /// This method will only pause the players it will not release the resources. + /// + /// Returns true if all player paused otherwise return false. + Future pauseAllPlayers() async { + var isAllPlayersPaused = + await AudioWaveformsInterface.instance.pauseAllPlayers(); + if (isAllPlayersPaused) { + PlatformStreams.instance.playerControllerFactory + .forEach((playKey, controller) { + controller._setPlayerState(PlayerState.paused); + }); + } + return isAllPlayersPaused; } /// Sets [_shouldRefresh] flag with provided boolean parameter. diff --git a/pubspec.yaml b/pubspec.yaml index 56dde324..4a94cd72 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: audio_waveforms description: A Flutter package that allow you to generate waveform while recording audio or from audio file. -version: 1.2.0 +version: 1.2.1 homepage: https://github.com/SimformSolutionsPvtLtd/audio_waveforms issue_tracker: https://github.com/SimformSolutionsPvtLtd/audio_waveforms/issues