AudioElement length property set to Infinity on Safari

716 views
Skip to first unread message

BiffCornwall

unread,
Mar 23, 2015, 5:41:36 PM3/23/15
to sta...@googlegroups.com
Hi,

I have a rather large sound file that I am attempting to stream with the AudioElementSound class via the AudioElementSound.load() method.  The .length property is always coming back as Infinity.  If I load using the WebAudioAPI instead, the length comes back correct, but this file needs to be streamed.  Is there something I am doing wrong here?

    _sounds = new ResourceManager();
    _sounds
      ..addCustomObject(data.title, AudioElementSound.load(data.songPaths[0], new SoundLoadOptions(alternativeUrls:data.songPaths, mp3:true, ogg:true, wav:true)))
      ..load().then((_)
      {
        Sound sound = _sounds.getCustomObject(data.title);
        print("${sound.length}");
      });

Bernhard Pichler

unread,
Mar 23, 2015, 6:16:53 PM3/23/15
to BiffCornwall, sta...@googlegroups.com
Hi,

Your code looks correct and i wonder what the problem could be. Maybe it's the sound file itself. Is it a mp3 with VBR encoding? Sometimes those files have issues with the length calculation. You could also take a look at the id3 tag of the file, maybe this one is wrong.

Btw. the sample you showed is probably just a simplified version of your actual code. If you just need to load one sound file, you don't necessarily need to use the ResourceManager class. You could do something simple like this:

var slo = new SoundLoadOptions(alternativeUrls:data.songPaths, mp3:true, ogg:true, wav:true);
AudioElementSound.load(data.songPaths[0], slo).then((sound) => sound.play());

Sorry that i can't provide a good answer to your initial question. Please keep me posted if you find out what's wrong.

Bernhard

 




--
You received this message because you are subscribed to the Google Groups "StageXL" group.
Visit this group at http://groups.google.com/group/stagexl.
To view this discussion on the web visit https://groups.google.com/d/msgid/stagexl/a244f654-24d3-4ae3-8658-9f92f2808eab%40googlegroups.com.

Joshua Brown

unread,
Mar 23, 2015, 6:21:21 PM3/23/15
to Bernhard Pichler, sta...@googlegroups.com

Thanks for the reply! I thought maybe the id3 tags could have been the problem, but If I run this exact code in chrome or Firefox the length is correctly calculated. The length is not correctly calculated on safari for desktops or mobile.

Bernhard Pichler

unread,
Mar 23, 2015, 6:28:15 PM3/23/15
to Joshua Brown, sta...@googlegroups.com
Hmmm ... sounds like a browser bug. Maybe you could work around the issue by providing an ac3 encoded audio file. Safari should support this audio format and StageXL will load this file if the primary audio url is the ac3 file.

Joshua Brown

unread,
Mar 23, 2015, 6:49:19 PM3/23/15
to Bernhard Pichler, sta...@googlegroups.com

It's weird to me that it would happen in safari for ios 7.x & 8.x and for safari 6 on Mac osx 10.8 when I have no problems with it working in Chrome or Firefox. Is there another way to pull the length from the song other than using the .length property?  I suppose I could try the ac3 format.

Bernhard Pichler

unread,
Mar 24, 2015, 2:01:33 AM3/24/15
to sta...@googlegroups.com, bernhard.ro...@gmail.com
Yes it's weird. Unfortunately this is the only way to get the length of the audio file.

Maybe an "onEnded" event on the SoundChannel would work for you - but even this simple feature is complicated in the world of html5 audio. There is an open issue on Git Hub but we can't fix it: https://github.com/bp74/StageXL/issues/96




On Monday, March 23, 2015 at 11:49:19 PM UTC+1, BiffCornwall wrote:

It's weird to me that it would happen in safari for ios 7.x & 8.x and for safari 6 on Mac osx 10.8 when I have no problems with it working in Chrome or Firefox. Is there another way to pull the length from the song other than using the .length property?  I suppose I could try the ac3 format.


BiffCornwall

unread,
Mar 24, 2015, 10:31:29 AM3/24/15
to sta...@googlegroups.com, bernhard.ro...@gmail.com
Yeah, I was using the length to run a timer that helps me determine when the sound is complete.  It's how I've been getting around the lack of a SoundChannel 'onEnded' event.

Ravi Purushotma

unread,
Mar 27, 2015, 5:47:27 PM3/27/15
to sta...@googlegroups.com, brown.j...@gmail.com
It may not be a browser bug so much as a server one. I've run into JS issues where length goes to infinity on localhost / local server / server without headers configured a particular way. But, when the sound file is served from a different server everything goes smooth.


Is there any way to get the current play position for a playing sound in StageXL? The basic idea for what I'm hoping to do is:

onUpdate {
   gotoAndPlay(numFrames * (song.position/song.length));
}

But, I didn't see any way of doing sound.position in the StageXL docs short of interop'ing to howler.js . Or Is there a better route to going about this I should be thinking (keeping perfect sync between animations and songs, with the priority being on the song)?

Bernhard Pichler

