It never shocks me when I run into bugs in the Flash player, even though it distresses me. On that note and for anyone in the know, the Sound object (flash.media.Sound) is riddled with bugs. The one I ran into most recently has to do with Sound’s isBuffering property.
DEFINING THE FUNCTIONALITY
So what is buffer? Simply defined it is a cushion. In the case of Sound, it is a specified time span cushion that you want to have loaded before playing. If you set the buffer to 5 seconds, no data is loaded, the Sound will only start once 5 seconds has loaded (isBuffering is true). This can happen at any point while playing and will cause playback to pause while buffering. In the case where you are 30 seconds in and have completely played out all data that has been loaded but are still loading data, the buffer is said to be empty and you begin buffering again (isBuffering is true). However, if you seek back to 0 seconds at this point, 0 to 5 is already cached so you return to a playing state (isBuffering is false)
To provide a little history, in AS2, the player’s way with dealing with Sound buffer was to provide a global property _soundbuftime. This implementation was somewhat comedic, in that it did not actually buffer the data for the Sound, it just buffered the time before play. If you were loading a Sound, set the _soundbuftime to 10, loaded 2 seconds into the buffer in the span of 10 seconds, it would play whatever it had loaded in that 10 seconds (in this case 2 seconds). Fun right?
AS3 actually creates a true data buffer for loaded Sounds via the SoundLoaderContext. In the example script below, the MP3 is loaded from a remote server with a buffer of 3 seconds (NOTE: SoundLoaderContext is specified in milliseconds, the default is 1 second)
snd.load(new URLRequest("http://server.com/test.mp3", new SoundLoaderContext(3000, false));
Since this actually provides the true data buffer, the new isBuffering property of the Sound object returns a Boolean (true or false). This is great and a large improvement from what we were previously provided in terms of an API.
So where is the BUG you ask? Well there are actually 2.
- The first bug’s use case is : if you have loaded a Sound partially or completely to cache, upon reloading it, the isBuffering property will incorrectly report true. This is the case even though it may have 30 seconds in the buffer when only a 1 second buffer is set. This isn’t to big of a deal, though it means you could be showing buffering states when not needed.
- The second bug’s use case is : if you are loading a Sound, it has enough data to play, and plays to a point where it starts buffering, and then you seek to a cached position. For example, my buffer is set to 5 seconds, I’ve loaded and played 10 seconds, I’ve started buffering at 10 seconds, and seek back to 0. At this point I should be able to play through to 10 seconds again and isBuffering should report false until I reach that point where I don’t have enough data to play again. Unfortunately, this is not the case. isBuffering continues to report true, playback is paused, and only until the 10-15 second span is loaded will the Sound start playing from 0.
As you can see the isBuffering property is a great addition to the API, but you can’t actually rely on it. In essence, it makes it useless and I wouldn’t rely on it for determining buffer. Sorry kids 🙁