goldfire / howler.js

Javascript audio library for the modern web.
https://howlerjs.com
MIT License
23.8k stars 2.22k forks source link

HTML5 Audio causing extension of sprite duration #826

Closed sgrund14 closed 4 years ago

sgrund14 commented 6 years ago

Sprites are playing longer than they should when using html5 audio.

Initializing howl like this:

import AudioInfo from '../audio/GameAudio.json';
import { Howl } from 'howler';

const spriteMap = {};
for (const sprite in AudioInfo.spritemap) {
    spriteMap[sprite] = [
        (AudioInfo.spritemap[sprite].start * 1000),
        ((AudioInfo.spritemap[sprite].end - AudioInfo.spritemap[sprite].start) * 1000),
        AudioInfo.spritemap[sprite].loop
    ];
}

const GameAudio = new Howl({
  src: [GameAudioMP3, GameAudioM4A, GameAudioOGG, GameAudioAC3],
  sprite: spriteMap,
  html5: true,
  volume: 1.0
});

AudioInfo looks like this:

{
  "resources": [
    "GameAudio.ogg",
    "GameAudio.m4a",
    "GameAudio.mp3",
    "GameAudio.ac3"
  ],
  "spritemap": {
    "GameAudio": {
      "start": 0,
      "end": 810,
      "loop": false
    },
    "demo_loop": {
      "start": 811,
      "end": 862.9978004535147,
      "loop": false
    },
    "enter_game": {
      "start": 864,
      "end": 869.4073469387755,
      "loop": false
    },
    "gameplay_loop": {
      "start": 871,
      "end": 1384.8808163265307,
      "loop": true
    },
    "level_end": {
      "start": 1386,
      "end": 1387.5673469387755,
      "loop": false
    },
    "main_loop": {
      "start": 1389,
      "end": 1508.614693877551,
      "loop": true
    },
    "move": {
      "start": 1510,
      "end": 1510.3395918367346,
      "loop": false
    },
    "move_blocked": {
      "start": 1512,
      "end": 1512.2351020408164,
      "loop": false
    },
    "switch_toggle": {
      "start": 1514,
      "end": 1514.444081632653,
      "loop": false
    }
  }
}

spriteMap passed into Howl looks like this:

screen shot 2017-10-10 at 11 15 24 am

Getting duration for the howl by using (sprite.end - sprite.start) * 1000.

While the duration of each sprite is correct using duration(), it plays for longer than that, resulting in extra sprite sounds being played.

The start time for the sprite is also correct.

What's curious is, when I set html5: false, the duration is as long as it should be, and no extra sprites are played.

Generating GameAudio using audiosprite.

sgrund14 commented 6 years ago

So for example, if I call GameAudio.play('move'), it will play move, then move_blocked, then switch_toggle.

goldfire commented 6 years ago

What browser are you testing this in? I'm unable to reproduce this in my own testing, but I may be doing something differently.

sgrund14 commented 6 years ago

Google Chrome!

JochenHeizmann commented 6 years ago

Same here on MAC OS X with Google Chrome and FireFox. On Safari it doesn't even play ("onplayerror" is triggered) when setting html5 to true.

JochenHeizmann commented 6 years ago

I'm new to the codebase, but I've found out, that the following line is evaluating to true (regarding the comment it should only evaluate to true for IE with network latency), and this is causing that the _ended callback is triggered forever, so the sound/sprite is never stopped from playing:

https://github.com/goldfire/howler.js/blob/master/src/howler.core.js#L1711

I don't know how to fix it right now without introducing another edge case, so I haven't created a pull request yet.

oleg-ch commented 6 years ago

got the same issue, and yes, you have to do something inside the if condition, otherwise _ended will get restarted over and over again till your whole sprite file comes to an end. The following solves the immediate issue for now:

// If we are using IE and there was network latency we may be clipping
// audio before it completes playing. Lets check the node to make sure it
// believes it has completed, before ending the playback.
if (!self._webAudio && sound._node && !sound._node.paused) {
    self.stop(sound._id, true);
    setTimeout(self._ended.bind(self, sound), 100);
    return self;
}
veeking commented 5 years ago

Me too! if html5: true, duration delay 500ms!!!

ml-hance commented 4 years ago

I have same issue when I try to use some mp3 file which has duration larger than 1 min.

goldfire commented 4 years ago

Closing due to inactivity. If this is still an issue, reply with more info and I'll reopen.

asenvolev commented 8 months ago

Closing due to inactivity. If this is still an issue, reply with more info and I'll reopen.

more info

asenvolev commented 8 months ago

this still reproduces even with the latest versions of howler 2.2.3 and 2.2.4