Skip to content

Commit

Permalink
Merge pull request #77 from SimformSolutionsPvtLtd/develop
Browse files Browse the repository at this point in the history
Release v2.1.0
  • Loading branch information
mukesh-simform authored Sep 13, 2024
2 parents 1e657f3 + 5d5c3d9 commit bb64154
Show file tree
Hide file tree
Showing 35 changed files with 449 additions and 139 deletions.
117 changes: 62 additions & 55 deletions README.md

Large diffs are not rendered by default.

15 changes: 10 additions & 5 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ buildscript {
}

dependencies {
classpath "com.android.tools.build:gradle:7.2.1"
classpath "com.android.tools.build:gradle:8.1.0"
// noinspection DifferentKotlinGradleVersion
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
Expand Down Expand Up @@ -71,8 +71,12 @@ android {
}

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
}

kotlinOptions {
jvmTarget = "11"
}
}

Expand All @@ -93,6 +97,7 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"


// Android Audio Playback Dependency
implementation "com.google.android.exoplayer:exoplayer:2.17.1"
// Android Audio Media3 Dependency
implementation 'androidx.media3:media3-exoplayer:1.3.1'
implementation 'androidx.media3:media3-common:1.3.1'
}
7 changes: 4 additions & 3 deletions android/gradle.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
AudioWaveform_kotlinVersion=1.7.0
AudioWaveform_kotlinVersion=1.6.10
AudioWaveform_minSdkVersion=21
AudioWaveform_targetSdkVersion=31
AudioWaveform_compileSdkVersion=31
AudioWaveform_targetSdkVersion=34
AudioWaveform_compileSdkVersion=34
AudioWaveform_ndkversion=21.4.7075529
android.suppressUnsupportedCompileSdk=34
48 changes: 43 additions & 5 deletions android/src/main/java/com/audiowaveform/AudioPlayer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.WritableMap
import com.facebook.react.common.JavascriptException
import com.facebook.react.modules.core.DeviceEventManagerModule
import com.google.android.exoplayer2.ExoPlayer
import com.google.android.exoplayer2.MediaItem
import com.google.android.exoplayer2.Player
import androidx.media3.exoplayer.ExoPlayer
import androidx.media3.common.MediaItem
import androidx.media3.common.Player

