Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Failed to execute 'stop' on 'AudioScheduledSourceNode': cannot call stop without calling start first. #25

Closed
phpsollution opened this issue Feb 15, 2023 · 5 comments

Comments

@phpsollution
Copy link

phpsollution commented Feb 15, 2023

Hi @ozdemirburak
When i am clicking first time on the playicon then the audio has been start playing but as soon as i am clicking again to pause the audio it showing me this error "Failed to execute 'stop' on 'AudioScheduledSourceNode': cannot call stop without calling start first."

I am unable to understand what i am making wrong. Please help some one.

const morse = require('morse-decoder');
const togglePlay = (event) => {
      const audio = morse.audio('My Text');
      if (event.target.className === 'playicon') {
          audio.play();
          event.target.className = 'pauseicon';
      } else {
          audio.stop();
          event.target.className = 'playicon';
      }
  }

<div className="playicon" onClick={togglePlay}></div>
@salmanAhmad143
Copy link

Hey @phpsollution @ozdemirburak @chris--jones
Have you got the solution?
I am also facing the same error when i am trying to stop the morse it giving me the same error

image

const audio = morse.audio('My Text');

if(notPlaying) {
     audio.play();
} else {
     audio.stop();
}

Please suggest any one. Waiting for your reply.

@chris--jones
Copy link
Contributor

I haven't seen this happen before my only guess is some sort of race condition.
The current implementation of play/stop is kind of broken because AudioBufferSourceNodes aren't supposed to have start and stop called more than once - so audio.stop() is probably more of a dispose.

To make functionality similar to what you're expecting would require some refactoring in the library - only calling start for the first play on the source, tracking the currentTime (should be exposed I guess) and either altering the playRate or gain to simulate a pause on stop rather than outright stopping the source (although we'd still want a clean way to dispose of the audio source).

The current workaround is to create new audio instances when you play:

let audio;
if(notPlaying) {
     audio = morse.audio('My Text')
     audio.play();
} else {
     audio.stop();
}

note this won't enable you to pause and resume though.

@ozdemirburak
Copy link
Owner

Chris' response should work as a workaround; therefore, I'm closing this issue. However, another issue can be opened for adding the pause/play option.

Completely refactoring the audio generation is another option. There are other potential changes mentioned here on #27.

@chris--jones
Copy link
Contributor

chris--jones commented Oct 7, 2023

I know this is closed, but it also occurred to me that you can use the wave functions to get an audio blob that you can pause, play and seek to your heart's content.

As an example consider this which binds the rendered audio to an audio element with controls:

<audio id="morse" controls />
<script>
    const morse = window['morse-decoder'];
    const audioOutput = morse.audio('Go ahead, pause this audio');
    audioOutput.getWaveUrl().then((url) => {
        document.querySelector('#morse')
        .setAttribute('src', url);
    });
</script>

image

I'll submit a PR to add more examples to the readme, since there's a few other omissions such as how to even use the minified js on a web page as I have above.

@ozdemirburak
Copy link
Owner

That's a really smart approach.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants