Sound.position “Gotcha” with Multiple Calls to Sound.loadSound()
The Sound.position property indicates how far along a Sound instance has played. If you’ve loaded an external file or attached an embedded file at runtime, but haven’t yet started it, that instance’s position property is 0. If it’s a 10-second clip and you’re 2.5 seconds in, the property reads 2500 (that’s 2,500 milliseconds). When your audio reaches its end, position will match that instance’s Sound.duration property, which indicates the total length of the audio. This is a can be useful for checking when a sound has concluded — of course, the Sound.onSoundComplete event is much more straightforward — but there are any number of reasons you might want to keep tabs on a sound’s position. Unfortunately, this property doesn’t always report the value you may expect.
The Sound.loadSound() method loads audio files (specifically MP3s) that are external to the SWF. This method takes two parameters. The first indicates the location of the MP3 file; the second is optional and determines whether or not the audio plays in stream mode. The word is a bit misleading in this context, because loaded files don’t truly stream unless served by streaming server software, such as Flash Media Server. If simply loaded from the server’s file system, the MP3 will progressively download, which means it can begin playing before the entire file has been retrieved. Comes in handy.
The problem is, any subsequent call to loadSound() — for the same instance — leaves the position value where it was at the time the call was made. Personally, I would expect it to start again from zero, because the new file starts from the beginning (when enough of the file has loaded).
In other words, in the following code …
var song:Sound = new Sound();
song.loadSound("looneyTunesTheme.mp3", true);
… the specified MP3 starts playing as soon as enough of the file has arrived. If you monitor song.position, you’ll see it grow from zero until the end of the song. If you happen to load a new file at, say, seven seconds in …
setTimeout(function():Void {
song.loadSound("tronTheme.mp3", true);
}, 7000);
… the instance’s duration value will change — assuming each song has a different length — but its position value will keep trucking from 7000 onward.
Play this new song for several seconds, then jump back …
setTimeout(function():Void {
song.loadSound("looneyTunesTheme.mp3", true);
}, 45000);
… and position just keeps climbing. The only thing that stops it is the end of the audio. When position’s value reaches the duration value of the currently loaded file, position plumb stops updating, even if the file continues to play. Remember, this isn’t because position is actually the same as duration: because of several seconds of the other MP3 playing, the position property was thrown off.
I’m not even sure if this phenomenon is a bug or a feature, to be honest. Regardless, is there a way to “fix” it? The answer is yes.
Just before you issue a second (or third, etc.) call to loadSound(), be sure to call Sound.start() first, and pass in the optional secondsOffset parameter. That resets position.
// … existing code
song.start(0);
song.loadSound("aintNoMountainHighEnough", true);
February 1st, 2007 at 3:57 pm
But if you just call the start function on the last sound object created it will just jump to the position you want…why re-load the same song? I had this same problem and just realized that you need to offer a scrubber for each song so they can go to 0 or 100% of the song, or go to another song…shrug, maybe i am misunderstood what you are saying.
February 1st, 2007 at 4:05 pm
Chris,
I may not have been especially clear on this one. That code sample at the end is loading a new song into the same
Soundinstance. In this case, I was using a singleSoundinstance to load dozens of audio files, and the problem was that theSound.positionproperty failed to start at zero with each new file. Maybe theSoundclass is designed that way, but it’s not what I was expecting. So thestart()call provides that “reset” and the immediateloadSound()call loads the next song so quickly, there isn’t enough time to hear anything from the previous file. Which solved my problem.February 14th, 2008 at 6:18 am
keep up the good work you are a big help
February 16th, 2008 at 6:50 pm
justin,
Thanks!