Skip to content

Commit 162fe4e

Browse files
Merge pull request #72 from SimformSolutionsPvtLtd/feature/UNT-T28297_Implement_playback_speed
feat(UNT-T28297): Implement playback speed
2 parents 3f31e64 + 2cd5766 commit 162fe4e

File tree

26 files changed

+216
-32
lines changed

26 files changed

+216
-32
lines changed

README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ A React Native package featuring native modules for generating and rendering aud
1212

1313
## 🎬 Preview
1414

15-
| Audio Playback Waveform | Audio Record Waveform |
16-
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
17-
| <a href="https://github.com/SimformSolutionsPvtLtd/react-native-audio-waveform"><img width="352px;" height="640px;" alt="AudioPlaybackWaveform" src="./assets/audio_playback.gif"> </a> | <a href="https://github.com/SimformSolutionsPvtLtd/react-native-audio-waveform"><img width="352px;" height="640px;" alt="AudioRecordWaveform" src="./assets/audio_record.gif"> </a> |
15+
| Audio Playback Waveform | Audio Record Waveform | Audio Waveform with Speed |
16+
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
17+
| <a href="https://github.com/SimformSolutionsPvtLtd/react-native-audio-waveform"><img width="400px;" height="500px;" alt="AudioPlaybackWaveform" src="./assets/audio_playback.gif"> </a> | <a href="https://github.com/SimformSolutionsPvtLtd/react-native-audio-waveform"><img width="400px;" height="500px;" alt="AudioRecordWaveform" src="./assets/audio_record.gif"> </a> | <a href="https://github.com/SimformSolutionsPvtLtd/react-native-audio-waveform"><img width="400px;" height="500px;" alt="AudioRecordWaveform" src="./assets/audio_playback_with_speed.gif"> </a> |
1818

1919
## Quick Access
2020

@@ -132,6 +132,7 @@ You can check out the full example at [Example](./example/src/App.tsx).
132132
| mode\* | - ||| 'live' or 'static' | Type of waveform. It can be either `static` for the resource file or `live` if you want to record audio |
133133
| ref\* | - ||| IWaveformRef | Type of ref provided to waveform component. If waveform mode is `static`, some methods from ref will throw error and same for `live`.<br> Check [IWaveformRef](#iwaveformref-methods) for more details about which methods these refs provides. |
134134
| path\* | - ||| string | Used for `static` type. It is the resource path of an audio source file. |
135+
| playbackSpeed | 1.0 ||| 1.0 / 1.5 / 2.0 | The playback speed of the audio player. Note: Currently playback speed only supports, Normal (1x) Faster(1.5x) and Fastest(2.0x), any value passed to playback speed greater than 2.0 will be automatically adjusted to normal playback speed |
135136
| candleSpace | 2 ||| number | Space between two candlesticks of waveform |
136137
| candleWidth | 5 ||| number | Width of single candlestick of waveform |
137138
| candleHeightScale | 3 ||| number | Scaling height of candlestick of waveform |

android/src/main/java/com/audiowaveform/AudioPlayer.kt

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,18 @@ class AudioPlayer(
105105
}
106106
}
107107

