.mp3 player (spectrum 2)

by Thy forked from .mp3 player (spectrum) (diff: 308)
guyz, i dont really know if I can use those musics. They are not mine..
please warn me if i shold use those .mp3, and, if possible, where's an .mp3 a cold use :D thx
♥0 | Line 613 | Modified 2010-08-13 07:05:23 | MIT License
play

ActionScript3 source code

/**
 * Copyright Thy ( http://wonderfl.net/user/Thy )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/A1H0
 */

// forked from Thy's .mp3 player (spectrum)
// forked from Thy's .mp3 player
// guyz, i dont really know if I can use those musics. They are not mine..
// please warn me if i shold use those .mp3, and, if possible, where's an .mp3 a cold use :D thx
package 
{
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Graphics;
    import flash.display.Shape;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.filters.BlurFilter;
    import flash.filters.DropShadowFilter;
    import flash.filters.GlowFilter;
    import flash.geom.Matrix;
    import flash.geom.Point;
    import flash.system.Security;
    import flash.ui.Mouse;
    /**
     * ...
     * @author Thi
     * v. 1.5
     *     
     * usa of the class:
     * There are .mp3's in websites. They can be mine (like, from webs.com)
     * or they can be not mine (like, search on bee.mp3)
     * if the site is mine, i can get the ID3 and stuff by an local .swf, Entrosa
     * else, i pretend to get it (but i wont), using an defalt EntrosaPlacebo
     *
     * sry, it still brazilian
     *
     */
    public class Main extends Sprite 
    {
        // layer
        private var
        layer0:Sprite = new Sprite(),
        layer1:Sprite = new Sprite(), // grass
        layer2:Sprite = new Sprite(),
        layer3:Sprite = new Sprite(), // buttons
        layer4:Sprite = new Sprite(), // mouse
        layer5:Sprite = new Sprite(),
        layer6:Sprite = new Sprite(),
        layer7:Sprite = new Sprite() // frontground
        
        // music
        private var 
        player:MusicPlayer
        
        // mouse
        private var
        num:int = Math.random() * 10 + 5, parts:Vector.<Part> = new Vector.<Part>(num, true),
        espectro:Espectro,
        alcance:Number = Math.random() * 10 + 20,
        lastX:Number = mouseX, lastY:Number = mouseY,
        follow:Shape = new Shape(),  ang:Number = 0, alvo:Point = new Point(), alvoV:Point = new Point(),
        mousing:Boolean, secs_3:int = 0, follow_raioX:Number, follow_raioY:Number, horario:int, dire:Boolean,
        blur:BlurFilter, shadow:DropShadowFilter
        
        //
        private var
        rad_pi:Number = 180 / Math.PI
        
        // temp
        private var
        shape:Shape, sprite:Sprite,
        i:int, j:int, k:int, l:int,
        g:Graphics,
        part:Part
        
        // grass
        private var
        grass_data:BitmapData = new BitmapData(450, 150, false, 0xF0F9FF),
        grass_bm:Bitmap = new Bitmap(grass_data, "auto", true)
        
        public function Main():void 
        {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }
        
        private function init(e:Event = null):void 
        {
            removeEventListener(Event.ADDED_TO_STAGE, init);
            this.x = 8; this.y = 140 // for wonderfl print screen
            // layers
            addChild(layer0)
            addChild(layer1)
            addChild(layer2)
            addChild(layer3)
            addChild(layer4)
            addChild(layer5)
            addChild(layer6)
            addChild(layer7)
            
            // frontground
            layer7.addChild(shape = new Shape())
            g = shape.graphics
            g.lineStyle(1, 0)
            g.drawRect(0, 0, 449, 149)
            
            // music
            var links:Array = 
            [ 
            "http://thymusic.webs.com/Entrosa8.swf",
            "http://thymusic.webs.com/m/06%20Eminem%20Feat%20Rihanna%20-%20Love%20The%20Way%20You%20Lie.mp3",
            "http://thymusic.webs.com/m/13%20David%20Guetta%20&%20Chris%20Willis%20Feat%20Fergie%20&%20Lmfao%20-%20Gettin%20Over%20You.mp3",
                
            "http://thymusic.webs.com/EntrosaPlacebo6.swf",
            "http://phoenix.vlcteam.free.fr/Son/Bourrier/02 - Helicopter.mp3",
            "http://aolradio.podcast.aol.com/aolmusic/mp3s/Nirvana_AboutAGirl.mp3",
            
            "http://thethi.webs.com/Entrosa8.swf",
            "http://thethi.webs.com/m/Im%20Not%20Alone_.mp3",
            "http://thethi.webs.com/m/39%20Glee%20Cast%20-%20It's%20My%20Life-Confessions%20Pt.II.mp3"
            ]
            
            player = new MusicPlayer( this, links )
            
            var nomes:Array = 
            [
            true, // sempre quando a próxima "" for um entrosa, vc coloca o 'nome do álbum'
            "Pop",
            "LALALALA, this music I can reach the ID3, so this is not necessari", // esse nome tbm já é acesível pelo ID3
            "This one too, i can get the ID3", // esse nome já é acessível pelo ID3
            true,
            "Diversas",
            "Helicopter - Bloc Party", // this one i CANT get the ID3
            "About A Girl - Nirvana", // this neigther
            true, // agr vai ser umas que têm um entrosa no msm domínio, ou seja, os ID3 SÃO acessíveis
            "Outras", // então, se os ID3 são acessíveis, a classe, na hora de colocar um nome, só vai usar esses se o ID3 não foi acessível ^^
            "This wold be 'Im Not Alone' but it will look for the original ID3", // então pode escrever o que quiser, que o ID3 verdadeiro será mostrado
            "Blablabla, saiduhasoiduask, sería a glee - its my life" // então, nem precisa escrever (escreve null se o ID3 já for acessível)
            ]
            // manda a 'nomes' da classe ser igual à, no meu caso, a var nomes
            // então .formarNomes() organiza os nomes, da classe
            player.nomes = nomes
            player.formarNomes()
            
            // buttons
            sprite = new Sprite()
            layer3.addChild(sprite)
            g = sprite.graphics
            g.lineStyle(1, 0); g.beginFill(0); 
            g.lineTo(5, 2.5); g.lineTo(0, 5); g.lineTo(0, 0)
            g.endFill()
            sprite.scaleX = sprite.scaleY = 2
            sprite.x = 225 - 4.5 + 25; sprite.y = 10
            sprite.addEventListener(MouseEvent.CLICK, function ():void { if (player._play) { player.pause() } else { player.play() }} )
            sprite = new Sprite()
            layer3.addChild(sprite)
            g = sprite.graphics
            g.lineStyle(1, 0); g.beginFill(0)
            g.lineTo(5, 2.5); g.lineTo(0, 5); g.lineTo(0, 0); 
            g.moveTo(4.5, 0); 
            g.lineTo(9, 2.5); g.lineTo(4.5, 5); g.lineTo(4.5, 0)
            g.endFill()
            sprite.scaleX = sprite.scaleY = 2
            sprite.x = 225 - 4.5; sprite.y = 10
            sprite.addEventListener(MouseEvent.CLICK, function ():void {player.changeMusic(player.album, player.track + 1)})
            sprite = new Sprite()
            layer3.addChild(sprite)
            g = sprite.graphics
            g.lineStyle(1, 0);    g.beginFill(0)
            g.lineTo(5, 2.5); g.lineTo(0, 5); g.lineTo(0, 0)
            g.moveTo(4.5, 0)
            g.lineTo(9, 2.5); g.lineTo(4.5, 5); g.lineTo(4.5, 0)
            g.endFill()
            sprite.scaleX = -2; sprite.scaleY = 2
            sprite.x = 225 - 4.5 - 8; sprite.y = 10
            sprite.addEventListener(MouseEvent.CLICK, function ():void { player.changeMusic(player.album, player.track - 1) } )
            
            // grass
            layer1.addChild(grass_bm)
            
            // mouse
            //Mouse.hide()
            layer4.addChild(follow)
            layer4.addChild(espectro = new Espectro(alcance, 3))
            espectro.graphics.lineStyle(1, 0, .5)
            espectro.graphics.drawCircle(0, 0, alcance * .25)
            layer4.filters = [shadow = new DropShadowFilter(4, 45, 0, 1, 2, 2, 1, 1, false, true), blur = new BlurFilter()]
            layer4.mouseEnabled = false
            follow_raioX = 10
            follow_raioY = 10
            
            // parts
            i = 0
            parts[0] = new Part(mouseX, mouseY)
            while (++i < num)
            {
                parts[i] = new Part(Math.random() * 450, Math.random() * 150)
                parts[i].prev = parts[i - 1]
                parts[i-1].next = parts[i]
            }
            
            // frameRate
            new SmartPause(stage, .5, 40).start()
            
            // listener
            stage.addEventListener(Event.ENTER_FRAME, ef)
            stage.addEventListener(MouseEvent.MOUSE_MOVE, mv)
        }
        
        private function mv(e:MouseEvent):void
        {
            mousing = false
            secs_3 = 360
            follow_raioX = 150
            follow_raioY = 40
        }
        
        private var grass_shape:Shape = new Shape(),
        matrix:Matrix = new Matrix()
        
        private function ef(e:Event):void
        {
            // mouse
            mouse_ef()
            
            // grass
            if (Math.random() > .9) grass_ef()
        }
        
        private function grass_ef():void
        {
            var 
            X:Number = 0, Y:Number = 0, X2:Number = 0, Y2:Number = 0,
            R:Number = 0, A:Number = 0
            g = grass_shape.graphics
                X = espectro.x
                Y = 150//espectro.y
                A = -Math.random() * Math.PI
                R = Math.random() * 50 - 25
                X2 = X + Math.cos(A) * R //* Math.random()
                Y2 = Y - Math.random() * Math.random() * 150 + Math.sin(A) * R //* Math.random()
                g.lineStyle(1,0)
                g.moveTo(X, Y)
                g.curveTo(X2 + Math.random() * 10 - 5,Y2 + Math.random() * 20 + 5,X2,Y2)
                //g.lineTo(X2, Y2)
            grass_data.draw(grass_shape)//, new Matrix())
            g.clear()
        }
        
        private function mouse_ef():void
        {
            if (mousing)
            {
                alvo.x += alvoV.x
                alvo.y += alvoV.y
                if (alvo.x > 450) 
                {
                    alvo.x = 450 
                    if (alvoV.x > 0) alvoV.x *= -.98
                }
                if (alvo.x < 0) 
                {
                    alvo.x = 0
                    if (alvoV.x < 0) alvoV.x *= -.98
                }
                if (alvo.y > 150) 
                {
                    alvo.y = 150
                    if(alvoV.y > 0) alvoV.y *= -.98
                }
                if (alvo.y < 0) 
                {
                    alvo.y = 0
                    if(alvoV.y < 0) alvoV.y *= -.98
                }
            } else
            {
                if (--secs_3 == 0)
                {
                    trace("AE")
                    mousing = true
                    alvoV.x = Math.random() * 10 - 20
                    alvoV.y = Math.random() * 10 - 20
                    follow_raioX = Math.random() * 50 + 50
                    follow_raioY = Math.random() * 50 + 20
                }
                alvo.x = mouseX
                alvo.y = mouseY
            }
            if (++ horario > 0)
            {
                horario = -120
                dire = Boolean(Math.random() * 10 - 20)
            }
            ang += Number(dire) * Math.random() -.5
            var X:Number = Math.cos(ang)*(Math.random() * 10 + follow_raioX) + alvo.x
            var Y:Number = Math.sin(ang) * (Math.random() * 10 + follow_raioY) + alvo.y
            if (player.id3Pego) 
            {
                player.objEntrosa.getByteArray(), espectro.ba = player.objEntrosa.ba, espectro.refresh()
                var rot:Number = Math.atan2(lastY - Y, lastX - X) * rad_pi
                espectro.rotation = rot
            }
            var dx:Number = X - lastX
            var dy:Number = Y - lastY
            espectro.x = (lastX += (dx) * .05)
            espectro.y = (lastY += (dy) * .05)
            //
            g = follow.graphics
            g.clear()
            g.lineStyle(10, 0)
            part = parts[0]
            g.moveTo(part.x += (espectro.x - part.x) * .2, part.y += (espectro.y - part.y) * .2)
            i = 10
            while (part = part.next)
            {
                g.lineStyle(20/(++i * .5), 0)
                if (i % 2 == 0)
                {
                    g.lineTo((part.x += (part.prev.x - part.x) * .4),(part.y += (part.prev.y - part.y) * .4))
                } else
                {
                    g.lineStyle(1, 0)
                    g.lineTo((part.x += (part.prev.x - part.x) * .4),(part.y += (part.prev.y - part.y) * .4))
                }
            }
            //
            blur.blurX = dx*dx / 2162
            blur.blurY = dy * dy / 2162
            layer4.filters = [shadow, blur]
        }
    }
    
}


