Skip to content

Commit 5773b49

Browse files
✨ Allow users to update reported duration for smoothening wave progress animation
1 parent 8869e23 commit 5773b49

File tree

12 files changed

+109
-13
lines changed

12 files changed

+109
-13
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
## 1.0.4 (Unreleased)
1+
## 1.0.4
22

33
- Fixed [#171](https://github.com/SimformSolutionsPvtLtd/audio_waveforms/issues/171) - Do not call `notifyListeners()` when disposed
4+
- Add `UpdateFrequency` to update reporting rate of current duration. Fixes [#118](https://github.com/SimformSolutionsPvtLtd/audio_waveforms/issues/118) & [#145](https://github.com/SimformSolutionsPvtLtd/audio_waveforms/issues/145)
45

56
## 1.0.3
67

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ import 'package:audio_waveforms/audio_waveforms.dart';
6262
```dart
6363
RecorderController controller = RecorderController(); // Initialise
6464
await controller.record(path: 'path'); // Record (path is optional)
65-
final hasPermission = await controller.checkPermission(); // Check mic permission (also called duration record)
65+
final hasPermission = await controller.checkPermission(); // Check mic permission (also called during record)
6666
await controller.pause(); // Pause recording
6767
final path = await controller.stop(); // Stop recording and get the path
6868
controller.refresh(); // Refresh waveform to original position
@@ -129,7 +129,8 @@ await controller.pausePlayer(); // Pause aud
129129
await controller.stopPlayer(); // Stop audio player
130130
await controller.setVolume(1.0); // Set volume level
131131
await controller.seekTo(5000); // Seek audio
132-
final duration = await controller.getDuration(DurationType.max); // Get duration of audio player
132+
final duration = await controller.getDuration(DurationType.max); // Get duration of audio player
133+
controller.updateFrequency = UpdateFrequency.low; // Update reporting rate of current duration.
133134
controller.onPlayerStateChanged.listen((state) {}); // Listening to player state changes
134135
controller.onCurrentDurationChanged.listen((duration) {}); // Listening to current duration changes
135136
controller.onCurrentExtractedWaveformData.listen((data) {}); // Listening to latest extraction data

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,16 @@ class AudioPlayer(
2424
private var isPlayerPrepared: Boolean = false
2525
private var finishMode = FinishMode.Stop
2626
private var key = playerKey
27+
private var updateFrequency = UpdateFrequency.Low
2728

2829
fun preparePlayer(
2930
result: MethodChannel.Result,
3031
path: String?,
31-
volume: Float?
32+
volume: Float?,
33+
frequency: UpdateFrequency,
3234
) {
3335
if (path != null) {
36+
updateFrequency = frequency
3437
val uri = Uri.parse(path)
3538
val mediaItem = MediaItem.fromUri(uri)
3639
player = ExoPlayer.Builder(appContext).build()
@@ -167,7 +170,7 @@ class AudioPlayer(
167170
args[Constants.current] = currentPosition
168171
args[Constants.playerKey] = key
169172
methodChannel.invokeMethod(Constants.onCurrentDuration, args)
170-
handler.postDelayed(this, 200)
173+
handler.postDelayed(this, updateFrequency.value)
171174
} else {
172175
result.error(Constants.LOG_TAG, "Can't get current Position of player", "")
173176
}

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

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,15 @@ class AudioWaveformsPlugin : FlutterPlugin, MethodCallHandler, ActivityAware {
7171
val audioPath = call.argument(Constants.path) as String?
7272
val volume = call.argument(Constants.volume) as Double?
7373
val key = call.argument(Constants.playerKey) as String?
74+
val frequency = call.argument(Constants.updateFrequency) as Int?
7475
if (key != null) {
7576
initPlayer(key)
76-
audioPlayers[key]?.preparePlayer(result, audioPath, volume?.toFloat())
77+
audioPlayers[key]?.preparePlayer(
78+
result,
79+
audioPath,
80+
volume?.toFloat(),
81+
getUpdateFrequency(frequency),
82+
)
7783
} else {
7884
result.error(Constants.LOG_TAG, "Player key can't be null", "")
7985
}
@@ -225,6 +231,15 @@ class AudioWaveformsPlugin : FlutterPlugin, MethodCallHandler, ActivityAware {
225231
return
226232
}
227233

234+
private fun getUpdateFrequency(frequency: Int?): UpdateFrequency {
235+
if (frequency == 2) {
236+
return UpdateFrequency.High
237+
} else if (frequency == 1) {
238+
return UpdateFrequency.Medium
239+
}
240+
return UpdateFrequency.Low
241+
}
242+
228243
private fun createOrUpdateExtractor(
229244
playerKey: String,
230245
noOfSamples: Int,

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,17 @@ object Constants {
6262
const val onCurrentExtractedWaveformData = "onCurrentExtractedWaveformData"
6363
const val waveformData = "waveformData"
6464
const val useLegacyNormalization = "useLegacyNormalization"
65+
const val updateFrequency = "updateFrequency"
6566
}
6667

6768
enum class FinishMode(val value:Int) {
6869
Loop(0),
6970
Pause(1),
7071
Stop(2)
72+
}
73+
74+
enum class UpdateFrequency(val value:Long) {
75+
High(50),
76+
Medium(100),
77+
Low(200),
7178
}

ios/Classes/AudioPlayer.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,21 @@ class AudioPlayer: NSObject, AVAudioPlayerDelegate {
88
private var timer: Timer?
99
private var player: AVAudioPlayer?
1010
private var finishMode: FinishMode = FinishMode.stop
11+
private var updateFrequency = UpdateFrequency.low
1112
var plugin: SwiftAudioWaveformsPlugin
1213
var playerKey: String
1314
var flutterChannel: FlutterMethodChannel
15+
1416

1517
init(plugin: SwiftAudioWaveformsPlugin, playerKey: String, channel: FlutterMethodChannel) {
1618
self.plugin = plugin
1719
self.playerKey = playerKey
1820
flutterChannel = channel
1921
}
2022

21-
func preparePlayer(path: String?, volume: Double?, result: @escaping FlutterResult) {
23+
func preparePlayer(path: String?, volume: Double?, updateFrequency: UpdateFrequency,result: @escaping FlutterResult) {
2224
if(!(path ?? "").isEmpty) {
25+
self.updateFrequency = updateFrequency
2326
let audioUrl = URL.init(string: path!)
2427
if(audioUrl == nil){
2528
result(FlutterError(code: Constants.audioWaveforms, message: "Failed to initialise Url from provided audio file", details: "If path contains `file://` try removing it"))
@@ -114,7 +117,7 @@ class AudioPlayer: NSObject, AVAudioPlayerDelegate {
114117

115118
func startListening() {
116119
if #available(iOS 10.0, *) {
117-
timer = Timer.scheduledTimer(withTimeInterval: 0.2, repeats: true, block: { _ in
120+
timer = Timer.scheduledTimer(withTimeInterval: (updateFrequency.rawValue / 1000), repeats: true, block: { _ in
118121
let ms = (self.player?.currentTime ?? 0) * 1000
119122
self.flutterChannel.invokeMethod(Constants.onCurrentDuration, arguments: [Constants.current: Int(ms), Constants.playerKey: self.playerKey])
120123
})

ios/Classes/SwiftAudioWaveformsPlugin.swift

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,10 @@ public class SwiftAudioWaveformsPlugin: NSObject, FlutterPlugin {
4848
let key = args?[Constants.playerKey] as? String
4949
if(key != nil){
5050
initPlayer(playerKey: key!)
51-
audioPlayers[key!]?.preparePlayer(path: args?[Constants.path] as? String, volume: args?[Constants.volume] as? Double,result: result)
51+
audioPlayers[key!]?.preparePlayer(path: args?[Constants.path] as? String,
52+
volume: args?[Constants.volume] as? Double,
53+
updateFrequency: getUpdateFrequency(freq: args?[Constants.updateFrequency] as? Int) ,
54+
result: result)
5255
} else {
5356
result(FlutterError(code: Constants.audioWaveforms, message: "Can not prepare player", details: "Player key is null"))
5457
}
@@ -129,6 +132,15 @@ public class SwiftAudioWaveformsPlugin: NSObject, FlutterPlugin {
129132
}
130133
}
131134

135+
func getUpdateFrequency(freq: Int?) -> UpdateFrequency{
136+
if(freq == 2){
137+
return UpdateFrequency.high
138+
} else if(freq == 1){
139+
return UpdateFrequency.medium
140+
}
141+
return UpdateFrequency.low
142+
}
143+
132144
func initPlayer(playerKey: String) {
133145
if audioPlayers[playerKey] == nil {
134146
let newPlayer = AudioPlayer(plugin: self,playerKey: playerKey,channel: flutterChannel)
@@ -144,7 +156,7 @@ public class SwiftAudioWaveformsPlugin: NSObject, FlutterPlugin {
144156
result(FlutterError(code: Constants.audioWaveforms, message: "Failed to initialise Url from provided audio file", details: "If path contains `file://` try removing it"))
145157
return
146158
}
147-
var newExtractor = try WaveformExtractor(url: audioUrl!, flutterResult: result, channel: flutterChannel)
159+
let newExtractor = try WaveformExtractor(url: audioUrl!, flutterResult: result, channel: flutterChannel)
148160
extractors[playerKey] = newExtractor
149161
let data = newExtractor.extractWaveform(samplesPerPixel: noOfSamples, playerKey: playerKey)
150162
newExtractor.cancel()

ios/Classes/Utils.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ struct Constants {
5656
static let waveformData = "waveformData"
5757
static let onExtractionProgressUpdate = "onExtractionProgressUpdate"
5858
static let useLegacyNormalization = "useLegacyNormalization"
59+
static let updateFrequency = "updateFrequency"
5960
}
6061

6162
enum FinishMode : Int{
@@ -64,6 +65,11 @@ enum FinishMode : Int{
6465
case stop = 2
6566
}
6667

68+
enum UpdateFrequency : Double{
69+
case high = 50.0
70+
case medium = 100.0
71+
case low = 200.0
72+
}
6773
/// Creates an 2D array of floats
6874
public typealias FloatChannelData = [[Float]]
6975

lib/src/base/audio_waveforms_interface.dart

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,17 @@ class AudioWaveformsInterface {
9191
}
9292

9393
///platform call to prepare player
94-
Future<bool> preparePlayer(String path, String key, [double? volume]) async {
94+
Future<bool> preparePlayer({
95+
required String path,
96+
required String key,
97+
required int frequency,
98+
double? volume,
99+
}) async {
95100
var result = await _methodChannel.invokeMethod(Constants.preparePlayer, {
96101
Constants.path: path,
97102
Constants.volume: volume,
98103
Constants.playerKey: key,
104+
Constants.updateFrequency: frequency,
99105
});
100106
return result ?? false;
101107
}

lib/src/base/constants.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,5 @@ class Constants {
4343
static const String onCurrentExtractedWaveformData =
4444
"onCurrentExtractedWaveformData";
4545
static const String useLegacyNormalization = "useLegacyNormalization";
46+
static const String updateFrequency = "updateFrequency";
4647
}

0 commit comments

Comments
 (0)