108-
fun start(finishMode: Int?, promise: Promise) {
108+
private fun validateAndSetPlaybackSpeed(player: Player, speed: Float?): Boolean {
109+
// Validate the speed: if null or less than or equal to 0, set to 1f
110+
val validSpeed = if (speed == null || speed <= 0f) 1f else speed
111+
112+
// Set the playback speed on the player
113+
val playbackParameters = player.playbackParameters.withSpeed(validSpeed)
114+
player.playbackParameters = playbackParameters
115+
116+
return true // Indicate success
117+
}
118+
119+
fun start(finishMode: Int?, speed: Float?, promise: Promise) {
109120
try {
110121
if (finishMode != null && finishMode == 0) {
111122
this.finishMode = FinishMode.Loop
@@ -114,6 +125,9 @@ class AudioPlayer(
114125
} else {
115126
this.finishMode = FinishMode.Stop
116127
}
128+
129+
validateAndSetPlaybackSpeed(player, speed)
130+
117131
player.playWhenReady = true
118132
player.play()
119133
promise.resolve(true)
@@ -158,6 +172,18 @@ class AudioPlayer(
158172
}
159173
}
160174

175+
fun setPlaybackSpeed(speed: Float?, promise: Promise) {
176+
try {
177+
// Call the custom function to validate and set the playback speed
178+
val success = validateAndSetPlaybackSpeed(player, speed)
179+
promise.resolve(success) // Resolve the promise with success
180+
181+
} catch (e: Exception) {
182+
// Handle any exceptions and reject the promise
183+
promise.reject("setPlaybackSpeed Error", e.toString())
184+
}
185+
}
186+
161187
private fun startListening(promise: Promise) {
162188
try {
163189
audioPlaybackListener = object : CountDownTimer(player.duration, UpdateFrequency.Low.value) {

android/src/main/java/com/audiowaveform/AudioWaveformModule.kt

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,9 @@ class AudioWaveformModule(context: ReactApplicationContext): ReactContextBaseJav
133133
fun startPlayer(obj: ReadableMap, promise: Promise) {
134134
val finishMode = obj.getInt(Constants.finishMode)
135135
val key = obj.getString(Constants.playerKey)
136+
val speed = obj.getDouble(Constants.speed)
136137
if (key != null) {
137-
audioPlayers[key]?.start(finishMode ?: 2, promise)
138+
audioPlayers[key]?.start(finishMode ?: 2, speed.toFloat(),promise)
138139
} else {
139140
promise.reject("startPlayer Error", "Player key can't be null")
140141
}
@@ -222,6 +223,23 @@ class AudioWaveformModule(context: ReactApplicationContext): ReactContextBaseJav
222223
}
223224
}
224225

226+
@ReactMethod
227+
fun setPlaybackSpeed(obj: ReadableMap, promise: Promise) {
228+
// If the key doesn't exist or if the value is null or undefined, set default speed to 1.0
229+
val speed = if (!obj.hasKey(Constants.speed) || obj.isNull(Constants.speed)) {
230+
1.0f // Set default speed to 1.0 if null, undefined, or missing
231+
} else {
232+
obj.getDouble(Constants.speed).toFloat()
233+
}
234+
235+
val key = obj.getString(Constants.playerKey)
236+
if (key != null) {
237+
audioPlayers[key]?.setPlaybackSpeed(speed, promise)
238+
} else {
239+
promise.reject("setPlaybackSpeed Error", "Player key can't be null")
240+
}
241+
}
242+
225243
private fun initPlayer(playerKey: String) {
226244
if (audioPlayers[playerKey] == null) {
227245
val newPlayer = AudioPlayer(

android/src/main/java/com/audiowaveform/Utils.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ object Constants {
4343
const val currentDecibel = "currentDecibel"
4444
const val bitRate = "bitRate"
4545
const val sampleRate = "sampleRate"
46+
const val speed = "speed"
4647
}
4748

4849
enum class FinishMode(val value:Int) {

assets/audio_playback.gif

-3.8 MB
Loading
12.1 MB
Loading

assets/audio_record.gif

-237 KB
Loading

example/ios/AudioWaveformExample.xcodeproj/project.pbxproj

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@
1414
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
1515
4A3054DD28F34283AA8FEE0D /* file_example_mp3_15s.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = C2A26BD00D7D401B9804E1AA /* file_example_mp3_15s.mp3 */; };
1616
578F19E664D14A79A203A29B /* file_example_mp3_12s.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = D09FCEB6D8A04D349E9422A5 /* file_example_mp3_12s.mp3 */; };
17+
6393E563479648F7B8E27E90 /* file_example_mp3_700kb.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = 2026064602944A9C9A1F84D3 /* file_example_mp3_700kb.mp3 */; };
1718
7699B88040F8A987B510C191 /* libPods-AudioWaveformExample-AudioWaveformExampleTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 19F6CBCC0A4E27FBF8BF4A61 /* libPods-AudioWaveformExample-AudioWaveformExampleTests.a */; };
1819
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; };
19-
75825DA638CD44CCB89B4B48 /* index.ts in Resources */ = {isa = PBXBuildFile; fileRef = 4879BE3405234CBFAFAD88DB /* index.ts */; };
20+
DDA8C5D92054463296965254 /* index.ts in Resources */ = {isa = PBXBuildFile; fileRef = DEA7EA5ABBD543DFB81B93A1 /* index.ts */; };
2021
F754817CD5E04214A63ED292 /* file_example_mp3_1mg.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = 3D92446673D84104B7DBB5E8 /* file_example_mp3_1mg.mp3 */; };
21-
6393E563479648F7B8E27E90 /* file_example_mp3_700kb.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = 2026064602944A9C9A1F84D3 /* file_example_mp3_700kb.mp3 */; };
2222
/* End PBXBuildFile section */
2323

2424
/* Begin PBXContainerItemProxy section */
@@ -42,18 +42,18 @@
4242
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = AudioWaveformExample/Info.plist; sourceTree = "<group>"; };
4343
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = AudioWaveformExample/main.m; sourceTree = "<group>"; };
4444
19F6CBCC0A4E27FBF8BF4A61 /* libPods-AudioWaveformExample-AudioWaveformExampleTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-AudioWaveformExample-AudioWaveformExampleTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
45+
2026064602944A9C9A1F84D3 /* file_example_mp3_700kb.mp3 */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = undefined; includeInIndex = 0; lastKnownFileType = unknown; name = file_example_mp3_700kb.mp3; path = ../src/assets/audio/file_example_mp3_700kb.mp3; sourceTree = "<group>"; };
4546
3B4392A12AC88292D35C810B /* Pods-AudioWaveformExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AudioWaveformExample.debug.xcconfig"; path = "Target Support Files/Pods-AudioWaveformExample/Pods-AudioWaveformExample.debug.xcconfig"; sourceTree = "<group>"; };
47+
3D92446673D84104B7DBB5E8 /* file_example_mp3_1mg.mp3 */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = undefined; includeInIndex = 0; lastKnownFileType = unknown; name = file_example_mp3_1mg.mp3; path = ../src/assets/audio/file_example_mp3_1mg.mp3; sourceTree = "<group>"; };
4648
5709B34CF0A7D63546082F79 /* Pods-AudioWaveformExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AudioWaveformExample.release.xcconfig"; path = "Target Support Files/Pods-AudioWaveformExample/Pods-AudioWaveformExample.release.xcconfig"; sourceTree = "<group>"; };
4749
5B7EB9410499542E8C5724F5 /* Pods-AudioWaveformExample-AudioWaveformExampleTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AudioWaveformExample-AudioWaveformExampleTests.debug.xcconfig"; path = "Target Support Files/Pods-AudioWaveformExample-AudioWaveformExampleTests/Pods-AudioWaveformExample-AudioWaveformExampleTests.debug.xcconfig"; sourceTree = "<group>"; };
4850
5DCACB8F33CDC322A6C60F78 /* libPods-AudioWaveformExample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-AudioWaveformExample.a"; sourceTree = BUILT_PRODUCTS_DIR; };
4951
81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = AudioWaveformExample/LaunchScreen.storyboard; sourceTree = "<group>"; };
5052
89C6BE57DB24E9ADA2F236DE /* Pods-AudioWaveformExample-AudioWaveformExampleTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AudioWaveformExample-AudioWaveformExampleTests.release.xcconfig"; path = "Target Support Files/Pods-AudioWaveformExample-AudioWaveformExampleTests/Pods-AudioWaveformExample-AudioWaveformExampleTests.release.xcconfig"; sourceTree = "<group>"; };
5153
C2A26BD00D7D401B9804E1AA /* file_example_mp3_15s.mp3 */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = undefined; includeInIndex = 0; lastKnownFileType = unknown; name = file_example_mp3_15s.mp3; path = ../src/assets/audio/file_example_mp3_15s.mp3; sourceTree = "<group>"; };
5254
D09FCEB6D8A04D349E9422A5 /* file_example_mp3_12s.mp3 */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = undefined; includeInIndex = 0; lastKnownFileType = unknown; name = file_example_mp3_12s.mp3; path = ../src/assets/audio/file_example_mp3_12s.mp3; sourceTree = "<group>"; };
55+
DEA7EA5ABBD543DFB81B93A1 /* index.ts */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = undefined; includeInIndex = 0; lastKnownFileType = unknown; name = index.ts; path = ../src/assets/audio/index.ts; sourceTree = "<group>"; };
5356
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
54-
4879BE3405234CBFAFAD88DB /* index.ts */ = {isa = PBXFileReference; name = "index.ts"; path = "../src/assets/audio/index.ts"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
55-
3D92446673D84104B7DBB5E8 /* file_example_mp3_1mg.mp3 */ = {isa = PBXFileReference; name = "file_example_mp3_1mg.mp3"; path = "../src/assets/audio/file_example_mp3_1mg.mp3"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
56-
2026064602944A9C9A1F84D3 /* file_example_mp3_700kb.mp3 */ = {isa = PBXFileReference; name = "file_example_mp3_700kb.mp3"; path = "../src/assets/audio/file_example_mp3_700kb.mp3"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
5757
/* End PBXFileReference section */
5858

5959
/* Begin PBXFrameworksBuildPhase section */
@@ -111,9 +111,9 @@
111111
children = (
112112
D09FCEB6D8A04D349E9422A5 /* file_example_mp3_12s.mp3 */,
113113
C2A26BD00D7D401B9804E1AA /* file_example_mp3_15s.mp3 */,
114-
4879BE3405234CBFAFAD88DB /* index.ts */,
115114
3D92446673D84104B7DBB5E8 /* file_example_mp3_1mg.mp3 */,
116115
2026064602944A9C9A1F84D3 /* file_example_mp3_700kb.mp3 */,
116+
DEA7EA5ABBD543DFB81B93A1 /* index.ts */,
117117
);
118118
name = Resources;
119119
path = "";
@@ -270,9 +270,9 @@
270270
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
271271
578F19E664D14A79A203A29B /* file_example_mp3_12s.mp3 in Resources */,
272272
4A3054DD28F34283AA8FEE0D /* file_example_mp3_15s.mp3 in Resources */,
273-
75825DA638CD44CCB89B4B48 /* index.ts in Resources */,
274273
F754817CD5E04214A63ED292 /* file_example_mp3_1mg.mp3 in Resources */,
275274
6393E563479648F7B8E27E90 /* file_example_mp3_700kb.mp3 in Resources */,
275+
DDA8C5D92054463296965254 /* index.ts in Resources */,
276276
);
277277
runOnlyForDeploymentPostprocessing = 0;
278278
};

0 commit comments

Comments
 (0)