//package  
//{
    /**
     * ...
     * @author Thi
     */
    /*public*/ class Part
    {
        public var x:Number, y:Number, next:Part, prev:Part
        
        public function Part(x:Number = 0, y:Number = 0, next:Part = null, prev:Part = null) 
        {
            this.x = x
            this.y = y
            this.next = next
            this.prev = prev
            
        }
        
    }

//}


// modificado
//package  
//{
    import flash.display.Stage
    import flash.events.Event;
    import flash.events.MouseEvent;
    /**
     * ...
     * @author Thi
     * v. 1.1
     */
    /*public*/ class SmartPause //extends Object
    {
        
        public var min:Number
        public var max:Number
        
        private var stage:Stage
        private var event:int = 0
        
        public function SmartPause(stage:Stage = null, a:Number = 0,b:Number = 40) 
        {
            this.stage = stage
            min = a
            max = b
            stage.frameRate = min
        }
        //
        public function start():void
        {
            event = 1
            stage.addEventListener(MouseEvent.MOUSE_MOVE, In)
            stage.addEventListener(Event.ENTER_FRAME, count)
        }
        
        public function stop():void
        {
            if (event == 1)
            {
                stage.removeEventListener(MouseEvent.MOUSE_MOVE, In)
            }
            if (event == 2)
            {
                stage.removeEventListener(Event.MOUSE_LEAVE, Out)
            }
            event = 0
        }
        //
        private function In(e:MouseEvent = null):void
        {
            event = 2
            stage.frameRate = max
            stage.removeEventListener(MouseEvent.MOUSE_MOVE, In)
            stage.addEventListener(Event.MOUSE_LEAVE, Out)
        }
        
        private function Out(e:Event = null):void
        {
            num = -80
        }
        
        private var num:int = 0
        private function count(e:Event):void
        {
            if (event == 2)
            {
                if (++num == 0)
                {
                    event = 1
                    stage.frameRate = min
                    stage.addEventListener(MouseEvent.MOUSE_MOVE, In)
                    stage.removeEventListener(Event.MOUSE_LEAVE, Out)
                }
            }
        }
    }
