Skip to content

Commit 4447aee

Browse files
Merge pull request #68 from SimformSolutionsPvtLtd/fix/UNT-T28237_UI_performance_issue_in_recording_mode
fix(UNT-T2823): ui performance issue in recording mode
2 parents 7bb39b2 + 9b762a9 commit 4447aee

File tree

3 files changed

+75
-55
lines changed

3 files changed

+75
-55
lines changed

README.md

Lines changed: 60 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
![Audio Waveform - Simform](./assets/react_native_audiowave.gif)
32

43
# react-native-audio-waveform
@@ -13,8 +12,8 @@ A React Native package featuring native modules for generating and rendering aud
1312

1413
## 🎬 Preview
1514

16-
| Audio Playback Waveform | Audio Record Waveform |
17-
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
15+
| Audio Playback Waveform | Audio Record Waveform |
16+
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
1817
| <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> |
1918

2019
## Quick Access
@@ -81,19 +80,22 @@ When you want to show a waveform for a pre-existing audio file, you need to use
8180
Check the example below for more information.
8281

8382
```tsx
84-
import { Waveform, type IWaveformRef } from '@simform_solutions/react-native-audio-waveform';
83+
import {
84+
Waveform,
85+
type IWaveformRef,
86+
} from '@simform_solutions/react-native-audio-waveform';
8587

8688
const path = ''; // path to the audio file for which you want to show waveform
8789
const ref = useRef<IWaveformRef>(null);
8890
<Waveform
89-
mode="static"
90-
ref={ref}
91-
path={item}
92-
candleSpace={2}
93-
candleWidth={4}
94-
scrubColor="white"
95-
onPlayerStateChange={playerState=>console.log(playerState)}
96-
onPanStateChange={isMoving=>console.log(isMoving)}
91+
mode="static"
92+
ref={ref}
93+
path={item}
94+
candleSpace={2}
95+
candleWidth={4}
96+
scrubColor="white"
97+
onPlayerStateChange={playerState => console.log(playerState)}
98+
onPanStateChange={isMoving => console.log(isMoving)}
9799
/>;
98100
```
99101

@@ -104,16 +106,19 @@ When you want to record audio and show a waveform for that recording, you need t
104106
Check the example below for more information.
105107

106108
```tsx
107-
import { Waveform, type IWaveformRef } from '@simform_solutions/react-native-audio-waveform';
109+
import {
110+
Waveform,
111+
type IWaveformRef,
112+
} from '@simform_solutions/react-native-audio-waveform';
108113

109114
const ref = useRef<IWaveformRef>(null);
110115
<Waveform
111-
mode="live"
112-
ref={ref}
113-
candleSpace={2}
114-
candleWidth={4}
115-
onRecorderStateChange={recorderState => console.log(recorderState)}
116-
/>
116+
mode="live"
117+
ref={ref}
118+
candleSpace={2}
119+
candleWidth={4}
120+
onRecorderStateChange={recorderState => console.log(recorderState)}
121+
/>;
117122
```
118123

119124
You can check out the full example at [Example](./example/src/App.tsx).
@@ -122,23 +127,24 @@ You can check out the full example at [Example](./example/src/App.tsx).
122127

123128
## Properties
124129

125-
| **Props** | **Default** | **Static Mode** | **Live Mode** | **Type** | **Description** |
126-
| --------------------- | ---------- | --------------- | ------------- | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
127-
| mode\* | - ||| 'live' or 'static' | Type of waveform. It can be either `static` for the resource file or `live` if you want to record audio |
128-
| 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. |
129-
| path\* | - ||| string | Used for `static` type. It is the resource path of an audio source file. |
130-
| candleSpace | 2 ||| number | Space between two candlesticks of waveform |
131-
| candleWidth | 5 ||| number | Width of single candlestick of waveform |
132-
| candleHeightScale | 3 ||| number | Scaling height of candlestick of waveform |
133-
| containerStyle | - ||| `StyleProp<ViewStyle>` | style of the container |
134-
| waveColor | #545454 ||| string | color of candlestick of waveform |
135-
| scrubColor | #7b7b7b ||| string | color of candlestick of waveform which has played |
136-
| onPlayerStateChange | - ||| ( playerState : PlayerState ) => void | callback function, which returns player state whenever player state changes. |
137-
| onPanStateChange | - ||| ( panMoving : boolean ) => void | callback function which returns boolean indicating whether audio seeking is active or not. |
138-
| onRecorderStateChange | - ||| ( recorderState : RecorderState ) => void | callback function which returns the recorder state whenever the recorder state changes. Check RecorderState for more details |
139-
| onCurrentProgressChange | - ||| ( currentProgress : number, songDuration: number ) => void | callback function, which returns current progress of audio and total song duration. |
140-
| onChangeWaveformLoadState | - ||| ( state : boolean ) => void | callback function which returns the loading state of waveform candlestick. |
141-
| onError | - ||| ( error : Error ) => void | callback function which returns the error for static audio waveform |
130+
| **Props** | **Default** | **Static Mode** | **Live Mode** | **Type** | **Description** |
131+
| ------------------------- | ----------- | --------------- | ------------- | ---------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
132+
| mode\* | - ||| 'live' or 'static' | Type of waveform. It can be either `static` for the resource file or `live` if you want to record audio |
133+
| 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. |
134+
| path\* | - ||| string | Used for `static` type. It is the resource path of an audio source file. |
135+
| candleSpace | 2 ||| number | Space between two candlesticks of waveform |
136+
| candleWidth | 5 ||| number | Width of single candlestick of waveform |
137+
| candleHeightScale | 3 ||| number | Scaling height of candlestick of waveform |
138+
| maxCandlesToRender | 300 ||| number | Number of candlestick in waveform |
139+
| containerStyle | - ||| `StyleProp<ViewStyle>` | style of the container |
140+
| waveColor | #545454 ||| string | color of candlestick of waveform |
141+
| scrubColor | #7b7b7b ||| string | color of candlestick of waveform which has played |
142+
| onPlayerStateChange | - ||| ( playerState : PlayerState ) => void | callback function, which returns player state whenever player state changes. |
143+
| onPanStateChange | - ||| ( panMoving : boolean ) => void | callback function which returns boolean indicating whether audio seeking is active or not. |
144+
| onRecorderStateChange | - ||| ( recorderState : RecorderState ) => void | callback function which returns the recorder state whenever the recorder state changes. Check RecorderState for more details |
145+
| onCurrentProgressChange | - ||| ( currentProgress : number, songDuration: number ) => void | callback function, which returns current progress of audio and total song duration. |
146+
| onChangeWaveformLoadState | - ||| ( state : boolean ) => void | callback function which returns the loading state of waveform candlestick. |
147+
| onError | - ||| ( error : Error ) => void | callback function which returns the error for static audio waveform |
142148

143149
##### Know more about [ViewStyle](https://reactnative.dev/docs/view-style-props), [PlayerState](#playerstate), and [RecorderState](#recorderstate)
144150

@@ -255,14 +261,14 @@ Check out the following example:
255261
let hasPermission = await checkHasAudioRecorderPermission();
256262

257263
if (hasPermission === PermissionStatus.granted) {
258-
startRecording();
264+
startRecording();
259265
} else if (hasPermission === PermissionStatus.undetermined) {
260-
const permissionStatus = await getAudioRecorderPermission();
261-
if (permissionStatus === PermissionStatus.granted) {
262-
startRecording();
263-
}
266+
const permissionStatus = await getAudioRecorderPermission();
267+
if (permissionStatus === PermissionStatus.granted) {
268+
startRecording();
269+
}
264270
} else {
265-
Linking.openSettings();
271+
Linking.openSettings();
266272
}
267273
```
268274

@@ -272,19 +278,19 @@ if (hasPermission === PermissionStatus.granted) {
272278

273279
```ts
274280
enum PlayerState {
275-
playing = 'playing',
276-
paused = 'paused',
277-
stopped = 'stopped',
281+
playing = 'playing',
282+
paused = 'paused',
283+
stopped = 'stopped',
278284
}
279285
```
280286

281287
#### RecorderState
282288

283289
```ts
284290
enum RecorderState {
285-
recording = 'recording',
286-
paused = 'paused',
287-
stopped = 'stopped',
291+
recording = 'recording',
292+
paused = 'paused',
293+
stopped = 'stopped',
288294
}
289295
```
290296

@@ -293,19 +299,19 @@ enum RecorderState {
293299
```ts
294300
// Update frequency in milliseconds
295301
enum UpdateFrequency {
296-
high = 250.0,
297-
medium = 500.0,
298-
low = 1000.0,
302+
high = 250.0,
303+
medium = 500.0,
304+
low = 1000.0,
299305
}
300306
```
301307

302308
#### PermissionStatus
303309

304310
```ts
305311
enum PermissionStatus {
306-
denied = 'denied',
307-
undetermined = 'undetermined',
308-
granted = 'granted',
312+
denied = 'denied',
313+
undetermined = 'undetermined',
314+
granted = 'granted',
309315
}
310316
```
311317

src/components/Waveform/Waveform.tsx

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ import {
4040

4141
export const Waveform = forwardRef<IWaveformRef, IWaveform>((props, ref) => {
4242
const {
43+
// The maximum number of candles set in the waveform. Once this limit is reached, the oldest candle will be removed as a new one is added to the waveform.
44+
maxCandlesToRender = 300,
4345
mode,
4446
path,
4547
volume = 3,
@@ -432,7 +434,18 @@ export const Waveform = forwardRef<IWaveformRef, IWaveform>((props, ref) => {
432434
result => {
433435
if (mode === 'live') {
434436
if (!isNil(result.currentDecibel)) {
435-
setWaveform(prev => [...prev, result.currentDecibel]);
437+
setWaveform((previousWaveform: number[]) => {
438+
// Add the new decibel to the waveform
439+
const updatedWaveform: number[] = [
440+
...previousWaveform,
441+
result.currentDecibel,
442+
];
443+
444+
// Limit the size of the waveform array to 'maxCandlesToRender'
445+
return updatedWaveform.length > maxCandlesToRender
446+
? updatedWaveform.slice(1)
447+
: updatedWaveform;
448+
});
436449
if (scrollRef.current) {
437450
scrollRef.current.scrollToEnd({ animated: true });
438451
}

src/components/Waveform/WaveformTypes.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ export interface StaticWaveform extends BaseWaveform {
3030

3131
export interface LiveWaveform extends BaseWaveform {
3232
mode: 'live';
33+
maxCandlesToRender?: number;
3334
onRecorderStateChange?: (recorderState: RecorderState) => void;
3435
}
3536

0 commit comments

Comments
 (0)