WedX - журнал о программировании и компьютерных науках

несколько тегов ‹аудио›, воспроизводящих разные исходные файлы

У меня есть несколько кнопок на странице, при нажатии которых я хочу, чтобы проигрывался определенный звук. Он может работать с одним тегом, но когда я пытаюсь добавить другой (с другим источником), он переходит ко второму тегу и не воспроизводит первый.

<audio ref={`${cap}`} >
     <source src={singleLetter.capitalSound} preload='auto'/>
     </audio>

 <audio ref={`${low}`} >
     <source src={singleLetter.lowerSound} preload='auto'/>
 </audio>

    <button type="button" className="btn btn-lg display"
    onClick={() =>
      this.playCapital(cap)
    }>
      {singleLetter.capital}
    </button>

    <button type="button" className="btn btn-lg display"
    onClick={() =>
      this.playLower(low)
    }>
      {singleLetter.lowercase}
    </button>

Я также использую следующее для воспроизведения звуков (это приложение для реакции/редукции):

playCapital(cap) {
  this.refs[cap].load()
  this.refs[cap].play()
}

playLower(low) {
  this.refs[low].load()
  this.refs[low].play()
}
14.05.2017

Ответы:


1

При рендеринге компонентов в DOM React повторно использует узлы, которые могут вызывать проблемы, подобные описанным вами (особенно с тегами <audio> и <video>). Если вы действительно хотите использовать React для воспроизведения звуков, вы должны изучить разные подходы — назначение клавиш, рендеринг каждого звука как независимого компонента и т. д.

Вам следует рассмотреть возможность использования HTML5 Audio API, как показано здесь - это будет понятнее и не потребует хаков.

Ниже приведены примеры различных техник виртуального дома, каждая из которых имеет разные эффекты. В первом примере каждый звук отображается как отдельные аудиотеги и ссылается на них по URL-адресу. Это, вероятно, то, что вы хотите получить:

const sets = [
  {
      capital: 'Play WinXP error',
      capitalSound: 'https://www.myinstants.com/media/sounds/erro.mp3',
      
      lowercase: 'Play MSG',
      lowerSound: 'https://www.myinstants.com/media/sounds/metalgearsolid.swf.mp3'
   },
   
   {
      capital: 'Play Leeroy Jenking',
      capitalSound: 'https://www.myinstants.com/media/sounds/leroy.swf.mp3',
      
      lowercase: 'Play Murlock',
      lowerSound: 'https://www.myinstants.com/media/sounds/sound-9_____.mp3'
    }

]

class Example extends React.Component {
  constructor() {
    super()
    
    this.state = {
      set: 0,
      sounds: [
        sets[0].capitalSound, 
        sets[0].lowerSound, 
      ]
    }
    
    this.playSound = this.playSound.bind(this)
  }
  
  playSound(sound) {
    this.refs[sound].load()
    this.refs[sound].play()
  }

  render() {
    const singleLetter = sets[this.state.set]
    
    return (
      <div>
        {this.state.sounds.map(sound => 
          <audio key={sound} ref={`${sound}`} >
            <source src={sound} preload='auto'/>
          </audio>
        )}

        <button type="button" className="btn btn-lg display"
        onClick={() =>
          this.playSound(singleLetter.capitalSound)
        }>
          {singleLetter.capital}
        </button>

        <button type="button" className="btn btn-lg display"
        onClick={() =>
          this.playSound(singleLetter.lowerSound)
        }>
          {singleLetter.lowercase}
        </button>
        
        <button onClick={() =>
          this.setState({
            sounds: this.state.set == 0 ? 
              [
                ...this.state.sounds,
                sets[1].capitalSound, 
                sets[1].lowerSound
              ]
              :
              [
                ...this.state.sounds,
                sets[0].capitalSound, 
                sets[0].lowerSound
              ],
            set: this.state.set == 0 ? 1 : 0
          })
        }>
          Change set
        </button>
      </div>
    )
  }
}

ReactDOM.render(
  <Example />,
  document.getElementById("app")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id="app"></div>

Пример без клавиш, одни и те же звуки будут останавливаться после загрузки и воспроизводиться при изменении набора. (изменить набор -> воспроизвести Лироя -> изменить набор -> воспроизвести WinXP -- Лирой останавливается)

const sets = [
  {
      capital: 'Play WinXP error',
      capitalSound: 'https://www.myinstants.com/media/sounds/erro.mp3',
      
      lowercase: 'Play MSG',
      lowerSound: 'https://www.myinstants.com/media/sounds/metalgearsolid.swf.mp3'
   },
   
   {
      capital: 'Play Leeroy Jenking',
      capitalSound: 'https://www.myinstants.com/media/sounds/leroy.swf.mp3',
      
      lowercase: 'Play Murlock',
      lowerSound: 'https://www.myinstants.com/media/sounds/sound-9_____.mp3'
    }

]

class Example extends React.Component {
  constructor() {
    super()
    
    this.state = {set: 0}
    
    this.playCapital = this.playCapital.bind(this)
    this.playLower = this.playLower.bind(this)
  }
  
  playCapital(cap) {
    this.refs[cap].load()
    this.refs[cap].play()
  }

  playLower(low) {
    this.refs[low].load()
    this.refs[low].play()
  }

  render() {
    const cap = 'cap'
    const low = 'low'
    
    const singleLetter = sets[this.state.set]
    
    return (
      <div>
        <audio ref={`${cap}`} >
          <source src={singleLetter.capitalSound} preload='auto'/>
        </audio>

        <audio ref={`${low}`} >
          <source src={singleLetter.lowerSound} preload='auto'/>
        </audio>

        <button type="button" className="btn btn-lg display"
        onClick={() =>
          this.playCapital(cap)
        }>
          {singleLetter.capital}
        </button>

        <button type="button" className="btn btn-lg display"
        onClick={() =>
          this.playLower(low)
        }>
          {singleLetter.lowercase}
        </button>
        
        <button onClick={() =>
          this.setState({set: this.state.set == 0 ? 1 : 0})
        }>
          Change set
        </button>
      </div>
    )
  }
}

ReactDOM.render(
  <Example />,
  document.getElementById("app")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id="app"></div>

Пример с ключами, звук немедленно останавливается, когда набор изменяется из-за того, что React считает эти теги разными и не использует повторно теги <audio>. (измените набор во время воспроизведения звука, чтобы заметить, что тег audio удаляется)

const sets = [
  {
      capital: 'Play WinXP error',
      capitalSound: 'https://www.myinstants.com/media/sounds/erro.mp3',
      
      lowercase: 'Play MSG',
      lowerSound: 'https://www.myinstants.com/media/sounds/metalgearsolid.swf.mp3'
   },
   
   {
      capital: 'Play Leeroy Jenking',
      capitalSound: 'https://www.myinstants.com/media/sounds/leroy.swf.mp3',
      
      lowercase: 'Play Murlock',
      lowerSound: 'https://www.myinstants.com/media/sounds/sound-9_____.mp3'
    }

]

class Example extends React.Component {
  constructor() {
    super()
    
    this.state = {set: 0}
    
    this.playCapital = this.playCapital.bind(this)
    this.playLower = this.playLower.bind(this)
  }
  
  playCapital(cap) {
    this.refs[cap].load()
    this.refs[cap].play()
  }

  playLower(low) {
    this.refs[low].load()
    this.refs[low].play()
  }

  render() {
    const cap = 'cap'
    const low = 'low'
    
    const singleLetter = sets[this.state.set]
    
    return (
      <div>
        <audio key={singleLetter.capitalSound} ref={`${cap}`} >
          <source src={singleLetter.capitalSound} preload='auto'/>
        </audio>

        <audio key={singleLetter.lowerSound} ref={`${low}`} >
          <source src={singleLetter.lowerSound} preload='auto'/>
        </audio>

        <button type="button" className="btn btn-lg display"
        onClick={() =>
          this.playCapital(cap)
        }>
          {singleLetter.capital}
        </button>

        <button type="button" className="btn btn-lg display"
        onClick={() =>
          this.playLower(low)
        }>
          {singleLetter.lowercase}
        </button>
        
        <button onClick={() =>
          this.setState({set: this.state.set == 0 ? 1 : 0})
        }>
          Change set
        </button>
      </div>
    )
  }
}

ReactDOM.render(
  <Example />,
  document.getElementById("app")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id="app"></div>

15.05.2017
  • Последний пример у меня хорошо сработал, большое спасибо Przemyslaw - я использовал ключи, и я мог лучше понять, как внести реквизит в аудио теги отдельно. Спасибо еще раз. 15.05.2017
  • Новые материалы

    Как создать диаграмму градиентной кисти с помощью D3.js
    Резюме: Из этого туториала Вы узнаете, как добавить градиентную кисть к диаграмме с областями в D3.js. Мы добавим градиент к значениям SVG и применим градиент в качестве заливки к диаграмме с..

    Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что это выглядит сложно…
    Просто начните и учитесь самостоятельно Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что он кажется мне сложным, и я бросил его. Это в основном инструмент..

    Лицензии с открытым исходным кодом: руководство для разработчиков и создателей
    В динамичном мире разработки программного обеспечения открытый исходный код стал мощной парадигмой, способствующей сотрудничеству, инновациям и прогрессу, движимому сообществом. В основе..

    Объяснение документов 02: BERT
    BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..


    Для любых предложений по сайту: [email protected]