Как приостановить предыдущий звук при воспроизведении нового звука в React?

Когда я нажимаю на значок «PlayCircleFilled», звук воспроизводится идеально, проблема в том, что если пользователь нажимает на разные значки «PlayCircleFilled», все звуки воспроизводятся одновременно.

Чего я хочу добиться, так это остановить воспроизведение звука, когда пользователь нажимает на новый значок «PlayCircleFilled», чтобы одновременно воспроизводился только один звук, воспроизводится звук, на который был нажат последний клик.

Мой код выглядит следующим образом:

const Client = (props) => {

  const {
    sentence,
    typeConversation
  } = props;

  const [audioUrl, setAudioUrl] = useState(null);
  const audioRef = useRef(null);

  const handleAudioPlay = (url) => {
    if (audioRef.current) {
      audioRef.current.pause();
      audioRef.current.currentTime = 0;
    }
    setAudioUrl(url);
  };

  const handleAudioEnded = () => {
    setAudioUrl(null); 
  };

  const renderTextWithAudioPlayer = (text) => {
    const combinedRegex = /(https?://[^\s]+)|(\[Audio\])/g;
    const parts = text.split(combinedRegex).filter(part => part !== undefined && part !== "");

    let renderedElements = [];

    parts.forEach((part, index) => {
      if (/https?://[^\s]+/.test(part)) {
        const fileExtension = part.split('.').pop().toLowerCase();
        if (fileExtension === 'wav' || fileExtension === 'mp3' || fileExtension === 'ogg') {
          renderedElements.push(
            <Tooltip key = {index} placement = "bottom" title = "Reproducir audio">
              <PlayCircleFilled className = "play-audio-icon" onClick = {() => handleAudioPlay(part)} />
            </Tooltip>
          );
        } else {
          renderedElements.push(
            <a key = {index} href = {part} target = "_blank" rel = "noopener noreferrer">
              {part}
            </a>
          );
        }
      } else if (/\[Audio\]/.test(part)) {
        renderedElements.push(<AudioFilled className = "play-audio-icon" key = {index} />);
      } else {
        renderedElements.push(<span key = {index} dangerouslySetInnerHTML = {{ __html: part }} />);
      }
    });
    return renderedElements;
  };

  return(
    <div className = "chat-message" id = {sentence.id}>
      <div className = "chat-message__text">
      {
        typeConversation == 'audio' ?
        <h6 className = "chat-message__title chat-message__title--client">
          Cliente | {sentence.start_time}
        </h6>
        :
        <h6 className = "chat-message__title chat-message__title--client">
          Cliente | {sentence.date} {sentence.time}
        </h6>
      }
        <p>
          {renderTextWithAudioPlayer(sentence.text)}
        </p>
        {audioUrl && (
          <audio controls autoPlay ref = {audioRef} onEnded = {handleAudioEnded} style = {{ display: 'none' }}>
            <source src = {audioUrl} type = "audio/mpeg" />
            Su navegador no admite la reproducción de audio.
          </audio>
        )}
      </div>
    </div>
  );
}

export default Client;

Большое спасибо за ваше время и надеюсь, что вы сможете мне помочь!

Я попробовал использовать useRef и document.querySelector("audio"), но это не сработало.

Francisco.js 30.04.2024 16:03
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
1
1
59
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ведите список ссылок для каждого рендеринга <audio> и приостанавливайте остальные, когда один воспроизводится.

Посмотреть полный пример

function AudioPlayers({ urls }) {
  const refs = []   
  const newRef = () => refs[refs.push(createRef()) - 1]
  const onPlay = event => {
    refs.forEach(ref => (ref.current !== event.target) && ref.current.pause())
  }

  return urls.map(src => <audio controls {...{ref: newRef(), src, onPlay}} />)
}

Можете ли вы помочь мне адаптировать его к моему коду?

Francisco.js 07.05.2024 15:07

Я просто добавил эту функцию в тег <audio>, и она работала правильно: const onPlay = (event) => { const audioElements = document.querySelectorAll('audio'); audioElements.forEach(audio => { if (audio !== event.target) { audio.pause(); } }); };

Francisco.js 07.05.2024 17:59

Другие вопросы по теме