最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - how to use howler.js in react? - Stack Overflow

programmeradmin3浏览0评论

Why is it that when I click play, I can play the sound and when I click play, there is no sound??

import React, { Component } from "react";
import { Howl, Howler } from 'howler';

class App extends Component {
  SoundPlay() {
    const Sounds = new Howl({
      src: ["sound.mp3"]
    })
    Sounds.play()
    console.log("sound")
  }
  render() {
    return (
      <div className="App">
        <button onClick={this.SoundPlay}>play</button>
      </div>
    );
  }
}

export default App;

Why is it that when I click play, I can play the sound and when I click play, there is no sound??

import React, { Component } from "react";
import { Howl, Howler } from 'howler';

class App extends Component {
  SoundPlay() {
    const Sounds = new Howl({
      src: ["sound.mp3"]
    })
    Sounds.play()
    console.log("sound")
  }
  render() {
    return (
      <div className="App">
        <button onClick={this.SoundPlay}>play</button>
      </div>
    );
  }
}

export default App;
Share Improve this question edited Feb 26, 2019 at 13:27 barbsan 3,45811 gold badges23 silver badges29 bronze badges asked Feb 26, 2019 at 13:23 张晓钒张晓钒 611 gold badge1 silver badge2 bronze badges 2
  • 2 Pretty sure it is a path issue. Look at the console and see the url where the browser tries to find the file. (See working codesandbox, the .mp3 file is in the public folder) – Gabriele Petrioli Commented Feb 26, 2019 at 13:59
  • Thanks, I also put the sound. Mp3 file in the public directory. Change it to src :[" /sound.mp3 "] and it will play. – 张晓钒 Commented Feb 27, 2019 at 14:18
Add a comment  | 

4 Answers 4

Reset to default 8

I recently published react-use-audio-player which is a react hooks abstraction of howlerjs. You can use it like so:

import { useAudioPlayer } from "react-use-audio-player"

function MyComponent() {
    const { play, pause, stop, playing } = useAudioPlayer()

    const handlePlayPause = () => {
        if (playing) {
            pause()
        } else {
            play()
        }
    }

    return (
        <div className="audioControls">
            <button onClick={handlePlayPause}>
                {playing ? "pause" : "play"}
            </button>
            <button onClick={stop}>stop</button>
        </div>
    )
}

Change your code to the following (using / in front of the file name) and make sure your file is in your app's public folder.

const Sounds = new Howl({
    src: ["/sound.mp3"]
})

I recently ran into this as well. The problem with using Howler directly in JavaScript is that you'll need to manage the Howl instance manually. When your component dismounts, you'll need to stop any playing sounds.

React Howler exists which solves this:

import React, { useState } from 'react'
import ReactHowler from 'react-howler'

export default function PlayPause() {
  const { play, setPlay } = useState(false)
  return (
    <div>
      <ReactHowler src='./sound.mp3' playing={play} />
      <button onClick={() => setPlay(!play)}>
        { play ? 'Pause' : 'Play' }
      </button>
    </div>
  )
}

I have to admit, though, that React Howler didn't solve my use case because it doesn't actually implement all of howler's features, particularly audio sprites.

I ended up writing my own library, Rehowl. It separates out the loading of the file from the playing of sounds like so:

import React, { useState } from 'react'
import { Play, useHowl } from 'rehowl'

export default function PlayPause() {
  const { play, setPlay } = useState(false)
  const { howl } = useHowl({ src: './sound.mp3' })
  return (
    <div>
      <Play howl={howl} pause={!play} />
      <button onClick={() => setPlay(!play)}>
        { play ? 'Pause' : 'Play' }
      </button>
    </div>
  )
}

The useAudioPlayer library linked in another answer seems like another solid alternative to react-howler.

In any case, I'd say that using Howler directly in a React project will cause headaches as managing playing sounds while dealing with the component lifecycle is hard.

The sound file needs to be imported to the component, just like React and Howler.

import React, { Component } from "react";
import { Howl, Howler } from 'howler';
import newSound from './sound.mp3';

class App extends Component {
  constructor() {
    super()
    this.state = { 
      sound: new Howl({
          src: [newSound]
      })
    }
  }

  render() {
    return (
      <div className="App">
        <button onClick={this.state.sound.play()}>play</button>
      </div>
    );
  }
}

export default App;


You might be able to store the sound in state, if you build a constructor, that way you aren't instantiating a new Howl every time you click play. Something like this.

import React, { Component } from "react";
import { Howl, Howler } from 'howler';
import newSound from './sound.mp3';

class App extends Component {
  SoundPlay() {
    const Sounds = new Howl({
      src: [newSound]
    })
    Sounds.play()
    console.log("sound")
  }
  render() {
    return (
      <div className="App">
        <button onClick={this.SoundPlay}>play</button>
      </div>
    );
  }
}

export default App;

This might throw an error though, with Chrome's AudioContext rules. But I would be interested in seeing if it works!

发布评论

评论列表(0)

  1. 暂无评论