简体   繁体   中英

How to pause music(mp3) using Tone.player of Tone.js?

I'm new to tone.js and I just want a simple pause button. I know that there is a stop() and start() but it's not a pause and when to start again the music just go to the beginning of the song.

I use tone.js because I want to manipulate the music and do some synthesizing sound. I also use p5.js but somehow the pause dose not work. It throws an error saying "Cannot read property 'length' of undefined. So I want to use tone.js but just have to figure out how to pause the music. Thanks.

Here's the code

var player = new Tone.Player("data/audio/singingbird_audio.mp3").toMaster();
var whale = new Tone.Player("data/audio/whale.mp3").toMaster();
whale.autostart = false;
whale.volume.value = -10;
player.autostart = false;
player.volume.value = 5;
player.stop();

button = createButton('Play Bird');
button.position(20, 200);
button.mousePressed(birdSwitch);

function birdSwitch() {
    if (player.state == "started") {
        player.stop();
        whale.stop();
    } else if (player.state == "stopped") {
        player.start();
        whale.start();
    }
}

Not sure why Johannes is being such a buzz kill. There's absolutely no reason NOT to use Tone.js. It's a really cool library.

Besides, the ACTUAL solution is easier than the solution Johaness so unhelpfully came up with.

SOLUTION

Literally all you need to do is sync the Player objects to the Tone.Transport and then you can play/pause/stop all day long by controlling the Transport instead of the players

Try modifying your code to look like this

var player = new Tone.Player("data/audio/singingbird_audio.mp3").toMaster();
var whale = new Tone.Player("data/audio/whale.mp3").toMaster();

// sync the Players to the Transport like this
player.sync().start(0);
whale.sync().start(0);

whale.volume.value = -10;
player.volume.value = 5;

button = createButton('Play Bird');
button.position(20, 200);
button.mousePressed(birdSwitch);

function birdSwitch() {
    if (player.state == "started") {
        // Use the Tone.Transport to pause audio
        Tone.Transport.pause();
    } else if (player.state == "stopped") {
        // Use the Tone.Transport to start again
        Tone.Transport.start();
    }
}

ADDITIONAL IDEAS

If you want to make the UI for your program even easier, you may also want to consider using the "tonejs-ui.js" library, which has a great Play/Pause/Stop button in it.

Just include the link to the "tonejs-ui.js" library in your <head> and then you can use the <tone-play-toggle> element in your HTML and add an event listener to it that triggers the Transport start/pause.

Here's an example of the code you'd need to add to your HTML file and the event listener to add to your javascript instead of the logic you're using for your own button. Hopefully this makes sense.

<head>
   <!-- The tonejs-ui.js CDN link     -->
   <script type="text/javascript" src="https://unpkg.com/@tonejs/ui@0.0.8/build/tonejs-ui.js"></script>

</head>

<body>

   <tone-content>
      <tone-play-toggle></tone-play-toggle>
   </tone-content>

   <script type="text/javascript">
      document.querySelector("tone-play-toggle").addEventListener("play", (e) => {

         const playing = e.detail;

         if (playing){
            Tone.Transport.start();
         } else {
            Tone.Transport.pause();
         }
      });

   </script>
</body>

Tone.js is a bit of a overkill to just play an mp3 file.

Why not just using the <audio> -Tag? That way you can directly play and pause it.

<button id="pause">Play/Pause</button>
<audio
  id="audioNode"
  src="https://www.soundhelix.com/examples/mp3/SoundHelix-Song-7.mp3"
  controls
></audio>
const audio = document.getElementById("audioNode");

document.getElementById("pause").addEventListener("click", () => {
  if (audio.paused) {
    audio.play();
  } else {
    audio.pause();
  }
});

Codesandbox: https://codesandbox.io/s/charming-wiles-ehy8y

In Tonejs a player is just a wrapper around an audio buffer. Play, pausing, etc. is done by syncing the players to the Transport class and use Transports play, pause, stop functionalities. Which then propagates to the players. But since the Transport has an internal timeline I don't think that this is what you need, since you would have to reset the Transport to the correct position, etc.

I guess in the end it's way more convenient for you to just fall back to the simpler solution.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM