Skip to content

Commit 7bb39b2

Browse files
Merge pull request #66 from SimformSolutionsPvtLtd/fix/UNT-T28164_waveform_not_loaded_with_flatlist_after_scroll
fix(UNT-T28164): waveform not loaded with flatlist after scroll
2 parents 7e028e4 + 4aa6e13 commit 7bb39b2

File tree

5 files changed

+40
-9
lines changed

5 files changed

+40
-9
lines changed

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,4 +173,8 @@ class AudioPlayer(
173173
audioPlaybackListener.cancel()
174174
}
175175
}
176+
177+
fun isHoldingAudioTrack(): Boolean {
178+
return ::audioPlaybackListener.isInitialized
179+
}
176180
}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class AudioWaveformModule(context: ReactApplicationContext): ReactContextBaseJav
3434

3535
companion object {
3636
const val NAME = "AudioWaveform"
37+
const val MAX_NUMBER_OF_AUDIO_PLAYER = 30
3738
}
3839

3940
override fun getName(): String {
@@ -100,6 +101,10 @@ class AudioWaveformModule(context: ReactApplicationContext): ReactContextBaseJav
100101
obj: ReadableMap,
101102
promise: Promise
102103
) {
104+
if(audioPlayers.filter { it.value?.isHoldingAudioTrack() == true }.count() >= MAX_NUMBER_OF_AUDIO_PLAYER) {
105+
promise.reject(Constants.LOG_TAG, "Too many players have been initialized. Please stop some players before continuing")
106+
}
107+
103108
val path = obj.getString(Constants.path)
104109
val key = obj.getString(Constants.playerKey)
105110
val frequency = obj.getInt(Constants.updateFrequency)
@@ -133,6 +138,7 @@ class AudioWaveformModule(context: ReactApplicationContext): ReactContextBaseJav
133138
val key = obj.getString(Constants.playerKey)
134139
if (key != null) {
135140
audioPlayers[key]?.stop(promise)
141+
audioPlayers[key] = null // Release the player after stopping it
136142
} else {
137143
promise.reject("stopPlayer Error", "Player key can't be null")
138144
}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import java.nio.ByteBuffer
1616
import java.util.concurrent.CountDownLatch
1717
import kotlin.math.pow
1818
import kotlin.math.sqrt
19+
import java.io.File
1920

2021
class WaveformExtractor(
2122
context: ReactApplicationContext,
@@ -66,6 +67,11 @@ class WaveformExtractor(
6667

6768
fun startDecode() {
6869
try {
70+
if (!File(path).exists()) {
71+
promise.reject("File Error", "File does not exist at the given path.")
72+
return
73+
}
74+
6975
val format = getFormat(path) ?: error("No audio format found")
7076
val mime = format.getString(MediaFormat.KEY_MIME) ?: error("No MIME type found")
7177
decoder = MediaCodec.createDecoderByType(mime).also {

ios/AudioWaveform.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ class AudioWaveform: RCTEventEmitter {
172172
let key = args?[Constants.playerKey] as? String
173173
if(key != nil){
174174
audioPlayers[key!]?.stopPlayer(result: resolve)
175+
audioPlayers[key!] = nil // Release the player after stopping it
175176
} else {
176177
reject(Constants.audioWaveforms, "Can not stop player, Player key is null", NSError())
177178
}

src/components/Waveform/Waveform.tsx

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
PanResponder,
1111
ScrollView,
1212
View,
13+
type LayoutChangeEvent,
1314
type LayoutRectangle,
1415
type NativeTouchEvent,
1516
} from 'react-native';
@@ -114,7 +115,9 @@ export const Waveform = forwardRef<IWaveformRef, IWaveform>((props, ref) => {
114115
durationType: DurationType.max,
115116
});
116117
if (!isNil(duration)) {
117-
setSongDuration(duration);
118+
const audioDuration = Number(duration);
119+
setSongDuration(audioDuration > 0 ? audioDuration : 0);
120+
return Promise.resolve(audioDuration);
118121
} else {
119122
return Promise.reject(
120123
new Error(`Could not get duration for path: ${path}`)
@@ -129,7 +132,10 @@ export const Waveform = forwardRef<IWaveformRef, IWaveform>((props, ref) => {
129132
try {
130133
const prepare = await preparePlayerForPath();
131134
if (prepare) {
132-
await getAudioDuration();
135+
const duration = await getAudioDuration();
136+
if (duration < 0) {
137+
await getAudioDuration();
138+
}
133139
}
134140
} catch (err) {
135141
console.error(err);
@@ -174,7 +180,6 @@ export const Waveform = forwardRef<IWaveformRef, IWaveform>((props, ref) => {
174180
const result = await stopPlayer({
175181
playerKey: `PlayerFor${path}`,
176182
});
177-
await preparePlayerForPath();
178183
if (!isNil(result) && result) {
179184
setCurrentProgress(0);
180185
setPlayerState(PlayerState.stopped);
@@ -197,6 +202,10 @@ export const Waveform = forwardRef<IWaveformRef, IWaveform>((props, ref) => {
197202
const startPlayerAction = async (args?: IStartPlayerRef) => {
198203
if (mode === 'static') {
199204
try {
205+
if (playerState === PlayerState.stopped) {
206+
await preparePlayerForPath();
207+
}
208+
200209
const play = await playPlayer({
201210
finishMode: FinishMode.stop,
202211
playerKey: `PlayerFor${path}`,
@@ -409,7 +418,13 @@ export const Waveform = forwardRef<IWaveformRef, IWaveform>((props, ref) => {
409418

410419
const tracePlaybackValue = onCurrentDuration(data => {
411420
if (data.playerKey === `PlayerFor${path}`) {
412-
setCurrentProgress(data.currentDuration);
421+
const currentAudioDuration = Number(data.currentDuration);
422+
423+
if (!isNaN(currentAudioDuration)) {
424+
setCurrentProgress(currentAudioDuration);
425+
} else {
426+
setCurrentProgress(0);
427+
}
413428
}
414429
});
415430

@@ -500,18 +515,17 @@ export const Waveform = forwardRef<IWaveformRef, IWaveform>((props, ref) => {
500515
<View
501516
ref={viewRef}
502517
style={styles.waveformInnerContainer}
503-
onLayout={() => {
504-
viewRef.current?.measure((_x, _y, width, height, pageX, pageY) => {
505-
setViewLayout({ height, width, x: pageX, y: pageY });
506-
});
518+
onLayout={(event: LayoutChangeEvent) => {
519+
const { height, width, x, y } = event.nativeEvent.layout;
520+
setViewLayout({ height, width, x, y });
507521
}}
508522
{...(mode === 'static' ? panResponder.panHandlers : {})}>
509523
<ScrollView
510524
horizontal
511525
ref={scrollRef}
512526
style={styles.scrollContainer}
513527
scrollEnabled={mode === 'live'}>
514-
{waveform.map((amplitude, indexCandle) => (
528+
{waveform?.map?.((amplitude, indexCandle) => (
515529
<WaveformCandle
516530
key={indexCandle}
517531
index={indexCandle}

0 commit comments

Comments
 (0)