@@ -2,23 +2,24 @@ package com.audiowaveform
22
33import android.net.Uri
44import android.os.CountDownTimer
5+ import androidx.media3.common.MediaItem
6+ import androidx.media3.common.PlaybackException
7+ import androidx.media3.common.Player
8+ import androidx.media3.exoplayer.ExoPlayer
59import com.facebook.react.bridge.Arguments
610import com.facebook.react.bridge.Promise
711import com.facebook.react.bridge.ReactApplicationContext
812import com.facebook.react.bridge.WritableMap
913import com.facebook.react.common.JavascriptException
1014import com.facebook.react.modules.core.DeviceEventManagerModule
11- import androidx.media3.exoplayer.ExoPlayer
12- import androidx.media3.common.MediaItem
13- import androidx.media3.common.Player
1415
1516class AudioPlayer (
1617 context : ReactApplicationContext ,
1718 playerKey : String ,
1819) {
1920 private val appContext = context
2021 private lateinit var player: ExoPlayer
21- private var playerListener: Player .Listener ? = null
22+ private lateinit var playerListener: Player .Listener
2223 private var isPlayerPrepared: Boolean = false
2324 private var finishMode = FinishMode .Stop
2425 private val key = playerKey
@@ -49,8 +50,7 @@ class AudioPlayer(
4950 player.prepare()
5051 playerListener = object : Player .Listener {
5152
52- @Deprecated(" Deprecated in Java" )
53- override fun onPlayerStateChanged (isReady : Boolean , state : Int ) {
53+ override fun onPlaybackStateChanged (state : Int ) {
5454 if (! isPlayerPrepared) {
5555 if (state == Player .STATE_READY ) {
5656 player.volume = (volume ? : 1 ).toFloat()
@@ -59,6 +59,10 @@ class AudioPlayer(
5959 val duration = player.duration
6060 promise.resolve(duration.toString())
6161 }
62+ else if (state == Player .STATE_IDLE ) {
63+ // Fix leaking promise when path is incorrect
64+ promise.reject(" preparePlayer-onPlayerStateChanged-error-idle" , " Player stayed in idle state, unable to load $path " )
65+ }
6266 }
6367 if (state == Player .STATE_ENDED ) {
6468 val args: WritableMap = Arguments .createMap()
@@ -87,30 +91,27 @@ class AudioPlayer(
8791 }
8892 }
8993 }
94+ override fun onPlayerError (error : PlaybackException ) {
95+ promise.reject(" preparePlayer-onPlayerError" , error.message)
96+ }
9097 }
91- player.addListener(playerListener!! )
98+
99+ player.addListener(playerListener)
92100 } else {
93- promise.reject(" preparePlayer Error " , " path to audio file or unique key can't be null" )
101+ promise.reject(" preparePlayer-error " , " path to audio file or unique key can't be null" )
94102 }
95103 }
96104
97- fun seekToPosition (progress : Long? , promise : Promise ) {
105+ fun seekToPosition (progress : Long? ): Boolean {
98106 if (progress != null ) {
99107 player.seekTo(progress)
100- promise.resolve(true )
101- } else {
102- promise.resolve(false )
108+ return true ;
103109 }
110+ return false ;
104111 }
105112
106- fun getDuration (durationType : DurationType , promise : Promise ) {
107- if (durationType == DurationType .Current ) {
108- val duration = player.currentPosition
109- promise.resolve(duration.toString())
110- } else {
111- val duration = player.duration
112- promise.resolve(duration.toString())
113- }
113+ fun getDuration (durationType : DurationType ): Long {
114+ return if (durationType == DurationType .Current ) player.currentPosition else player.duration
114115 }
115116
116117 private fun validateAndSetPlaybackSpeed (player : Player , speed : Float? ): Boolean {
@@ -124,75 +125,48 @@ class AudioPlayer(
124125 return true // Indicate success
125126 }
126127
127- fun start (finishMode : Int? , speed : Float? , promise : Promise ) {
128- try {
129- if (finishMode != null && finishMode == 0 ) {
130- this .finishMode = FinishMode .Loop
131- } else if (finishMode != null && finishMode == 1 ) {
132- this .finishMode = FinishMode .Pause
133- } else {
134- this .finishMode = FinishMode .Stop
135- }
128+ fun start (finishMode : Int , speed : Float ): Boolean {
129+ this .finishMode = when (finishMode) {
130+ 0 -> FinishMode .Loop
131+ 1 -> FinishMode .Pause
132+ else -> FinishMode .Stop
133+ }
136134
137- validateAndSetPlaybackSpeed(player, speed)
135+ validateAndSetPlaybackSpeed(player, speed)
138136
139- player.playWhenReady = true
140- player.play()
141- promise.resolve(true )
142- startListening(promise)
143- } catch (e: Exception ) {
144- promise.reject(" Can not start the player" , e.toString())
145- }
137+ player.playWhenReady = true
138+ player.play()
139+ startListening()
140+ return true
146141 }
147142
148- fun stop (promise : Promise ) {
143+ fun stop () {
149144 stopListening()
150- if (playerListener != null ) {
151- player.removeListener(playerListener!! )
152- }
145+ player.removeListener(playerListener)
153146 isPlayerPrepared = false
154- player.stop()
147+ if (player.isPlaying) player.stop()
155148 player.release()
156- promise.resolve(true )
157149 }
158150
159- fun pause (promise : Promise ) {
160- try {
161- stopListening()
162- player.pause()
163- promise.resolve(true )
164- } catch (e: Exception ) {
165- promise.reject(" Failed to pause the player" , e.toString())
166- }
167-
151+ fun pause (): Boolean {
152+ stopListening()
153+ player.pause()
154+ return true
168155 }
169156
170- fun setVolume (volume : Float? , promise : Promise ) {
157+ fun setVolume (volume : Float ): Boolean {
171158 try {
172- if (volume != null ) {
173- player.volume = volume
174- promise.resolve(true )
175- } else {
176- promise.resolve(false )
177- }
178- } catch (e: Exception ) {
179- promise.resolve(false )
159+ player.volume = volume
160+ return true ;
161+ } catch (_: Exception ) {
162+ // Noop
180163 }
164+ return false
181165 }
182166
183- fun setPlaybackSpeed (speed : Float? , promise : Promise ) {
184- try {
185- // Call the custom function to validate and set the playback speed
186- val success = validateAndSetPlaybackSpeed(player, speed)
187- promise.resolve(success) // Resolve the promise with success
188-
189- } catch (e: Exception ) {
190- // Handle any exceptions and reject the promise
191- promise.reject(" setPlaybackSpeed Error" , e.toString())
192- }
193- }
167+ fun setPlaybackSpeed (speed : Float? ) = validateAndSetPlaybackSpeed(player, speed)
194168
195- private fun startListening (promise : Promise ) {
169+ private fun startListening () {
196170 try {
197171 audioPlaybackListener = object : CountDownTimer (player.duration, UpdateFrequency .Low .value) {
198172 override fun onTick (millisUntilFinished : Long ) {
@@ -207,7 +181,7 @@ class AudioPlayer(
207181 override fun onFinish () {}
208182 }.start()
209183 } catch (err: JavascriptException ) {
210- promise.reject (" startListening Error " , err)
184+ throw Exception (" startListening-error " , err)
211185 }
212186 }
213187
0 commit comments