//}


//package  
//{
    import flash.display.Shape;
    import flash.display.Graphics;
    import flash.utils.ByteArray;
    /**
     * ...
     * @author Thi
     * v. 1.0
     */
    /*public*/ class Espectro extends Shape
    {
        // o tipo do espectro
        public var tipo:int
        // a ba do espectro
        public var ba:ByteArray
        // a altura do espectro
        public var altura:Number
        
        // var de referência, pra ter que escrever menos..
        private var g:Graphics
        
        public function Espectro(altura:Number = 1, tipo:int = 0) 
        {
            // setup
            this.altura = altura
            this.tipo = tipo
            g = this.graphics
        }
        
        // variáveis usadas nos desenhos do spec
        private var i:int
        private var step:Number, ang:Number, alcance:Number
        
        public function refresh():void
        {
            g.clear()
            if(!ba) return;
            g.lineStyle(1,0)
            // loops
            var i:int
            //
            switch(tipo)
            {
                case 0: // linha (256)
                i = 0
                g.moveTo(0, (1 - ba.readFloat()) * altura)
                while(++i < 256) g.lineTo(i, (1 - ba.readFloat()) * altura)
                break;
                
                case 1: // linha dupla (512)
                i = 0
                g.moveTo(0, (1 - ba.readFloat()) * altura*.5)
                while(++i < 256) g.lineTo(i, (1 - ba.readFloat()) * altura*.5)
                i = 0
                g.moveTo(0, altura*.5)
                while(++i < 256) g.lineTo(i, altura*.5 + ba.readFloat() * altura*.5)
                break;
                
                case 2: // bola (256)
                i = 0
                step = 360 * Math.PI / (256 * 180), ang = 0, alcance = 0
                g.moveTo(-Math.cos(ang)*(alcance = altura*.75* ba.readFloat() + altura*.25), -Math.sin(ang)*alcance)
                while(++i < 256) g.lineTo(-Math.cos((ang += step))*(alcance = altura*.75* ba.readFloat() + altura*.25), -Math.sin(ang)*alcance)
                break;
                
                case 3: // bola dupla (512)
                i = 0
                step = Math.PI / 256, ang = 0, alcance = 0
                g.moveTo(-Math.cos(ang)*(alcance = altura*.75* ba.readFloat() + altura*.25), -Math.sin(ang)*alcance)
                while(++i < 256) g.lineTo(-Math.cos((ang += step))*(alcance = altura*.75* ba.readFloat() + altura*.25), -Math.sin(ang)*alcance)
                i = ang = 0
                g.moveTo(-Math.cos(ang)*(alcance = altura*.75* ba.readFloat() + altura*.25), -Math.sin(ang)*alcance)
                while(++i < 256) g.lineTo(-Math.cos((ang -= step))*(alcance = altura*.75* ba.readFloat() + altura*.25), -Math.sin(ang)*alcance)
                break;
                
                case 4: // bola interna (256)
                i = 0
                step = 360 * Math.PI / (256 * 180), ang = 0, alcance = 0
                g.moveTo(-Math.cos(ang)*(alcance = ((1 - ba.readFloat())*altura)), -Math.sin(ang)*alcance)
                while(++i < 256) g.lineTo(-Math.cos((ang += step))*(alcance = ((1-ba.readFloat())*altura)), -Math.sin(ang)*alcance)
                break;
                
                case 5: // bola interna (512)
                i = 0
                step = Math.PI / 256, ang = 0, alcance = 0
                g.moveTo(-Math.cos(ang)*(alcance = ((1 - ba.readFloat())*altura)), -Math.sin(ang)*alcance)
                while(++i < 256) g.lineTo(-Math.cos((ang += step))*(alcance = ((1-ba.readFloat())*altura)), -Math.sin(ang)*alcance)
                i = ang = 0
                g.moveTo(-Math.cos(ang)*(alcance = ((1 - ba.readFloat())*altura)), -Math.sin(ang)*alcance)
                while(++i < 256) g.lineTo(-Math.cos((ang -= step))*(alcance = ((1-ba.readFloat())*altura)), -Math.sin(ang)*alcance)
                break;
                
                
                
            }
        }
        
    }

//}



//package  
//{
    import flash.display.Graphics;
    import flash.display.Loader;
    import flash.display.MovieClip;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.events.ProgressEvent;
    import flash.media.Sound;
    import flash.media.SoundChannel;
    import flash.media.SoundTransform;
    import flash.net.URLRequest;
    import flash.text.TextField;
    import flash.text.TextFieldAutoSize;
    import flash.text.TextFormat;
    import flash.utils.ByteArray;
    /**
     * ...
     * @author Thi
     */
    /*public*/ class MusicPlayer extends Sprite
    {
        // variáveis setup
        public var links:Array // os links
        public var nomes:Array // os nomes das músicas
        
        // as variáveis que poderão ser retornadas
        public var string:String // palavra que o 'texto' mostrará (status ou informações)
        public var loading:Number // carregamento das musicas à ser tocada, 0 ~ 1
        public var length:Number // a estimativa da duração total da música, em milisegundos
        public var playing:Number // a estimativa do tanto da música que já foi tocado, 0 ~ 1
        public var objEntrosa:Object // variável acessível do .fla, o Entrosa
        public var id3Pego:Boolean // variável acessível do .fla, pra ver se o ID3 foi carregado
        // quando o ID3 da música é carregado, pode-se dar play, pegar o ID3, pegar espectro
        
        private var st:Sprite
        
        private var i:int, j:int, k:int // temp int
        private var s:String // temp string
        
        public function MusicPlayer(st:Sprite = null, links:Array = null, nomes:Array = null, mouseStart:Boolean = true) 
        {
            // setup
            this.st = st
            this.links = links
            this.nomes = nomes
            //
            
            formarLinks()
            //
            somC.soundTransform = somT
            //
            
            if (mouseStart)
            {
                
                st.addEventListener(MouseEvent.MOUSE_MOVE, init);
            }
        }
        
        public function formarLinks():void
        {
            var links2:Array = []
            i = -1
            while (++i < links.length)
            {
                links2[i] = links[i].concat()
            }
            links = []
            //
            // organiza melhor a indexação dos links
            i = 0; k = -1
            j = links2.length
            while (i < j)
            {
                s = links2[i]
                if (s.charAt(s.length - 3) == "s" && s.charAt(s.length - 2) == "w" && s.charAt(s.length - 1) == "f")
                {
                    // adiciona um novo entrosa
                    links.push([s])
                    ++k
                } else
                {
                    // se tiver alguma coisa escrito
                    if (s != "")
                    {
                        // adiciona uma nova música
                        links[k].push(s)
                    }
                }
                ++i
            }
            links2 = null
            
        }
        
        public function formarNomes():void
        {            
            var nomes2:Array = []
            i = -1
            while (++i < nomes.length)
            {
                nomes2[i] = nomes[i]
            }
            nomes = []
            // organiza os nomes (ID3 pré-determinado)
            i = -1, k = -1, j = nomes2.length
            while (++i < j)
            {
                s = String(nomes2[i])
                if (s == "true")
                {
                    // adiciona uma nova categoria
                    nomes.push([String(nomes2[++i])])
                    ++k
                } else
                {
                    // se tiver alguma coisa escrito
                    if (s != "")
                    {
                        // adiciona uma nova música
                        nomes[k].push(s)
                    }
                }
            }
            
        }
        
        private function init(e:MouseEvent):void
        {
            st.removeEventListener(MouseEvent.MOUSE_MOVE, init)
            start()
            st = null
        }
        
        public function start():void
        {
            // a 1° musica
            link_entrosa = links[0][0]
            track = 1
            // faz o loader
            loader()
        }
        
        private var link_entrosa:String
        private var carregou:Boolean
        private var Entrosa:Loader
        private function loader():void
        {
            // carrega o Entrosa. É ele quem na verdade manda carregar as musicas
            string = "Carregando álbum"
            Entrosa = new Loader()
            Entrosa.load(new URLRequest(link_entrosa))
            //Entrosa.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, loader_progress)
            Entrosa.contentLoaderInfo.addEventListener(Event.COMPLETE, loader_complete)
        }
        
        
        private function loader_complete(e:Event):void
        {
            // novo entrosa carregado
            string = "Álbum carregado"
            Entrosa.contentLoaderInfo.removeEventListener(Event.COMPLETE, loader_complete)
            objEntrosa = Object(Entrosa.content)
            // carrega nova musica
            newMusic()
        }
        
        private var som:Sound // a var Som, só tem uma
        private var somC:SoundChannel = new SoundChannel() // channel, posso dar pause etc
        private var somT:SoundTransform = new SoundTransform() // posso mudar o volume
        public var track:int = 0 // o index da musica à ser tocada
        
        // em qual Entrosa está a musica que está sendo tocada
        public var album:int
        
        private function newMusic():void
        {
            // arruma algumas variáveis
            carregou = false
            position = 0 // posição do play
            id3Pego = false
            tentativas = 0 // número de tentativas pra pegar o ID3 da música
            
            // arruma a música à ser tocada. É complicado porquê pode-se ter vários entrosas
            // o que considerei por 'vários álbuns'
            if (track >= links[album].length)
            {
                ++album
                if (album >= links.length)
                {
                    album = 0
                }
                track = 1
                // álbum posterior, carrega-se o novo Entrosa
                link_entrosa = links[album][0]
                loader()
            } else if (track < 1)
            {
                --album
                if (album < 0)
                {
                    album = links.length-1
                }
                track = links[album].length-1
                // álbum anterior, carrega-se o novo Entrosa
                link_entrosa = links[album][0]
                loader()
            } else 
            {
                // se não precisou trocar de álbum, é porquê não precisa carregar o novo entrosa
                newMusic2() // então continua na criação da musica
            }
        }
        
        public function changeMusic(album:int = 0, track:int = 1):void
        {
            if ((this.track != track || this.album != album) && pode_apertar)
            {
                pode_apertar = false // será true qdo o ID3 ficar pronto
                this.removeEventListener(Event.ENTER_FRAME, ef)
                somC.stop() // para o som atual
                if (!carregou)
                {
                    // se o som não estiver 100% carregado, fecha o stream
                    som.close()
                }
                
                
                this.track = track
                if (this.album != album)
                {
                    this.album = album
                    link_entrosa = links[album][0]
                    loader()
                } else 
                {
                    newMusic()
                }
            }
        }
        
        private function newMusic2():void
        {
            // vê o link da musica mp3
            objEntrosa.link = links[album][track]
            objEntrosa.loadLink() // manda o entrosa carregar o link enviado
            
            // lá no Entrosa tem uma var som. O nosso som daqui será uma referência à ela
            som = null
            som = objEntrosa.som 
            
            // listeners
            som.addEventListener(Event.COMPLETE, Lcomp) // acabou de carregar musica
            som.addEventListener(ProgressEvent.PROGRESS, Lprog) // carregando musica
            this.addEventListener(Event.ENTER_FRAME, id3) // pegando o ID3 da musica
            string = "Carregando música"
        }
        
        private function Lcomp(e:Event):void
        {
            // música totalmente carregada
            som.removeEventListener(Event.COMPLETE, Lcomp)
            som.removeEventListener(ProgressEvent.PROGRESS, Lprog)
            carregou = true
            // vê o valor do loading da música. Pode-se acessar essa var pelo .fla
            loading = 1 // 1 = 100%
            length = som.length // length real
        }
        
        private function Lprog(e:ProgressEvent):void
        {
            // vê o valor do loading da música. Pode-se acessar essa var pelo .fla
            loading = e.bytesLoaded / e.bytesTotal // 0 ~ 1
            length = som.length / loading // em milisegundos
        }
        
        private var tentativas:int // tentativas pra pegar o ID3
        private function id3(e:Event = null):void
        {
            if (objEntrosa.id3Pronto && !id3Pego)
            {
                if(objEntrosa.id3)
                {
                    string = (objEntrosa.id3.songName == null ? "Música desconhecida" : objEntrosa.id3.songName) + " - "  + (objEntrosa.id3.artist == null ? "Artista desconhecido" : objEntrosa.id3.artist)
                } else 
                if (nomes != null)
                {
                    if (nomes[album][track] != undefined)
                    {
                        string = nomes[album][track]
                    } else
                    {
                        string = "Nome da Música e Artista Inacessíveis"
                    }
                } else
                {
                    string = "Nome da Música e Artista Inacessíveis"
                }
                if(string == "Música desconhecida - Artista desconhecido")
                {
                    string = "Música e Artista desconhecidos"
                }
                
                id3Pego = true
                
                if (_play)
                {
                    somC = som.play()
                }
                
                pode_apertar = true
                this.addEventListener(Event.ENTER_FRAME, ef)
                
                //remove o listener desta função
                this.removeEventListener(Event.ENTER_FRAME, id3)
            }  else if (loading > 3 && ++tentativas > stage.frameRate+2) 
            {
                // desiste de pegar o ID3, então finge-se que o pegou, para os processos continuarem
                objEntrosa.id3Pronto = true
            }
        }
        
        public var _play:Boolean // pode-se ver se está tocando ou não
        public var pode_apertar:Boolean
        
        public var position:Number = 0
        public function pause(pos:Boolean = true):void
        {
            if (_play && pode_apertar)
            {
                _play = false
                if (pos)
                {
                    position = somC.position // guarda a posição
                } else
                {
                    position = 0 // reseta a posição
                }
                somC.stop()
            } else if (!pos && pode_apertar)
            {
                position = 0
            }
        }
        
        public function play():void
        {
            if (!_play && pode_apertar)
            {
                _play = true
                somC = som.play(position) // dá play no som, dependendo da posição
            }
        }
        
        public function volume(volume:Number = 0):void
        {
            if (somT.volume != volume)
            {
                somT.volume = volume
                somC.soundTransform = somT
            }
        }
        
        private function ef(e:Event):void
        {
            if(_play)
            {
                // calcula aposição do 'playing' (0 ~ 1)
                playing = somC.position / length
                // se a música acabar, vai pra próxima
                if (playing >= .99)
                {
                    this.removeEventListener(Event.ENTER_FRAME, ef)
                    // vai pro 'next', como se tivesse clicado no botão
                    changeMusic(album, track + 1)
                }
            }
        }
        
    }

//}

Forked