class AudioPlayer(
context: ReactApplicationContext,
Expand All @@ -25,8 +25,15 @@ class AudioPlayer(
private var updateFrequency = UpdateFrequency.Low
private lateinit var audioPlaybackListener: CountDownTimer

fun preparePlayer(path: String?, volume: Int?, frequency: UpdateFrequency, promise: Promise) {
fun preparePlayer(
path: String?,
volume: Int?,
frequency: UpdateFrequency,
progress: Long,
promise: Promise
) {
if (path != null) {
isPlayerPrepared = false
updateFrequency = frequency
val uri = Uri.parse(path)
val mediaItem = MediaItem.fromUri(uri)
Expand All @@ -41,6 +48,7 @@ class AudioPlayer(
if (!isPlayerPrepared) {
if (state == Player.STATE_READY) {
player.volume = (volume ?: 1).toFloat()
player.seekTo(progress)
isPlayerPrepared = true
val duration = player.duration
promise.resolve(duration.toString())
Expand Down Expand Up @@ -97,7 +105,18 @@ class AudioPlayer(
}
}

fun start(finishMode: Int?, promise: Promise) {
private fun validateAndSetPlaybackSpeed(player: Player, speed: Float?): Boolean {
// Validate the speed: if null or less than or equal to 0, set to 1f
val validSpeed = if (speed == null || speed <= 0f) 1f else speed

// Set the playback speed on the player
val playbackParameters = player.playbackParameters.withSpeed(validSpeed)
player.playbackParameters = playbackParameters

return true // Indicate success
}

fun start(finishMode: Int?, speed: Float?, promise: Promise) {
try {
if (finishMode != null && finishMode == 0) {
this.finishMode = FinishMode.Loop
Expand All @@ -106,6 +125,9 @@ class AudioPlayer(
} else {
this.finishMode = FinishMode.Stop
}

validateAndSetPlaybackSpeed(player, speed)

player.playWhenReady = true
player.play()
promise.resolve(true)
Expand Down Expand Up @@ -150,6 +172,18 @@ class AudioPlayer(
}
}

fun setPlaybackSpeed(speed: Float?, promise: Promise) {
try {
// Call the custom function to validate and set the playback speed
val success = validateAndSetPlaybackSpeed(player, speed)
promise.resolve(success) // Resolve the promise with success

} catch (e: Exception) {
// Handle any exceptions and reject the promise
promise.reject("setPlaybackSpeed Error", e.toString())
}
}

private fun startListening(promise: Promise) {
try {
audioPlaybackListener = object : CountDownTimer(player.duration, UpdateFrequency.Low.value) {
Expand All @@ -172,4 +206,8 @@ class AudioPlayer(
audioPlaybackListener.cancel()
}
}

fun isHoldingAudioTrack(): Boolean {
return ::audioPlaybackListener.isInitialized
}
}
33 changes: 32 additions & 1 deletion android/src/main/java/com/audiowaveform/AudioWaveformModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class AudioWaveformModule(context: ReactApplicationContext): ReactContextBaseJav

companion object {
const val NAME = "AudioWaveform"
const val MAX_NUMBER_OF_AUDIO_PLAYER = 30
}

override fun getName(): String {
Expand Down Expand Up @@ -100,16 +101,27 @@ class AudioWaveformModule(context: ReactApplicationContext): ReactContextBaseJav
obj: ReadableMap,
promise: Promise
) {
if(audioPlayers.filter { it.value?.isHoldingAudioTrack() == true }.count() >= MAX_NUMBER_OF_AUDIO_PLAYER) {
promise.reject(Constants.LOG_TAG, "Too many players have been initialized. Please stop some players before continuing")
}

val path = obj.getString(Constants.path)
val key = obj.getString(Constants.playerKey)
val frequency = obj.getInt(Constants.updateFrequency)
val volume = obj.getInt(Constants.volume)
val progress = if (!obj.hasKey(Constants.progress) || obj.isNull(Constants.progress)) {
0 // Set default progress to zero if null, undefined, or missing
} else {
obj.getInt(Constants.progress).toLong()
}

if (key != null) {
initPlayer(key)
audioPlayers[key]?.preparePlayer(
path,
volume,
getUpdateFrequency(frequency),
progress,
promise
)
} else {
Expand All @@ -121,8 +133,9 @@ class AudioWaveformModule(context: ReactApplicationContext): ReactContextBaseJav
fun startPlayer(obj: ReadableMap, promise: Promise) {
val finishMode = obj.getInt(Constants.finishMode)
val key = obj.getString(Constants.playerKey)
val speed = obj.getDouble(Constants.speed)
if (key != null) {
audioPlayers[key]?.start(finishMode ?: 2, promise)
audioPlayers[key]?.start(finishMode ?: 2, speed.toFloat(),promise)
} else {
promise.reject("startPlayer Error", "Player key can't be null")
}
Expand All @@ -133,6 +146,7 @@ class AudioWaveformModule(context: ReactApplicationContext): ReactContextBaseJav
val key = obj.getString(Constants.playerKey)
if (key != null) {
audioPlayers[key]?.stop(promise)
audioPlayers[key] = null // Release the player after stopping it
} else {
promise.reject("stopPlayer Error", "Player key can't be null")
}
Expand Down Expand Up @@ -209,6 +223,23 @@ class AudioWaveformModule(context: ReactApplicationContext): ReactContextBaseJav
}
}

@ReactMethod
fun setPlaybackSpeed(obj: ReadableMap, promise: Promise) {
// If the key doesn't exist or if the value is null or undefined, set default speed to 1.0
val speed = if (!obj.hasKey(Constants.speed) || obj.isNull(Constants.speed)) {
1.0f // Set default speed to 1.0 if null, undefined, or missing
} else {
obj.getDouble(Constants.speed).toFloat()
}

val key = obj.getString(Constants.playerKey)
if (key != null) {
audioPlayers[key]?.setPlaybackSpeed(speed, promise)
} else {
promise.reject("setPlaybackSpeed Error", "Player key can't be null")
}
}

private fun initPlayer(playerKey: String) {
if (audioPlayers[playerKey] == null) {
val newPlayer = AudioPlayer(
Expand Down
1 change: 1 addition & 0 deletions android/src/main/java/com/audiowaveform/Utils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ object Constants {
const val currentDecibel = "currentDecibel"
const val bitRate = "bitRate"
const val sampleRate = "sampleRate"
const val speed = "speed"
}

enum class FinishMode(val value:Int) {
Expand Down
6 changes: 6 additions & 0 deletions android/src/main/java/com/audiowaveform/WaveformExtractor.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import java.nio.ByteBuffer
import java.util.concurrent.CountDownLatch
import kotlin.math.pow
import kotlin.math.sqrt
import java.io.File

class WaveformExtractor(
context: ReactApplicationContext,
Expand Down Expand Up @@ -66,6 +67,11 @@ class WaveformExtractor(

fun startDecode() {
try {
if (!File(path).exists()) {
promise.reject("File Error", "File does not exist at the given path.")
return
}

val format = getFormat(path) ?: error("No audio format found")
val mime = format.getString(MediaFormat.KEY_MIME) ?: error("No MIME type found")
decoder = MediaCodec.createDecoderByType(mime).also {
Expand Down
Binary file modified assets/audio_playback.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/audio_playback_with_speed.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/audio_record.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions example/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ buildscript {
ext {
buildToolsVersion = "33.0.0"
minSdkVersion = 21
compileSdkVersion = 33
targetSdkVersion = 33
compileSdkVersion = 34
targetSdkVersion = 34

// We use NDK 23 which has both M1 support and is the side-by-side NDK version from AGP.
ndkVersion = "23.1.7779620"
Expand Down
14 changes: 7 additions & 7 deletions example/ios/AudioWaveformExample.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
4A3054DD28F34283AA8FEE0D /* file_example_mp3_15s.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = C2A26BD00D7D401B9804E1AA /* file_example_mp3_15s.mp3 */; };
578F19E664D14A79A203A29B /* file_example_mp3_12s.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = D09FCEB6D8A04D349E9422A5 /* file_example_mp3_12s.mp3 */; };
6393E563479648F7B8E27E90 /* file_example_mp3_700kb.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = 2026064602944A9C9A1F84D3 /* file_example_mp3_700kb.mp3 */; };
7699B88040F8A987B510C191 /* libPods-AudioWaveformExample-AudioWaveformExampleTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 19F6CBCC0A4E27FBF8BF4A61 /* libPods-AudioWaveformExample-AudioWaveformExampleTests.a */; };
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; };
75825DA638CD44CCB89B4B48 /* index.ts in Resources */ = {isa = PBXBuildFile; fileRef = 4879BE3405234CBFAFAD88DB /* index.ts */; };
DDA8C5D92054463296965254 /* index.ts in Resources */ = {isa = PBXBuildFile; fileRef = DEA7EA5ABBD543DFB81B93A1 /* index.ts */; };
F754817CD5E04214A63ED292 /* file_example_mp3_1mg.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = 3D92446673D84104B7DBB5E8 /* file_example_mp3_1mg.mp3 */; };
6393E563479648F7B8E27E90 /* file_example_mp3_700kb.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = 2026064602944A9C9A1F84D3 /* file_example_mp3_700kb.mp3 */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand All @@ -42,18 +42,18 @@
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = AudioWaveformExample/Info.plist; sourceTree = "<group>"; };
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = AudioWaveformExample/main.m; sourceTree = "<group>"; };
19F6CBCC0A4E27FBF8BF4A61 /* libPods-AudioWaveformExample-AudioWaveformExampleTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-AudioWaveformExample-AudioWaveformExampleTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
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>"; };
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>"; };
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>"; };
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>"; };
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>"; };
5DCACB8F33CDC322A6C60F78 /* libPods-AudioWaveformExample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-AudioWaveformExample.a"; sourceTree = BUILT_PRODUCTS_DIR; };
81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = AudioWaveformExample/LaunchScreen.storyboard; sourceTree = "<group>"; };
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>"; };
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>"; };
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>"; };
DEA7EA5ABBD543DFB81B93A1 /* index.ts */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = undefined; includeInIndex = 0; lastKnownFileType = unknown; name = index.ts; path = ../src/assets/audio/index.ts; sourceTree = "<group>"; };
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
4879BE3405234CBFAFAD88DB /* index.ts */ = {isa = PBXFileReference; name = "index.ts"; path = "../src/assets/audio/index.ts"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
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; };
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; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -111,9 +111,9 @@
children = (
D09FCEB6D8A04D349E9422A5 /* file_example_mp3_12s.mp3 */,
C2A26BD00D7D401B9804E1AA /* file_example_mp3_15s.mp3 */,
4879BE3405234CBFAFAD88DB /* index.ts */,
3D92446673D84104B7DBB5E8 /* file_example_mp3_1mg.mp3 */,
2026064602944A9C9A1F84D3 /* file_example_mp3_700kb.mp3 */,
DEA7EA5ABBD543DFB81B93A1 /* index.ts */,
);
name = Resources;
path = "";
Expand Down Expand Up @@ -270,9 +270,9 @@
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
578F19E664D14A79A203A29B /* file_example_mp3_12s.mp3 in Resources */,
4A3054DD28F34283AA8FEE0D /* file_example_mp3_15s.mp3 in Resources */,
75825DA638CD44CCB89B4B48 /* index.ts in Resources */,
F754817CD5E04214A63ED292 /* file_example_mp3_1mg.mp3 in Resources */,
6393E563479648F7B8E27E90 /* file_example_mp3_700kb.mp3 in Resources */,
DDA8C5D92054463296965254 /* index.ts in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
Loading

0 comments on commit bb64154

Please sign in to comment.