This is a premium alert message you can set from Layout! Get Now!

How to add audio wave forms to your Flutter app

0

When adding a feature to record audio in your app, it’s usually a good idea to show some sort of visual representation to the user that audio is being recorded. For example, you could add a timer to the UI that informs the user how long the audio has been recording. But, if you really want to give your users a clean visual experience, wave forms could be a game changer.

In this article, we’ll learn how to create simple wave forms when you’re either recording audio or playing an audio file in Flutter. Let’s get started!

Table of contents

What are audio wave forms, and why do we need them?

Put simply, audio wave forms are graphs that represent how loud different parts of the audio are. The x-axis represents time, and the y-axis represents amplitude. So, the higher the waves, the louder the sound is. Similarly, lower waves or flatter waves represent softer areas in the audio.

Wave forms let the user know if they’re speaking softly or loudly so that they can adjust their volume accordingly. For example, a user could be trying to speak softly, but it could be too soft for the microphone to pick up. By looking at the graph, they could easily decide to raise their volume for the microphone.

Wave forms also come in handy when you want to play or stream an audio file. For example, when doctors listen to the sound relayed by a stethoscope, it would only make the experience better to see a graph on the screen showing the sound patterns.

In this tutorial, we’ll build a feature like in the images below for a Flutter app:

Flutter Wave Forms Recorder
Wave forms in recorder
Wave Forms Player
Wave forms in player

Setting up our Flutter app

We’ll start by adding the required dependencies and permissions, including the Audio Waveforms package:

flutter pub add audio_waveforms

Import the package in our main.dart file:

import 'package:audio_waveforms/audio_waveforms.dart';

Now, add the permission to record to the Android manifest:

<uses-permission android:name="android.permission.RECORD_AUDIO" />

Creating the waveforms

The AudioWaveforms widget will create our wave forms. But, before we can continue, we need to create a recorderController that will be passed to our AudioWaveforms widget. Let’s declare a RecordController in our state with the following code:

late final RecorderController recorderController;

Then, to initialize the controller, enter the commands below:

void _initialiseController() {
 recorderController = RecorderController()
      ..androidEncoder = AndroidEncoder.aac
      ..androidOutputFormat = AndroidOutputFormat.mpeg4
      ..iosEncoder = IosEncoder.kAudioFormatMPEG4AAC
      ..sampleRate = 16000;
}

We can change the sample rate and encoders according to our needs. We’ll call this method in our initState:

void initState() {
  super.initState();
  _initialiseController();
}

Now, using the controller to record audio and display a waveform is as simple as adding the AudioWaveform widget to our widget tree as follows:

AudioWaveforms(
  size: Size(MediaQuery.of(context).size.width, 200.0),
  recorderController: recorderController,
),


void _startRecording() async {
  await recorderController.record(path);
  // update state here to, for eample, change the button's state
}

To start the recording, we’ll call the method above on the click of a button:

IconButton(
          icon: Icon(Icons.mic),
          tooltip: 'Start recording',
          onPressed: _startRecording
)

We’ll stop the recording with the following code:

final path = await recorderController.stop();

Stopping the recorder will return the path of the file where the recording is saved.

Customizing the waveforms

We already saw that we have control over the sample rate and the encoding in RecordController.
AudioWaveforms also allows us to change the style of the waves, including aspects like size, waveStyle, color, padding, and margin:

AudioWaveforms(
              enableGesture: true,
              size: Size(MediaQuery.of(context).size.width / 2, 50),
              recorderCAudioWaveforms(
              enableGesture: true,
              size: Size(MediaQuery.of(context).size.width / 2, 50),
              recorderController: recorderController,
              waveStyle: const WaveStyle(
                waveColor: Colors.white,
                extendWaveform: true,
                showMiddleLine: false,
              ),
              decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(12.0),
                color: const Color(0xFF1E1B26),
              ),
              padding: const EdgeInsets.only(left: 18),
              margin: const EdgeInsets.symmetric(horizontal: 15),
            )

We can also apply color gradients to the waves:

waveStyle: WaveStyle(
   gradient: ui.Gradient.linear(
    const Offset(70, 50),
    Offset(MediaQuery.of(context).size.width / 2, 0),
    [Colors.red, Colors.green],
   ),
  )

Playing audio

Now, we’ll learn how to play audio files and generate wave forms for them. The main differences here from the previous example for recording the audio are:

  1. We’ll create a PlayerController instead of a RecordController
  2. We’ll use AudioFileWaveforms instead of AudioWaveforms

First, we’ll run the same code as before, replacing RecordController with PlayerController:

late final PlayerController playerController;

However, this time, we’re making the following alteration:

void _initialiseController() {
 playerController = PlayerController();
}

Pass this playerController to the AudioFileWaveforms widget in your widget tree:

AudioFileWaveforms(
 size: Size(MediaQuery.of(context).size.width, 100.0),
 playerController: playerController,
)

We need to provide the path of the audio file to the controller. You can grab the path of the file any way you like. We’ll use path_provider for this task. Add path_provider to your pubspec.yaml, then at the top of your main.dart, add the code below:

import 'package:path_provider/path_provider.dart';

You could store the path in a variable called path:

String? path;
late Directory directory;

void initState() {
  super.initState();
  _initialiseController();
  directory = await getApplicationDocumentsDirectory();
  path = "${directory.path}/test_audio.aac";
  playerController.preparePlayer(path);
}

Notice that we also call the preparePlayer method on our controller by providing the path to our audio file. We can start and stop the player the same way we did with recordController:

await playerController.startPlayer();
await playerController.stopPlayer();


void _playandPause() async {
  playerController.playerState == PlayerState.playing
  ? await playerController.pausePlayer()
  : await playerController.startPlayer(finishMode: FinishMode.loop);
}

Now, we can call the _playandPause method on a button click. We also provide a finishMode to the startPlayer method to loop the audio and the waveform when it ends. You could also add other options to pause the waveform or stop it with FinishMode.pause and FinishMode.stop, respectively.

We can also add the ability to seek the audio using gestures on the wave form:

AudioFileWaveforms(
 enableSeekGesture: true,
)

We’ll style our wave forms as follows:

AudioFileWaveforms(
 size: Size(MediaQuery.of(context).size.width / 2, 70),
              playerController: playerController,
              density: 1.5,
              playerWaveStyle: const PlayerWaveStyle(
                scaleFactor: 0.8,
                fixedWaveColor: Colors.white30,
                liveWaveColor: Colors.white,
                waveCap: StrokeCap.butt,
              ),
)

Notice that we’re using PlayerWaveStyle to provide the styles instead of WaveStyle, which is better suited for recorders.

Disposing the controllers

Before finishing up, it’s important to dispose of the controllers that we used to record and play audio. In the dispose method, we’ll add the following code:

 @override
void dispose() {
  super.dispose();
  recorderController.dispose();
  playerController.dispose();
}

Conclusion

We just saw how easy it is to create an audio player and display wave forms in Flutter using the Audio Waveforms package. Wave forms are a dynamic visual representation of the volume of sound; they provide feedback to the user of how well the microphone is capturing their spoken words so that they can increase or decrease their volume accordingly.

We learned how to add customizations to our wave forms so they suit our visual preferences, start and stop the recording, and finally, dispose of the controllers for recording and playing audio. I hope you enjoyed this tutorial; be sure to leave a comment if you have any questions.

The post How to add audio wave forms to your Flutter app appeared first on LogRocket Blog.



from LogRocket Blog https://ift.tt/m7wvfyo
Gain $200 in a week
via Read more

Post a Comment

0 Comments
* Please Don't Spam Here. All the Comments are Reviewed by Admin.
Post a Comment

Search This Blog

To Top