Paolo Rossi
Paolo Rossi

Reputation: 2510

ExternalInterface behavior on Chrome in win 7

I have a mp3player swf in my web site. To display the page and start playing the music when the mp3 file is loaded fully in my swf I added a function of Action Script to send a call ExternalInterface when the mp3 file has been fully loaded.

AS

private function loadMP3():void {

 ...
 ...

// Load complete function
mp3.addEventListener(Event.COMPLETE, onLoadComplete);
}


private function onLoadComplete(e:Event):void {

if (ExternalInterface.available)
    {
        ExternalInterface.call("JSCallback");
    }
}

My html jquery function

function JSCallback()
{
// Finish load swf and hide overlay
$('#loader-overlay').fadeOut('slow');
}

This method works well in Internet Explorer 8, Firefox, Chrome, Opera on XP. In win 7 on Firefox, IE 10 works well, while chrome starts playing the music before it is fully loaded and that page is displayed. Have you any idea how to solve this problem? thanks

FULL CLASS

package xxx.xxx.xxx.sound {

import flash.display.MovieClip;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.events.MouseEvent;
import flash.geom.ColorTransform;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.media.SoundMixer;
import flash.net.URLRequest;
import flash.utils.ByteArray;
import flash.text.TextField;
import flash.external.ExternalInterface;

public class MP3Player extends MovieClip {

    // Location of the config xml file
    public static const CONFIG_XML_URL:String = "xml/config.xml";

    // URL of the mp3 file
    public static var MP3_URL:String = "mp3/track.mp3";

    // Main color for the mp3 player
    public static var MAIN_COLOR:uint = 0xFF0000;

    // An XMLLoader to load the configuration file
    private var xmlLoader:XMLLoader;

    // Sound object to be played
    private var mp3:Sound = new Sound();

    // A sound channel to play the sound object
    private var channel:SoundChannel;

    // Holds the pause position
    private var pausePos:Number;

    // A byte array to read spectrum
    private var bytes:ByteArray = new ByteArray();

    // Indicates whether the mp3 player is playing or not.
    private var _isPlaying:Boolean = false;

    // Holds the previous label color
    private var _prevColor:uint;        

    public function MP3Player() {

        // Initialize the player
        init();

    }

    /**
     * Initializes the player.
     */
    private function init():void {

        // Use as a button
        useHandCursor = true;
        buttonMode = true;
        mouseChildren = false;
        equalizer.alpha = 0;

        // Add necessary event listeners
        addEventListener(Event.ENTER_FRAME, onEnterFrame, false, 0, true);
        addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown, false, 0, true);
        addEventListener(MouseEvent.MOUSE_OVER, onMouseOver, false, 0, true);
        addEventListener(MouseEvent.MOUSE_OUT, onMouseOut, false, 0, true);
        loadConfig();

    }

    /**
     * Sets the color of the player to the given parameter.
     */
    public function setColor(color:uint):void {

        MAIN_COLOR = color;

        // Change the color of the equalizer
        var colorTransform:ColorTransform = equalizer.transform.colorTransform;
        colorTransform.color = MAIN_COLOR;
        equalizer.transform.colorTransform = colorTransform;

    }


    /**
     * Loads the configuration file to the memory.
     */
    private function loadConfig() {

        // Start loading the config.xml file
        xmlLoader = new XMLLoader(CONFIG_XML_URL);
        xmlLoader.addEventListener(XMLLoader.XML_LOADED, onXMLLoaded);
        xmlLoader.load();

    }

    /**
     * This method is called when the xml file is loaded to the memory.
     */
    private function onXMLLoaded(evt:Event):void {

        // Get configuration parameters
        var xml:XML = xmlLoader.getXML();
        MP3_URL = xml.@mp3URL;
        MAIN_COLOR = xml.@color;

        // Change the color of the equalizer
        equalizer.alpha = 1;
        setColor(MAIN_COLOR);

        // Start loading the mp3
        loadMP3();

    }

    /**
     * Start loading the mp3 file.
     */
    private function loadMP3():void {

        mp3.load(new URLRequest(MP3_URL));
        mp3.addEventListener(IOErrorEvent.IO_ERROR, onIOError, false, 0, true);
        channel = mp3.play();
        channel.addEventListener(Event.SOUND_COMPLETE, onSoundComplete, false, 0, true);            
        _isPlaying = true;

        // Load complete function
        mp3.addEventListener(Event.COMPLETE, onLoadComplete);
    }

    /**
     * This method is called whenever a new enter frame event occurs.
     */
    private function onEnterFrame(evt:Event):void {

        try {
            SoundMixer.computeSpectrum(bytes, true, 0);
        } catch (e:Error) {
        }

        equalizer.update(bytes);

    }

    /**
     * This method is called when playing the sound is finished.
     */
    private function onSoundComplete(evt:Event):void {

        // Loop
        channel = mp3.play();
        channel.addEventListener(Event.SOUND_COMPLETE, onSoundComplete, false, 0, true);
        _isPlaying = true;

    }

    /**
     * This method is called when the mouse is over the mp3 player.
     */
    private function onMouseOver(evt:MouseEvent):void {

        // Change the color of the equalizer
        _prevColor = label.textColor;
        label.textColor = MAIN_COLOR;

    }

    /**
     * This method is called when the mouse leaves the mp3 player.
     */
    private function onMouseOut(evt:MouseEvent):void {

        label.textColor = _prevColor;

    }

    /**
     * This method is called when the mouse is clicked on the mp3 player.
     */
    private function onMouseDown(evt:MouseEvent):void {

        if (_isPlaying) {
            pausePos = channel.position;
            channel.stop();
            _isPlaying = false;
            label.text = "MUSIC OFF";               
        } else {
            channel = mp3.play(pausePos);
            channel.addEventListener(Event.SOUND_COMPLETE, onSoundComplete, false, 0, true);
            _isPlaying = true;
            label.text = "MUSIC ON";
        }

    }

    /**
     * This method is called when load complete and sent call to js.
     */
    private function onLoadComplete(e:Event):void {
            // This will call a JavaScript function
            //ExternalInterface.call('loadedCallback');
        if (ExternalInterface.available)
            {
                ExternalInterface.call("JSCallback");
            }

    }

    /**
     * This method is called if an IO error occurs.
     */
    private function onIOError(evt:IOErrorEvent):void {
    }

}

 }

Upvotes: 0

Views: 114

Answers (1)

Aralicia
Aralicia

Reputation: 865

Your issue is that, in the method loadMP3(), mp3.play() is called immediately after mp3.load(). This means that the music must begin as soon as possible. And for the Sound class, "as soon as possible" isn't "after the mp3 is fully charged", but "as soon as I have enough data".

If you want to delay the music until after the file is completely loaded, you must remove play() from loadMP3() and add it to onLoadComplete()

private function loadMP3():void {

    mp3.load(new URLRequest(MP3_URL));
    mp3.addEventListener(IOErrorEvent.IO_ERROR, onIOError, false, 0, true);
    /* // removed
    channel = mp3.play();
    channel.addEventListener(Event.SOUND_COMPLETE, onSoundComplete, false, 0, true);            
    _isPlaying = true;
    /**/

    // Load complete function
    mp3.addEventListener(Event.COMPLETE, onLoadComplete);
}

[...]

private function onLoadComplete(e:Event):void {
    channel = mp3.play();
    channel.addEventListener(Event.SOUND_COMPLETE, onSoundComplete, false, 0, true);            
    _isPlaying = true;
    if (ExternalInterface.available)
    {
        ExternalInterface.call("JSCallback");
    }

}

Upvotes: 1

Related Questions