unread,
Mar 28, 2015, 3:28:46 AM3/28/15
to sta...@googlegroups.com, brown.j...@gmail.com
Yes this could be the case. Browsers never download the whole audio file, they use the Range header to download small parts of the file. This causes all kind of problems with different servers - e.g. loading audio files in Dart Editor behaves very strange because the built in web server does not properly support this header.

It is probably a good idea to focus a little bit more on the Sound APIs for the next version of StageXL. Maybe we can make the onEnded event work too. I also looked at the howler.js source and they use various workarounds for all kinds of problems. 

Regarding the length property that returns infinity: StageXL is listening to the "onCanPlay" event, while howler is listening to the "onCanPlayThrough" event when loading files. In the past StageXL was using the event too, but we changed it to "onCanPlay" because the other event wasn't fired sometimes. I have to look what the problem was and if the other event could fix the length problem. Biff, if you want to give it a try - the code is here: lib/src/internal/audio_loader.dart in line 30.

Bernhard Pichler

unread,
Mar 28, 2015, 3:52:39 AM3/28/15
to sta...@googlegroups.com, brown.j...@gmail.com
Maybe i should add one important thing - all those problems mainly apply to the AudioElement implementation (which is the fallback implementation for Internet Explorer and old Safari browsers). Modern browsers will use the WebAudio API which works much more reliable.

Bernhard Pichler

unread,
Mar 28, 2015, 11:32:33 AM3/28/15
to sta...@googlegroups.com, bernhard.ro...@gmail.com
There is an extended version of the Sound API available in the master branch on GitHub.

The SoundChannel class looks like:


SoundChannel.onComplete;     // An event that fires as soon as the SoundChannel completed the playback.
SoundChannel.loop;           // Getter if the SoundChannel is looping.
SoundChannel.stopped;        // Getter if the SoundChannel is stopped.
SoundChannel.position;       // Getter of the playback position in seconds.
SoundChannel.sound;          // Getter of the parent Sound.
SoundChannel.paused;         // Getter/Setter to pause the SoundChannel.
SoundChannel.soundTransform; // Getter/Setter to set the sound transformation of the SoundChannel.
SoundChannel.stop();         // Stop the playback of the SoundChannel. Can't be resumed!
SoundChannel.pause();        // Pause playback of the SoundChannel.
SoundChannel.resume();       // Resume playback of the SoundChannel.


Since nobody can trust the audio implementations in different browsers on different devices, everything is experimental and much more testing is required. It would be great if everyone could help testing the new implementation on their devices.

Bernhard



Ravi Purushotma

unread,
Mar 30, 2015, 6:41:50 PM3/30/15
to sta...@googlegroups.com, bernhard.ro...@gmail.com
Thanks!

BiffCornwall

unread,
Apr 24, 2017, 12:26:44 PM4/24/17
to StageXL
I know this is an old thread, but I'm reviving it because I've come across an interesting issue I wanted others to be aware of if they came searching.

It seems the SoundChannel.position variable is reporting as a delta instead of the actual position of the sound.

For example, if you were to start a sound at 35 seconds in using playFromPosition, the SoundChannel.position variable will report the position as 0 instead of 35 like you would expect, even though it does start playing the sound at 35 seconds in.  I'm not sure if this is intended functionality, but it is a bit confusing, and it makes tracking overall sound progress during playback a bit of a chore.

Bernhard Pichler

unread,
Apr 24, 2017, 1:01:52 PM4/24/17
to BiffCornwall, StageXL
Hi Biff,

That's very interesting. I would say this is a bug, because the position should be absolute.

I will take a closer look at it.

Bernhard



--
You received this message because you are subscribed to the Google Groups "StageXL" group.

BiffCornwall

unread,
Apr 24, 2017, 1:38:44 PM4/24/17
to StageXL, brown.j...@gmail.com
It looks like the position getter is not taking startTime into account during it's calculations.

Bernhard Pichler

unread,
Aug 26, 2017, 5:16:22 AM8/26/17
to BiffCornwall, StageXL
Hi,

This is a late follow up to the problem with the SoundChannel.position - that it does not report the actual position within the Sound file, but the position relative to the startTime of the sound. After looking at the code, this is actually the intended behavior of the SoundChannel.position property. The reason is that the startTime parameter for the SoundChannel is used for SoundSprites, where the user creates one big Sound file which contains many small sound snippets. When the user plays those sound snippets we use the startTime parameter of the SoundChannel constructure and here it makes perfect sense that the position is relative to the startTime parameter.

But of course this does not help if you have a Sound object and want to start a SoundChannel at a given position. Therefore StageXL 1.3 adds the SoundChannel.position setter. So you can play a Sound with the standard Sound.play() method, and immediately set the desired position within the Sound.

Hope this works for all use cases!

Bernhard


BiffCornwall <brown.j...@gmail.com> schrieb am Mo., 24. Apr. 2017 um 19:38 Uhr:
It looks like the position getter is not taking startTime into account during it's calculations.

--
You received this message because you are subscribed to the Google Groups "StageXL" group.
Visit this group at https://groups.google.com/group/stagexl.
Reply all
Reply to author
Forward
0 new messages