Home » Blogs » How to Play, Pause, Resume Audio in React Native Expo

How to Play, Pause, Resume Audio in React Native Expo

  • by
How to play audio using expo react native

In the previous post I showed you how you can read audio files from inside a device using expo-av api. Now in this post we will see how we can play audios from a remote api link. Also, this solution works for the audios that you have read from your device.

If you guys don’t know, we’ve already covered how to build a local audio player using Expo React Native. You can watch the entire video inside YouTube. Or you can only check out this video where you will learn how to play audio from your device.

Ok, without further ado let’s create a new project using expo-cli.

Initializing Audio Player

$ expo init MyAudioPlayer

Now we have our project initialized so let’s create some components to control our audio and we will write entire code inside our App.js.

Don’t be so excited we will not create any fancy UI.

export default function App() {
 return (
     <View style={{ flex: 1, padding: 50, backgroundColor: '#fff' }}>
        <Text style={{ fontWeight: 'bold', fontSize: 18, marginBottom: 15 }}>
          {audio.filename}
        </Text>
        <Ionicons
          style={{
            alignSelf: 'center',
            backgroundColor: 'gray',
            padding: 10,
            borderRadius: 50,
          }}
          name='play'
          size={24}
          color='white'
        />
      </View>
  );
}

Here inside this code. We are adding a Text component to render the title of our audio and we are rendering an icon to control our audio file which we will be fetching remotely.

Also we have some View components and general styling inside it to give our components a nice look.

And you can see we are using Ionicons component and audio.filename. So, let’s import Ionicons from @expo/vector-icons. You don’t need to install anything to use expo-vector-icons, it is already there.

import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { Ionicons } from '@expo/vector-icons';

Now your top of the App.js file should look like this. Also add this audio object outside of your App component.

const audio = {
  filename: 'My Awesome Audio',
  uri: 'https://file-examples-com.github.io/uploads/2017/11/file_example_MP3_700KB.mp3',
};

And now if you run your project, you should see something like this.

audio_player_app_first_look

API to Work With Audio & Video

Now our app looks fine let’s add expo-av inside our project to play, pause and resume the audio.

expo install expo-av

After this we need to add some states inside our audio player project.

const [isPlaying, setIsPlaying] = useState(false);
const [playbackObject, setPlaybackObject] = useState(null);
const [playbackStatus, setPlaybackStatus] = useState(null);

At first we have isPlaying state which we will use to update our UI and we have playbackObject and playbackStatus status states as well. We will use them to play, pause and resume our audio.

Let’s import Audio from expo-av

import { Audio } from 'expo-av';

Now we need to instantiate our playbackObject using Audio.Sound and we will do that inside useEffect hook.

useEffect(() => {
 if (playbackObject === null) {
    setPlaybackObject(new Audio.Sound());
 }
}, []);

Here we are checking if playbackObject is null then we want to update our playbackObject to new Audio.Sound(). Now we can use playbackObject to control our audio, whether it’s coming from remote api or from our device.

Handling Play, Pause & Resume

Let’s add some code to our Ionicons so that we can control our audio and update UI at the same time.

...
return (
...
        <Ionicons
          ...

          name={isPlaying ? 'pause' : 'play'}
          onPress={handleAudioPlayPause}
        />
...
  );

Here inside this code as you can see we are just updating the name prop and adding onPress prop. With this now our icon will change according to isPlaying state and we will create that handleAudioPlayPause method to play, pause and resume the audio.

Let’s create handleAudioPlayPause method.

const handleAudioPlayPause = async () => {
    if (playbackObject !== null && playbackStatus === null) {
      const status = await playbackObject.loadAsync(
        { uri: audio.uri },
        { shouldPlay: true }
      );
      console.log(status)
    }
};

As you can see inside this handleAudioPlayPause method first we are checking if playbackObject is null and playbackStatus is null. If this condition matches, it means our app is running for the first time. So, now we want to play our audio.

To play any audio with expo-av we can use that playbackObject returned from the new Audio.Sound() object. So, now we can use the playbackObject.loadAsync method.

Also you can see we are logging the returned status from that playbackObject.loadAsync method. If you see inside your terminal you will see a long object with some interesting values. Like audio url, isPlaying, isPaused, isBuffering and bunch of other values.

First we need to pass the audio uri that we want to play and as the second argument we can pass the status object. Like here we are passing shouldPlay to true. Now if you run your app and tap on that play icon your audio should play.

But you can not pause or stop you audio. For that first you need to add these codes inside your if block

setIsPlaying(true);
return setPlaybackStatus(status);

Now your if block should look like this.

if (playbackObject !== null && playbackStatus === null) {
   const status = await playbackObject.loadAsync(
        { uri: audio.uri },
        { shouldPlay: true }
   );
   setIsPlaying(true);
   return setPlaybackStatus(status);
}

This will update isPlaying and playbackStatus states inside our app. Let’s add some more code which will help us to pause and resume our audio.

const handleAudioPlayPause = async () => {
    ...
    // It will pause our audio
    if (playbackStatus.isPlaying) {
      const status = await playbackObject.pauseAsync();
      setIsPlaying(false);
      return setPlaybackStatus(status);
    }

    // It will resume our audio
    if (!playbackStatus.isPlaying) {
      const status = await playbackObject.playAsync();
      setIsPlaying(true);
      return setPlaybackStatus(status);
    }
  };

If you see these if statements then they are self explanatory. First we are checking if playbackStatus.isPlaying and we can do this because before that we updated our playbackStatus when we first played our audio.

If this condition matches it means our audio is already playing. So, we can use playbackObject.pauseAsync method to pause our audio. After that we are updating our isPlaying and playbackStatus sates.

At last we are checking if our playbackStatus is not playing it means our audio is in pause state. So, now we want to resume our audio.

You can check out the complete project here.

Leave a Reply

Your email address will not be published. Required fields are marked *