How do I do so that when one audio is activated, the other one that is playing is deactivated and restarted

How do I do so that when one audio is activated, the other one that is playing is deactivated and restarted.

There’s some suggestions how to solve that here:

No, it did not help me, because I am working with functional components of reactjs. Thanks the same.

It’s impossible to help you unless you provide more information (most of all, the relevant parts of your actual code). Are you using the HTML5 audio tag? Some library?

I’m doing the drum machine project. And how I said above is in reactjs. I manage to get it to play, but I want when I load another melody, the previous one will stop.

export default function Buttons({ name, sonido, id, onIniciar }){
    const [play, setPlay] = useState(true);
    const [temas, setTemas] = useState([audio, audio2, audio3, audio4, audio5, audio6, 
        audio7, audio8, audio9]);
    const [song, setSong] = useState('')
        
    const handlePlay = () =>{
        var audio = document.getElementById(id);
        if(play) {
            audio.play()
        }else{
            audio.pause()
            audio.currentTime = 0;
        } 
        setPlay(!play);

    }
    return (
        <div id="drum-machine">
            <button className='drum-pad' onClick={handlePlay}>{name}
                <ReactAudioPlayer
                    src={audio}
                    controls    
                    /> 
            </button>
            
        </div>
    )
}

I’m confused, is that just the code for one button or for the drumpad (all nine buttons)? I would’ve expected to see a .map function that renders an array of buttons, not just one. Just seeing this part of the code, it looks like you only have one button and one audio element?

They are two components. The father multiplies the batteries by 9, I don’t know if I faced it well. I pass you the two components.

export default function Buttons({ name, sonido, id, onIniciar }){
    const [play, setPlay] = useState(true);
    const [temas, setTemas] = useState([audio, audio2, audio3, audio4, audio5, audio6, 
        audio7, audio8, audio9]);
    const [song, setSong] = useState('')
        
    const handlePlay = () =>{
        var audio = document.getElementById(id);
        if(play) {
            audio.play()
        }else{
            audio.pause()
            audio.currentTime = 0;
        } 
        setPlay(!play);

    }
    return (
        <div id="drum-machine">
            <button className='drum-pad' onClick={handlePlay}>{name}
                <ReactAudioPlayer
                    src={audio}
                    controls    
                    /> 
            </button>
            
        </div>
    )
}

export default function DrumMachine(){
    
    

    return(
        <div id="drum-machine">
            <Buttons name='Q' sonido={audio} id= 'Q' />
            
            <Buttons name='W' sonido={audio2} id='W' />
            
            <Buttons name='E' sonido={audio3} id='E' />
            <Buttons name='A' sonido={audio3} id='A' />
            <Buttons name='S' sonido={audio3} id='S' />
            <Buttons name='D' sonido={audio3} id='D' />
            <Buttons name='Z' sonido={audio3} id='Z' />
            <Buttons name='X' sonido={audio3} id='X' />
            <Buttons name='C' sonido={audio3} id='C' />
            
        </div>
    )
}

Thanks, that’s better to understand.

So I’ve played with your code a bit, I’ve added comments:
(note that I removed the controls from <ReactAudioPlayer />, because otherwise your click handler wouldn’t fire)

export default function Buttons({ name, sonido, id, onIniciar }){
    // const [play, setPlay] = useState(true); // not needed
    const [song, setSong] = useState('')

    // pass the event to the handler
    const handlePlay = e =>{

        // get all audio elements and stop them all
        const allAudios = document.querySelectorAll('audio');
        allAudios.forEach(audioEl => {
            audioEl.pause()
            audioEl.currentTime=0;
        })

        // get the clicked audio element and play
        const thisAudio = e.target.querySelector('audio');
        thisAudio.play()
    }

    return (
        <div className="drum-button">
            <button className='drum-pad' onClick={handlePlay}>{name}
                <ReactAudioPlayer
                    src={sonido}
                />
            </button>
        </div>
    )
}

The above code works, but maybe a better solution would be to let the <DrumMachine /> component keep track of which audio should play and which shouldn’t. Then pass a Boolean isPlaying down to each <Button />. If the button receives false, let the button stop the audio.

Thank you very much, I was stuck in this problem for several days.
I would like to use your knowledge to solve another problem that I have.
It’s with the markdown previewer challenge. I have developed it, but when I press the ‘enter’ key in #editor I want it to also do a line break in #previewer.
I pass you code. It currently does not do that. I clarify that I already asked, but nobody could tell me, that’s why I take this opportunity.

import { useState, useEffect } from 'react';

import './index.css'

const App = () => {
   const [data, setData] = useState('');
   
   const onChange = (e) => {
    setData(e.target.value)
   }

const onKeyPressHandler = (event) => {
    if (event.keyCode === 13) {
        
    }
  }
  
return(
    
<div id="editor">
    
    <div>
        <h3>Editor</h3>
        <textarea value={data} onChange={onChange} onKeyDown={onKeyPressHandler} style={{
            width: '100%'
        }}></textarea>
        
    </div>

    <div>
            <h3>Previewer</h3>
            <div>{data}</div>
        
    </div>
    
</div>

)};

export default App;

I’m not familiar with that challenge, but I’ve read through the description and looked at the example project. They’re using a library that does all the hard work: https://marked.js.org/, and adding line breaks seems to be just a matter of configuration. I could imagine that coding it manually (without library) would be quite a pain.

Sorry I can’t help more, maybe open another thread about it again (as this one’s title doesn’t fit).

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.