Воспроизведение звука в React - PullRequest
0 голосов
/ 30 сентября 2018

Как воспроизвести звук из аудио onClick на родительском элементе в React.Я не уверен, что это правильный путь.Кто-то предложил мне использовать ссылки, но каким образом?Где их поставить?На div, который охватывает аудио тег или сам аудио тег?Но когда я нажимаю, я нажимаю на div, а не на аудио тег.Итак, как воспроизвести звук из аудио, когда вы нажимаете на его родитель?Вот мой код:

import React from 'react';
import ReactDOM from 'react-dom';
import 'bootstrap/dist/css/bootstrap.min.css';
import './style.css';

class DrumMachine  extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            pressedKey: null,
            display: null,
            sliderVal: 50,
            volume: 0.5,
            mySwitch: true,
            mySwitchBox: true,
            prevVolume:  0.5,
            fancy: false,
        };
        this.handleClick = this.handleClick.bind(this);
        this.keyPress = this.keyPress.bind(this);
        this.handleVolume = this.handleVolume.bind(this);
        this.onOff = this.onOff.bind(this);
        this.fancyToggle = this.fancyToggle.bind(this);
        this.myRef = React.createRef();
        this.mySwitchOn = React.createRef();
        this.mySwitchOff = React.createRef();

        //Refs of audio elements.
        this.Q = React.createRef();
        this.W = React.createRef();
        this.E = React.createRef();
        this.A = React.createRef();
        this.S = React.createRef();
        this.D = React.createRef();
        this.Z = React.createRef();
        this.X = React.createRef();
        this.C = React.createRef();

        //Refs of divs who are parents of audio.
        this.H1 = React.createRef();
        this.H2 = React.createRef();
        this.H3 = React.createRef();
        this.H41 = React.createRef();
        this.H6 = React.createRef();
        this.Dsc_Oh = React.createRef();
        this.Kick_n_Hat = React.createRef();
        this.RP4_KICK_1 = React.createRef();
        this.Cev_H2 = React.createRef();

        this.myRange = React.createRef();

        this.sounds = {
            sound1: null,
            sound2: null,
            sound3: null,
            sound4: null,
            sound5: null,
            sound6: null,
            sound7: null,
            sound8: null,
            sound9: null
        };

        this.parents = {
            parent1: null,
            parent2: null,
            parent3: null,
            parent4: null,
            parent5: null,
            parent6: null,
            parent7: null,
            parent8: null,
            parent9: null
        };

        this.tracks = {
            track1: ["https://s3.amazonaws.com/freecodecamp/drums/Heater-1.mp3", "https://s3.amazonaws.com/freecodecamp/drums/Heater-2.mp3", "https://s3.amazonaws.com/freecodecamp/drums/Heater-3.mp3", "https://s3.amazonaws.com/freecodecamp/drums/Heater-4_1.mp3", "https://s3.amazonaws.com/freecodecamp/drums/Heater-6.mp3", "https://s3.amazonaws.com/freecodecamp/drums/Dsc_Oh.mp3", "https://s3.amazonaws.com/freecodecamp/drums/Kick_n_Hat.mp3", "https://s3.amazonaws.com/freecodecamp/drums/RP4_KICK_1.mp3", "https://s3.amazonaws.com/freecodecamp/drums/Cev_H2.mp3"],
            track2: ["https://s3.amazonaws.com/freecodecamp/drums/Chord_1.mp3", "https://s3.amazonaws.com/freecodecamp/drums/Chord_2.mp3", "https://s3.amazonaws.com/freecodecamp/drums/Chord_3.mp3", "https://s3.amazonaws.com/freecodecamp/drums/Give_us_a_light.mp3", "https://s3.amazonaws.com/freecodecamp/drums/Dry_Ohh.mp3", "https://s3.amazonaws.com/freecodecamp/drums/Bld_H1.mp3", "https://s3.amazonaws.com/freecodecamp/drums/punchy_kick_1.mp3", "https://s3.amazonaws.com/freecodecamp/drums/side_stick_1.mp3", "https://s3.amazonaws.com/freecodecamp/drums/Brk_Snr.mp3"],
        };

        this.Id = {
            id1: ["Heater-1", "Heater-2", "Heater-3", "Heater-4", "Clap", "Open-HH", "Kick n' Hat", "Kick", "Closed-HH"],
            id2: ["Chord-1", "Chord-2", "Chord-3", "Shaker", "Open-HH", "Closed-HH", "Punchy-Kick", "Side-Stick", "Snare"],
        };

    }

    componentDidMount() {
        window.addEventListener("keydown", this.keyPress);

        this.sounds = {
            sound1: ReactDOM.findDOMNode(this.Q.current),
            sound2: ReactDOM.findDOMNode(this.W.current),
            sound3: ReactDOM.findDOMNode(this.E.current),
            sound4: ReactDOM.findDOMNode(this.A.current),
            sound5: ReactDOM.findDOMNode(this.S.current),
            sound6: ReactDOM.findDOMNode(this.D.current),
            sound7: ReactDOM.findDOMNode(this.Z.current),
            sound8: ReactDOM.findDOMNode(this.X.current),
            sound9: ReactDOM.findDOMNode(this.C.current)
        };

        this.parents = {
            parent1: ReactDOM.findDOMNode(this.H1.current),
            parent2: ReactDOM.findDOMNode(this.H2.current),
            parent3: ReactDOM.findDOMNode(this.H3.current),
            parent4: ReactDOM.findDOMNode(this.H41.current),
            parent5: ReactDOM.findDOMNode(this.H6.current),
            parent6: ReactDOM.findDOMNode(this.Dsc_Oh.current),
            parent7: ReactDOM.findDOMNode(this.Kick_n_Hat.current),
            parent8: ReactDOM.findDOMNode(this.RP4_KICK_1.current),
            parent9: ReactDOM.findDOMNode(this.Cev_H2.current)
        };
    }

    componentWillUnmount() {
        window.removeEventListener("keydown", this.keyPress);

        this.sounds = {
            sound1: ReactDOM.findDOMNode(this.Q.current),
            sound2: ReactDOM.findDOMNode(this.W.current),
            sound3: ReactDOM.findDOMNode(this.E.current),
            sound4: ReactDOM.findDOMNode(this.A.current),
            sound5: ReactDOM.findDOMNode(this.S.current),
            sound6: ReactDOM.findDOMNode(this.D.current),
            sound7: ReactDOM.findDOMNode(this.Z.current),
            sound8: ReactDOM.findDOMNode(this.X.current),
            sound9: ReactDOM.findDOMNode(this.C.current)
        };

        this.parents = {
            parent1: ReactDOM.findDOMNode(this.H1.current).id,
            parent2: ReactDOM.findDOMNode(this.H2.current).id,
            parent3: ReactDOM.findDOMNode(this.H3.current).id,
            parent4: ReactDOM.findDOMNode(this.H41.current).id,
            parent5: ReactDOM.findDOMNode(this.H6.current).id,
            parent6: ReactDOM.findDOMNode(this.Dsc_Oh.current).id,
            parent7: ReactDOM.findDOMNode(this.Kick_n_Hat.current).id,
            parent8: ReactDOM.findDOMNode(this.RP4_KICK_1.current).id,
            parent9: ReactDOM.findDOMNode(this.Cev_H2.current).id
        };
    }

    keyPress(event){

        let myKey = event.key;
        let displayId;

        switch (myKey.toUpperCase()) {
            case this.Q.current.id:
                this.sounds.sound1.volume = this.state.volume;
                this.sounds.sound1.play();

                if(this.state.volume===0){
                    displayId = null;
                }
                else{
                    displayId = this.parents.parent1.id;
                }

                break;
            case this.W.current.id:
                this.sounds.sound2.volume = this.state.volume;
                this.sounds.sound2.play();

                if(this.state.volume===0){
                    displayId = null;
                }
                else{
                    displayId = this.parents.parent2.id;
                }

                break;
            case this.E.current.id:
                this.sounds.sound3.volume = this.state.volume;
                this.sounds.sound3.play();

                if(this.state.volume===0){
                    displayId = null;
                }
                else{
                    displayId = this.parents.parent3.id;
                }

                break;
            case this.A.current.id:
                this.sounds.sound4.volume = this.state.volume;
                this.sounds.sound4.play();

                if(this.state.volume===0){
                    displayId = null;
                }
                else{
                    displayId = this.parents.parent4.id;
                }

                break;
            case this.S.current.id:
                this.sounds.sound5.volume = this.state.volume;
                this.sounds.sound5.play();

                if(this.state.volume===0){
                    displayId = null;
                }
                else{
                    displayId = this.parents.parent5.id;
                }

                break;
            case this.D.current.id:
                this.sounds.sound6.volume = this.state.volume;
                this.sounds.sound6.play();

                if(this.state.volume===0){
                    displayId = null;
                }
                else{
                    displayId = this.parents.parent6.id;
                }

                break;
            case this.Z.current.id:
                this.sounds.sound7.volume = this.state.volume;
                this.sounds.sound7.play();

                if(this.state.volume===0){
                    displayId = null;
                }
                else{
                    displayId = this.parents.parent7.id;
                }

                break;
            case this.X.current.id:
                this.sounds.sound8.volume = this.state.volume;
                this.sounds.sound8.play();

                if(this.state.volume===0){
                    displayId = null;
                }
                else{
                    displayId = this.parents.parent8.id;
                }

                break;
            case this.C.current.id:
                this.sounds.sound9.volume = this.state.volume;
                this.sounds.sound9.play();

                if(this.state.volume===0){
                    displayId = null;
                }
                else{
                    displayId = this.parents.parent9.id;
                }

                break;
            default:

        }

        this.setState({
            display: displayId,
        });

    }

    handleClick(e){

        let displayId;

        switch (e.target.id) {
            case this.H1.current.id:
                this.sounds.sound1.volume = this.state.volume;
                this.sounds.sound1.play();

                if(this.state.volume===0){
                    displayId = null;
                }
                else{
                    displayId = this.parents.parent1.id;
                }

                break;
            case this.H2.current.id:
                this.sounds.sound2.volume = this.state.volume;
                this.sounds.sound2.play();

                if(this.state.volume===0){
                    displayId = null;
                }
                else{
                    displayId = this.parents.parent2.id;
                }

                break;
            case this.H3.current.id:
                this.sounds.sound3.volume = this.state.volume;
                this.sounds.sound3.play();

                if(this.state.volume===0){
                    displayId = null;
                }
                else{
                    displayId = this.parents.parent3.id;
                }

                break;
            case this.H41.current.id:
                this.sounds.sound4.volume = this.state.volume;
                this.sounds.sound4.play();

                if(this.state.volume===0){
                    displayId = null;
                }
                else{
                    displayId = this.parents.parent4.id;
                }

                break;
            case this.H6.current.id:
                this.sounds.sound5.volume = this.state.volume;
                this.sounds.sound5.play();

                if(this.state.volume===0){
                    displayId = null;
                }
                else{
                    displayId = this.parents.parent5.id;
                }

                break;
            case this.Dsc_Oh.current.id:
                this.sounds.sound6.volume = this.state.volume;
                this.sounds.sound6.play();

                if(this.state.volume===0){
                    displayId = null;
                }
                else{
                    displayId = this.parents.parent6.id;
                }

                break;
            case this.Kick_n_Hat.current.id:
                this.sounds.sound7.volume = this.state.volume;
                this.sounds.sound7.play();

                if(this.state.volume===0){
                    displayId = null;
                }
                else{
                    displayId = this.parents.parent7.id;
                }

                break;
            case this.RP4_KICK_1.current.id:
                this.sounds.sound8.volume = this.state.volume;
                this.sounds.sound8.play();

                if(this.state.volume===0){
                    displayId = null;
                }
                else{
                    displayId = this.parents.parent8.id;
                }

                break;
            case this.Cev_H2.current.id:
                this.sounds.sound9.volume = this.state.volume;
                this.sounds.sound9.play();

                if(this.state.volume===0){
                    displayId = null;
                }
                else{
                    displayId = this.parents.parent9.id;
                }

                break;
            default:

        }

        this.setState({
            display: displayId,
        });

    }

    handleVolume(e){

        this.setState({
            volume: e.target.value/100,
            sliderVal: e.target.value,
            prevVolume: e.target.value/100,
        });

    }

    onOff(e){

        if(this.state.mySwitch){
            this.setState({
                mySwitch: !this.state.mySwitch,
                mySwitchBox: !this.state.mySwitchBox,
                volume: 0,
            });
        }
        else{
            this.setState({
                mySwitch: !this.state.mySwitch,
                mySwitchBox: !this.state.mySwitchBox,
                volume: this.state.prevVolume,
            });
        }

    }


    fancyToggle(e){
        this.setState({
            fancy: e.target.checked
        });

    }

    render(){

        const displayId = this.state.display ? this.state.display : "No sound";
        const mySwitch = this.state.mySwitch ? "switchOn" : "switchOff";
        const mySwitchBox = this.state.mySwitchBox ? "switchBoxOn" : "switchBoxOff";
        const switchText = this.state.mySwitch ? "On" : "Off";
        const fancyId = this.state.fancy ? this.Id.id2.map(item2 => item2.replace("-"," ")) : this.Id.id1.map(item1 => item1.replace("-"," "));
        const track = this.state.fancy ? this.tracks.track2 : this.tracks.track1;

        console.log("***");
        console.log(fancyId);
        console.log(track);
        console.log("***");

        return(

            <div id="drum-machine" className="grid-container cent" ref={this.myRef}>
                <div id="display" className="item1">{displayId}</div>

                <div id={fancyId[0]} ref={this.H1} className="drum-pad btn btn-warning" onClick={this.handleClick}>
                    Q<audio id="Q" ref={this.Q} className="clip">
                        <source src={track[0]} type="audio/mp3"></source>
                    </audio>
                </div>

                <div id={fancyId[1]} ref={this.H2} className="drum-pad btn btn-warning" onClick={this.handleClick}>
                    W<audio id="W" ref={this.W} className="clip">
                        <source src={track[1]}></source>
                    </audio>
                </div>

                <div id={fancyId[2]} ref={this.H3} className="drum-pad btn btn-warning" onClick={this.handleClick}>
                    E<audio id="E" ref={this.E} className="clip">
                        <source src={track[2]} type="audio/mp3"></source>
                    </audio>
                </div>

                <div id={fancyId[3]} ref={this.H41} className="drum-pad btn btn-warning" onClick={this.handleClick}>
                    A<audio id="A" ref={this.A} className="clip">
                        <source src={track[3]} type="audio/mp3"></source>
                    </audio>
                </div>

                <div id={fancyId[4]} ref={this.H6} className="drum-pad btn btn-warning" onClick={this.handleClick}>
                    S<audio id="S" ref={this.S} className="clip">
                        <source src={track[4]} type="audio/mp3"></source>
                    </audio>
                </div>

                <div id={fancyId[5]} ref={this.Dsc_Oh} className="drum-pad btn btn-warning" onClick={this.handleClick}>
                    D<audio id="D" ref={this.D} className="clip">
                        <source src={track[5]} type="audio/mp3"></source>
                    </audio>
                </div>

                <div id={fancyId[6]} ref={this.Kick_n_Hat} className="drum-pad btn btn-warning" onClick={this.handleClick}>
                    Z<audio id="Z" ref={this.Z} className="clip">
                        <source src={track[6]} type="audio/mp3"></source>
                    </audio>
                </div>

                <div id={fancyId[7]} ref={this.RP4_KICK_1} className="drum-pad btn btn-warning" onClick={this.handleClick}>
                    X<audio id="X" ref={this.X} className="clip">
                        <source src={track[7]} type="audio/mp3"></source>
                    </audio>
                </div>

                <div id={fancyId[8]} ref={this.Cev_H2} className="drum-pad btn btn-warning" onClick={this.handleClick}>
                    C<audio id="C" ref={this.C} className="clip">
                        <source src={track[8]} type="audio/mp3"></source>
                    </audio>
                </div>

                <div className="item3">
                    <input id="switch" type="checkbox" onChange={this.fancyToggle}/>
                    <div className="wrap">
                    <label htmlFor="switch"><span className="rib"></span><span className="rib"></span><span className="rib"></span></label>
                    </div>
                </div>

                <div className="item2">
                    <input type="range" min="1" max="100" value={this.state.sliderVal} className="slider" id="myRange" ref={this.myRange} onChange={this.handleVolume}/>
                    <div className="vol">Volume {this.state.sliderVal}</div>
                </div>

                <div id="sw"  className={mySwitchBox} onClick={this.onOff}>
                    <div className={mySwitch} ref={this.mySwitchOn}>{switchText}</div>
                </div>

            </div>

        );

    }

}

ReactDOM.render(<DrumMachine/>, document.getElementById('root'));

Игнорируйте закомментированный код, мне сказали, что это не божий способ сделать это.Кроме того, указанный код - это то, что я уже пробовал.Здесь работает пример кода.

Обновлен код.Теперь осталось решить только ту левую нижнюю кнопку, которая заряжается для чередования двух коллекций звуковых дорожек.На самом деле, он делает то, что должен, но звуки остаются прежними.После проверки подтега источника звука я не обнаружил ошибок и ничего.У него есть подходящий файл для воспроизведения ... Это поражает мое мнение, в чем здесь проблема, так как все соответствует спецификациям ... Что должна делать эта кнопка: при нажатии на нее она должна изменить все идентификаторы div, которые охватывают аудиоэлементы,измените значения, указанные в переменной fancyId в render (), также необходимо изменить другую звуковую дорожку, указанную в переменной track в render ().Используя console.log () во многих местах, я не мог точно определить, где проблема.Я проверил аудио элементы после нажатия на кнопку и источник звука изменился так, как он должен был.Я надеюсь, что новые взгляды могут пролить свет на эту опасную ситуацию, в которой я сейчас нахожусь.

Edit2: я думаю, что нашел решение.Вместо того, чтобы проверять, нажата ли кнопка (например, кнопка) в render (), я проверил это состояние (причудливо) в методах воспроизведения звуков, например handleClick () и keyPress ().Итак, ... если это неверно, используйте один набор звуков, если это правда, используйте другие наборы звуков.Проверьте код, он обновлен.

1 Ответ

0 голосов
/ 30 сентября 2018

Для начала я бы использовал один проигрыватель, а не несколько, и поместил бы все эти аудио-URL в массив и зациклил их в методе рендеринга в виде списка текстовых ссылок.Когда пользователь нажимает на ссылку, я загружаю этот проигрыватель через штат с текущим аудиофайлом.Примерно так:

constructor () {
  super()
  this.state = {
    currentAudioFile: 0,
  }
  this.audiofiles = [
    {
      label: 'Heater-1',
      url: 'https://s3.amazonaws.com/freecodecamp/drums/Heater-1.mp3'
    },
    {
      label: 'Heater-2',
      url: 'https://s3.amazonaws.com/freecodecamp/drums/Heater-2.mp3'
    },
    ...
  ]
}

А потом в методе рендеринга:

render () {
  return (
    <div>
      <audio id="Player" controls>
        <source src={this.audiofiles[this.state.currentAudioFile].url} type="audio/mp3"></source>
      </audio>
      <ul>
        {
          this.audiofiles.map((item,i) => (
            <li>
              <span
                onClick={() => {
                  this.setState({
                    currentAudioFile: i,
                  })
                }}
              >
                {item.label}
              </span>
            </li>
          ))
        }
      </ul>
    </div>
  )
}

Надеюсь, это может вам чем-нибудь помочь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...