5

I've followed the other posts that have asked similar questions, but they have not provided a solution.

I'm not able to pause audio in my React Hook.

This is my react hook:

import React, { useState } from "react";

export default (App = props => {
  const [audioStatus, changeAudioStatus] = useState(false);
  const audio = new Audio(
    "https://mcdn.podbean.com/mf/web/xm5ngf/The_Challenge_Chronicles_-_Episode_48_7ys6e.mp3"
  );
  audio.load();

  const startAudio = () => {
    audio.play();

    changeAudioStatus(true);
  };

  const pauseAudio = () => {
    console.log("here");
    audio.pause();
    changeAudioStatus(false);
  };

  return (
    <>
      {audioStatus ? (
        <button onClick={pauseAudio}>pause</button>
      ) : (
        <button onClick={startAudio}>start</button>
      )}
    </>
  );

I've also created a sandbox: https://codesandbox.io/s/great-gagarin-v0vi1

Abhishek Bhagate
  • 5,583
  • 3
  • 15
  • 32
schoenbl
  • 663
  • 2
  • 14
  • 29

5 Answers5

12

You can use the audio tag, and pass a ref to react, so that it will know what element is being used.

working example

export default (App = props => {
  const [audioStatus, changeAudioStatus] = useState(false);
  const myRef = useRef();

  const startAudio = () => {
    myRef.current.play();

    changeAudioStatus(true);
  };

  const pauseAudio = () => {
    console.log("here");
    myRef.current.pause();
    changeAudioStatus(false);
  };

  return (
    <>
      <audio
        ref={myRef}
        src="https://mcdn.podbean.com/mf/web/xm5ngf/The_Challenge_Chronicles_-_Episode_48_7ys6e.mp3"
      />
      {audioStatus ? (
        <button onClick={pauseAudio}>pause</button>
      ) : (
        <button onClick={startAudio}>start</button>
      )}
    </>
  );
});
k.s.
  • 2,964
  • 1
  • 25
  • 27
6

I had a similar problem as well and solved it by changing

const audio = new Audio(...)

to

const [audio, setAudio] = useState( new Audio(...) )

I believe that by putting the audio into the state we prevent React from refreshing the audio value on each rerender, and thus the reference problem is solved. I might, however, be wrong with the conclusion; please correct me if I'm wrong. In any case, this works.

ZenBerry
  • 217
  • 2
  • 12
  • 1
    Can you explain with complete code, it shows an error – Shubham Singhvi Jan 05 '22 at 20:39
  • Could you please specify the error if the question is still relevant? The complete code of mine is a huge mess haha, but if I knew more details about the error, I would try to solve it. My apologies for the delayed answer! – ZenBerry Jul 14 '22 at 06:28
  • Just in case, instead of '...' there has to be a URL of the audio file like this: const [audio, setAudio] = useState( new Audio('your-website.com/audio.wav') ) (I know you know this, but you might have been extremely tired and just copy my code to see what will happen haha) – ZenBerry Jul 14 '22 at 06:33
1

Try to initialize the audio outside of the React component.

const audio = new Audio(...)

const MyComponent=(props)=>{
  const [isMusic, isMusicSet] = React.useState(false);

  const toggleMusic = () => {
    const isMusicToggle = !isMusic;
    if (isMusicToggle) {
      audio.play();
    } else {
      audio.pause();
    }
    isMusicSet(isMusicToggle);
  };
}
Dragos UniqQum
  • 388
  • 4
  • 12
0

const audio = new Audio(...)

to

const [audio, setAudio] = useState( new Audio(...) )

This solution worked for me. I was able to get rid of my ref.

0

Just pass your audio element into useRef to retain it throughout the component lifecycle

  const audio = useRef(new Audio('path/to/audio/file')).current

  audio.load();

  const startAudio = () => {
    audio.play();

    changeAudioStatus(true);
  };

    const pauseAudio = () => {
    console.log("here");
    audio.pause();
    changeAudioStatus(false);
  };
Jordan Aasen
  • 73
  • 1
  • 9