Stopping a specific Marker using an AudioSprite

Hello! I’m just getting started with using audio in Phaser 3. I’m wondering, how do you stop a specific marker when using an AudioSprite?
Do audio sprites only allow for an all or nothing approach? I’ve looked over some of the examples, in particular Playback and Events
I didn’t see a way to stop the playback of a specific marker.

You can see an working example in post 1189

I did see your post, but that does not demonstrate stopping a specific marker.

Apparently it’s not possible to selectively stop markers and playing another just stops the playback of any markers already playing

Sorry for the miss understanding.

If I understand it right: You want to pause a marker, start another and then play the first marker where it stopped?

I guess you could save time of the current sound and later start that sound at the same saved time.

This is how you get the time
const time = music.seek // return 0 when playback ends
and then you restore it like this
music.setSeek(time)

But I guess to use this with markers, you first have to create a new sound instance with markers
const music = scene.sound.addAudioSprite(key, config)

I have just tested this approach and it seams to work fine:

(I hope this is what you needed)

preload() {
  this.load.audioSprite('music', 'assets/sounds/sounds.json')
}
create() {
  let time = 0
  let music = this.sound.addAudioSprite('music')

  music.play('sound3')

  this.time.addEvent({
    delay: 2000,
    callback: () => {
      time = music.seek // save the time of sound3
      music.play('sound4') // play sound4
    }
  })

  this.time.addEvent({
    delay: 5000,
    callback: () => {
      music.play('sound3') // play sound3 again
      music.setSeek(time) // restore its previous time
    }
  })

  this.time.addEvent({
    delay: 6000,
    callback: () => {
      console.log(music.currentMarker.name) // should be 'sound3'
      console.log(music.seek) // should be around 3 seconds
    }
  })
}

Use it like this if you use markers instead of a json file

preload() {
  this.load.audio('music', 'assets/sounds/0781.ogg')
}
create() {
  const markers = [
    { name: 'sound1', start: 1, duration: 1.0, config: {} },
    { name: 'sound2', start: 3, duration: 15, config: {} },
    { name: 'sound3', start: 20, duration: 15, config: {} },
    { name: 'sound4', start: 40, duration: 15, config: {} }
  ]
  let time = 0
  let music = this.sound.add('music')
  markers.forEach(marker => {
    music.addMarker(marker)
  })

  // and so on ...

Or was your goal to run both sound at the same time?
In this case you only need to create 2 sound instances.

let music1 = this.sound.addAudioSprite('music')
let music2 = this.sound.addAudioSprite('music')

music1.play('sound3')
music2.play('sound4')

// and in case you want to stop them
// music1.stop()
// music2.stop()

Thanks for testing this out! It looks like I’ll need to create multiple sprites to play different markers at the same time?

I have a 2D sprite that will require a marker to loop while the 2d sprite is temporarily active, until it’s offscreen or destroyed, in which case I just want to stop the playback. It appears that I will just make a separate instance of the audiosprite for that

Yes, I think you will need to create one instance per sound you want to play simultaneously.

I just tried your previous example, making two instances using this.sound.addAudioSprite
Unfortunately, when I play one and then play another it stops the first.

Have you played one on the first instance and the other on the second?

Yes, the first one is created as a property in my game class (an instance of scene)
The second is created as a variable in a method of another class (whenever a laser is fired)
Each is a separate variable. The only thing in common being that the scene is used to add the same AudioSprite. I’m pretty sure it’s just referencing the same thing, no matter how many times it’s created (using a cache)

This is strange. When I tested it, I could play two different sounds at the same time without any issues. It must be possible to create multiple instances and play separated sounds at the same time.

In this example, 4 instances are created at preload. The ‘escape’ sound is long. Press it and then several times the ‘boss hit’ sound.

That example loads audio that’s defined in the code, not loading an AudioSprite defined using json. I’m comparing the docs between the two methods, but I cannot tell if the instances property that is also available to the AudioSprite loading method

Can you upload a minimalistic example of your code and the json file?

Maybe it is a bug? I do use .ogg files and use the latest chrome. There it works!

Here’s what I did in my preloader to get it to work.

preload() {
    console.log('Preloader preload');
    this.load.image('logo', 'assets/logo.png');
    this.load.multiatlas('entities', 'assets/entities.json', 'assets');
    this.load.multiatlas('wall', 'assets/wall.json', 'assets');
    this.load.setPath('assets/audio/');
    this.load.audioSprite('resources', 'resources.json', [
        'resources.ogg',
        'resources.mp3',
        'resources.m4a'
    ], { instances: 6 }); // added this
}

Thanks for your help! :grinning:

:grinning: I’m very glad you found a solution.