@yoliani/react-native-audio-waveform
Version:
A React Native component to show audio waveform with ease in react native application
389 lines (266 loc) • 20.1 kB
Markdown

# react-native-audio-waveform
[](https://www.npmjs.com/package/@simform_solutions/react-native-audio-waveform) [](https://www.npmtrends.com/@simform_solutions/react-native-audio-waveform) [](https://packagephobia.com/result?p=@simform_solutions/react-native-audio-waveform) [](https://www.android.com) [](https://developer.apple.com/ios) [](https://opensource.org/licenses/MIT)
---
A React Native package featuring native modules for generating and rendering audio waveforms. Designed to efficiently produce visual representations for pre-recorded audio files and dynamically draw waveforms in real-time during audio recording within React Native applications.
---
## 🎬 Preview
| Audio Playback Waveform | Audio Record Waveform | Audio Waveform with Speed |
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| <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> |
## Quick Access
- [Installation](#installation)
- [Usage and Examples](#usage)
- [Properties](#properties)
- [Example Code](#example)
- [License](#license)
## Getting Started 🔧
Here's how to get started with react-native-audio-waveform in your React Native project:
### Installation
##### 1. Install the package
```sh
npm install @simform_solutions/react-native-audio-waveform react-native-gesture-handler
```
###### --- or ---
```sh
yarn add @simform_solutions/react-native-audio-waveform react-native-gesture-handler
```
##### 2. Install CocoaPods in the iOS project
```bash
npx pod-install
```
##### Know more about [react-native-gesture-handler](https://www.npmjs.com/package/react-native-gesture-handler)
##### 3. Add audio recording permissions
##### iOS
If you want to use recorder features in iOS, you have to add **NSMicrophoneUsageDescription** permission in info.plist and add a description based on your use case.
Here is a sample for info.plist permission and a description.
```
<key>NSMicrophoneUsageDescription</key>
<string>Needed permission to record audio</string>
```
##### Android
If you want to use recorder features in Android, you have to add **RECORD_AUDIO** permission in AndroidManifest.xml.
```xml
<uses-permission android:name="android.permission.RECORD_AUDIO" />
```
### Usage
#### 1. Static waveform
When you want to show a waveform for a pre-existing audio file, you need to use `static` mode for the waveform. We have provided type safety for forward ref so that if you pass the `static` mode then you can only access methods which are available for static mode other methods will reject promise.
Check the example below for more information.
```tsx
import {
Waveform,
type IWaveformRef,
} from '@simform_solutions/react-native-audio-waveform';
const path = ''; // path to the audio file for which you want to show waveform
const ref = useRef<IWaveformRef>(null);
<Waveform
mode="static"
ref={ref}
path={item}
candleSpace={2}
candleWidth={4}
scrubColor="white"
onPlayerStateChange={playerState => console.log(playerState)}
onPanStateChange={isMoving => console.log(isMoving)}
/>;
```
#### 2. Live recording waveform
When you want to record audio and show a waveform for that recording, you need to create a waveform with `live` mode. Same as `static` mode, we have safety for ref methods.
Check the example below for more information.
```tsx
import {
Waveform,
type IWaveformRef,
} from '@simform_solutions/react-native-audio-waveform';
const ref = useRef<IWaveformRef>(null);
<Waveform
mode="live"
ref={ref}
candleSpace={2}
candleWidth={4}
onRecorderStateChange={recorderState => console.log(recorderState)}
/>;
```
You can check out the full example at [Example](./example/src/App.tsx).
---
## Properties
| **Props** | **Default** | **Static Mode** | **Live Mode** | **Type** | **Description** |
| ------------------------------ | ----------- | --------------- | ------------- | ---------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| mode\* | - | ✅ | ✅ | 'live' or 'static' | Type of waveform. It can be either `static` for the resource file or `live` if you want to record audio |
| 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. |
| path\* | - | ✅ | ❌ | string | Used for `static` type. It is the resource path of an audio source file. |
| 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 |
| candleSpace | 2 | ✅ | ✅ | number | Space between two candlesticks of waveform |
| candleWidth | 5 | ✅ | ✅ | number | Width of single candlestick of waveform |
| candleHeightScale | 3 | ✅ | ✅ | number | Scaling height of candlestick of waveform |
| maxCandlesToRender | 300 | ❌ | ✅ | number | Number of candlestick in waveform |
| containerStyle | - | ✅ | ✅ | `StyleProp<ViewStyle>` | style of the container |
| waveColor | #545454 | ✅ | ✅ | string | color of candlestick of waveform |
| scrubColor | #7b7b7b | ✅ | ❌ | string | color of candlestick of waveform which has played |
| onPlayerStateChange | - | ✅ | ❌ | ( playerState : PlayerState ) => void | callback function, which returns player state whenever player state changes. |
| onPanStateChange | - | ✅ | ❌ | ( panMoving : boolean ) => void | callback function which returns boolean indicating whether audio seeking is active or not. |
| onRecorderStateChange | - | ❌ | ✅ | ( recorderState : RecorderState ) => void | callback function which returns the recorder state whenever the recorder state changes. Check RecorderState for more details |
| onCurrentProgressChange | - | ✅ | ❌ | ( currentProgress : number, songDuration: number ) => void | callback function, which returns current progress of audio and total song duration. |
| onChangeWaveformLoadState | - | ✅ | ❌ | ( state : boolean ) => void | callback function which returns the loading state of waveform candlestick. |
| onError | - | ✅ | ❌ | ( error : Error ) => void | callback function which returns the error for static audio waveform |
| showsHorizontalScrollIndicator | false | ❌ | ✅ | boolean | whether to show scroll indicator when live waveform is being recorded and total width is more than parent view width |
##### Know more about [ViewStyle](https://reactnative.dev/docs/view-style-props), [PlayerState](#playerstate), and [RecorderState](#recorderstate)
---
#### IWaveformRef Methods
#### For Static mode
#### startPlayer()
```ts
startPlayer({
finishMode?: FinishMode;
}): Promise<boolean>
```
starts playing the audio with the specified finish mode. If finish mode is not specified, it will default to `FinishMode.stop`.
It returns a boolean indicating whether playback is started.
#### stopPlayer()
```ts
stopPlayer(): Promise<boolean>
```
It returns a boolean indicating whether playback is stopped.
#### pausePlayer()
```ts
pausePlayer(): Promise<boolean>
```
It returns a boolean indicating whether playback is paused.
#### resumePlayer()
```ts
resumePlayer(): Promise<boolean>
```
It returns a boolean indicating whether playback is resumed again.
#### stopAllPlayers()
```ts
stopAllPlayers(): Promise<boolean>
```
Stops all the players at once and frees their native resources. Useful on unmount!
It returns a boolean indicating that all players were stopped.
#### stopAllWaveFormExtractors()
```ts
stopAllWaveFormExtractors(): Promise<boolean>
```
Stops all the extractors used to build the audio waveform and frees its native resource. Useful on unmount!
It returns a boolean indicating that all extractors were stopped.
#### stopPlayersAndExtractors()
```ts
stopPlayersAndExtractors(): Promise<[boolean, boolean]>
```
Combined the `stopAllWaveFormExtractors` and `stopAllPlayers` in one call to free up the maximum possible resources. Very useful on unmount!
It returns an array of two booleans indicating if all players and all waveform extractors were stopped.
#### For Live mode
#### startRecord()
```ts
startRecord({
encoder:number;
sampleRate: number;
bitRate: number;
fileNameFormat: string;
useLegacy: boolean;
updateFrequency?: UpdateFrequency;
}): Promise<boolean>
```
Start a new audio recording with the given parameters. It will return whether the recording was started or not.
Check [UpdateFrequency](#updatefrequency) to know more.
> Note: Before starting the recording, the user must allow **NSMicrophoneUsageDescription** for iOS. You can check the permissions by using **_checkHasAudioRecorderPermission_** from **_useAudioPermission_**. Check [useAudioPermission](#useaudiopermission-hook) to know more about various methods.
#### stopRecord()
```ts
stopRecord(): Promise<string>
```
It returns a string representing the current recorded audio file path.
#### pauseRecord()
```ts
pauseRecord(): Promise<boolean>
```
It returns a boolean indicating whether the recording is paused.
#### resumeRecord()
```ts
resumeRecord(): Promise<boolean>
```
It returns a boolean indicating whether the recording is resumed again.
### useAudioPermission hook
By using this hook, you can check and ask for permission from the user for **NSMicrophoneUsageDescription** permission.
#### checkHasAudioRecorderPermission()
This method checks whether the user has permission to use a microphone for recording new audio. It will return [PermissionStatus](#permissionstatus).
You can use this method as shown below:
```ts
const hasPermission: PermissionStatus = await checkHasAudioRecorderPermission();
```
#### getAudioRecorderPermission()
This method lets you ask for **NSMicrophoneUsageDescription** permission from the user. It will return PermissionStatus.
By combining this with checkHasAudioRecorderPermission you can ask for permission and start recording if permission is granted.
Check out the following example:
```ts
let hasPermission = await checkHasAudioRecorderPermission();
if (hasPermission === PermissionStatus.granted) {
startRecording();
} else if (hasPermission === PermissionStatus.undetermined) {
const permissionStatus = await getAudioRecorderPermission();
if (permissionStatus === PermissionStatus.granted) {
startRecording();
}
} else {
Linking.openSettings();
}
```
---
#### PlayerState
```ts
enum PlayerState {
playing = 'playing',
paused = 'paused',
stopped = 'stopped',
}
```
#### RecorderState
```ts
enum RecorderState {
recording = 'recording',
paused = 'paused',
stopped = 'stopped',
}
```
#### UpdateFrequency
```ts
// Update frequency in milliseconds
enum UpdateFrequency {
high = 250.0,
medium = 500.0,
low = 1000.0,
}
```
#### PermissionStatus
```ts
enum PermissionStatus {
denied = 'denied',
undetermined = 'undetermined',
granted = 'granted',
}
```
---
## Example
You can check out the example app for react-native-audio-waveform in [Example](./example/src/App.tsx)
To use example app you need to first run below command
```bash
cd example && npx react-native-asset
```
> Note: If link-assets-manifest.json file already exists then make sure to delete that before running npx react-native-asset command.
This command will add our example audio sample files to the iOS bundle so that we can access them inside the iOS app.
```sh
yarn
yarn example ios // For iOS
yarn example android // For Android
```
## Find this library useful? ❤️
Support it by joining [stargazers](https://github.com/SimformSolutionsPvtLtd/react-native-audio-waveform/stargazers) for this repository.⭐
## Bugs / Feature requests / Feedback
For bugs, feature requests, and discussion, please use [GitHub Issues](https://github.com/SimformSolutionsPvtLtd/react-native-audio-waveform/issues/new?labels=bug&late=BUG_REPORT.md&title=%5BBUG%5D%3A), [GitHub New Feature](https://github.com/SimformSolutionsPvtLtd/react-native-audio-waveform/issues/new?labels=enhancement&late=FEATURE_REQUEST.md&title=%5BFEATURE%5D%3A), [GitHub Feedback](https://github.com/SimformSolutionsPvtLtd/react-native-audio-waveform/issues/new?labels=enhancement&late=FEATURE_REQUEST.md&title=%5BFEEDBACK%5D%3A)
## 🤝 How to Contribute
We'd love to have you improve this library or fix a problem 💪
Check out our [Contributing Guide](CONTRIBUTING.md) for ideas on contributing.
## Awesome Mobile Libraries
- Check out our other [available awesome mobile libraries](https://github.com/SimformSolutionsPvtLtd/Awesome-Mobile-Libraries)
## License
- [MIT License](./LICENSE)