Update (2/25/2008): This bug has been fixed as of Flash Player version 10.0.22.87. Download the new version from Adobe: http://get.adobe.com/flashplayer/
Problem:
Flash Player 10 distorts sounds sampled higher than 44KHz when using the loadSound function within ActionScript 2.0. This is a problem since many of the Flash mp3 players that exist today are written with AS 2.0 using this function: soundContainer.loadSound(urltoplay, true);
Solution:
There are three solutions to this problem. One is to re-sample all of your audio down to 44KHz, which very few people are willing to do. Adobe’s official fix is to set the stream property on the loadSound method to false, however, with this fix users must wait until the sound is completely loaded before they will hear anything.
That brings us to the third and in most cases, the best solution: re-write the audio player in AS 3.0. To start lets take a look at how AS 2.0 handles mp3 playback…
var my_sound:Sound; var song = "demo.mp3"; function playMusic () { my_sound = new Sound(); my_sound.loadSound(song, true); } function stopMusic () { my_sound.stop(); }
Simple enough. The problem is that if a user has Flash Player 10 and tries to play a 48KHz sampling rate the sound is distorted and has popping and clicking sounds.
If you are interested in implementing Adobe’s official fix of setting the stream property to false you would have this:
function playMusic () { my_sound = new Sound(); my_sound.onLoad = function(success:Boolean) { if (success) { my_sound.start(); } }; my_sound.loadSound(song, false); }
You can try this fix out to see if it will work for your needs. If you prefer to allow your users to continue to stream the audio files as they load, your code would look like this:
import flash.media.Sound; import flash.media.SoundChannel; import flash.net.URLRequest; var song = "demo.mp3"; var snd:Sound = new Sound(); var channel:SoundChannel = new SoundChannel(); function playMusic(songSource:String){ var req:URLRequest = new URLRequest(song); snd = new Sound(); snd.load(req); channel = new SoundChannel(); channel = snd.play(); } function stopMusic() { channel.stop(); }
If you are concerned about having to re-write a whole mp3 player UI just to fix the audio playback code you may want to consider using javascript to bridge AS 2.0 and AS 3.0. This would allow you to play 48KHz audio files without having to re-write a whole flash mp3 player.
Here is a link to Adobe’s official bug site:
Adobe
ActionScript 3.0 Sound API
LiveDocs
And a couple of people that have implemented this fix:
Mike Breidegam
Noel Webb
Feel free to contact me or leave a comment if you have any questions about this implementation of the Sound class in ActionScript.
A little more information about 44.1 vs 48 KHz audio:
“There is relatively little difference in audible quality between 44.1KHz and 48KHz, since the slight increase in frequency response is outside the range of human hearing.” And, “the improvement from 44.1 to 48 is marginal at best.” However, “It also happens to be fairly difficult to do a good conversion from 48KHz to 44.1KHz…”
Hi,
Thanks a lot for the tip.
I have ran into another problem with the AS3 Sound API,
I’m trying to make a MP3 streaming server (check the url : http://yaass-project.sourceforge.net/).
On some case, the playing will just stop despite all the stream being loaded on the client side.
And when i go forward on the track (the player have this feature) it will play again.
(Using the third method :
var req:URLRequest = new URLRequest(song);
snd = new Sound();
snd.load(req);
channel = new SoundChannel();
channel = snd.play();
)
It seems that the SOUND_COMPLETE event is firing too early.
And the fact is that i dont want to rely on this event to end the playback (or to skip to the next track) since i also implemented a crossfading feeature (still buggy right now )
Do you have any idea or clue ?
I tried to find some resoucrces or tutos on this and find only this blog
Thanks in advance
— Sven
You could use a timer to check the current SoundChannel.position against the total length of the song. When the position nears the length of the song you could fire off the cross fade effect. I’ve noticed that the Sound.length property isn’t always accurate until the song has completely loaded (which may be part of the problem with the SOUND_COMPLETE event firing to early). You may want to look into using the id3 property for length or maybe just wait until the song has completely loaded before doing the comparison.
Hey,
Thanks for your quick reply.
I’m already using a timer to check the track length. qnd to start the fade out before the end of the track.
I think I’ll use also the SOUND_COMPLETE event to prevent the “middle track stop” bug.
Coz after all only a few percent of my mp3s are concerned with this issue… (maybe these are corrupted files or sth like this…)
I’ll also check the track length against the ID3 property after the stream has completly loaded.
Again, many thanks for pointing these directions.
Cheers,
— Sven
Did this get fixed? According to the bug page on Adobe, the latest version of Flash fixes this:
http://bugs.adobe.com/jira/browse/FP-862
Can anyone confirm this?
Regards,
David
Yup! Adobe released a new version of Flash Player 10 (10.0.22.87) on 02/24/08 that fixed this bug. I tested a few 48KHz audio files with an AS2 sound player and they sounded great.
I recently came across your blog and have been reading along. I thought I would leave my first comment. I don’t know what to say except that I have enjoyed reading. Nice blog. I will keep visiting this blog very often.
Miriam
http://www.craigslistguide.info
We had the same issue on our free flash mp3 player ( http://beta.flabell.com/products/details/29/name:Flash-Mp3-Player-beta/#comments ) and the solution was to encode the sound under 44 Khz, and it works without any issues. Thanks for the tip!
Hi all
I copied this code in the fist frame, but my sound dosen’t play.
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.net.URLRequest;
var song=”som48.mp3″;
var snd:Sound = new Sound();
var channel:SoundChannel = new SoundChannel();
function playMusic(songSource:String) {
var req:URLRequest=new URLRequest(song);
snd = new Sound();
snd.load(req);
channel = new SoundChannel();
channel=snd.play();
}
function stopMusic() {
channel.stop();
}
How to play this?
Any suggestions?