嵌入与动态加载声音

时间:2011-06-04 20:09:01

标签: actionscript-3 actionscript

只是想知道是否有人可以帮助我。我是动作脚本的新手,正在构建一个在点击按钮时播放一些声音的应用程序。

它有5个标签,并且会为用户提供每个标签播放约10个声音的选项。

我最初在运行时加载声音,所以每当用户点击按钮播放声音时,我会做类似的事情:

var sound:Sound = new Sound(new URLRequest("assets/hello.mp3"));
sound.play();

我不确定,但我认为这不是很好,因为如果用户按下按钮太多次,我会一遍又一遍地加载声音。

然后我考虑在每个视图中嵌入声音(每个标签有一个视图),因此每当加载视图时都会嵌入声音。我认为这是一个更好的选择,但仍然有点不确定嵌入是如何工作的。

[Embed('assets/hello.mp3')] private var hello_mp3:Class;

我认为它只是在swf编译时嵌入mp3文件(使其变大),但是一旦应用程序启动它们或者再次初始化该视图后它们就不再被加载了。

我的问题是:这是正确的方法吗?有没有更好的方法可以实现这一目标?是否为我的问题嵌入了正确的解决方案?

提前致谢

4 个答案:

答案 0 :(得分:2)

第一个解决方案工作正常,它不会使你的SWF变大,一旦声音被加载一次,它将被Flash Player缓存,因此声音不会一次又一次地加载。

这是一种更有效的方法,不会播放未播放的声音。

请记住,当第一次按下该按钮时,由于声音被加载,您可能会遇到轻微的延迟。

为了避免这种情况,您可以加载一些声音作为外部资源,这意味着在加载SWF之后,您可以调用一个函数来加载部分或全部声音,具体取决于应用程序的需求。您的SWF不会膨胀,按钮点击将更具响应性。

答案 1 :(得分:2)

听起来你需要一个SoundManager类或类似的东西来缓存你需要的声音,这样你就可以随时播放它们并且它们只会被加载一次。像这样的类,你只需要一个类的实例,是单身人士的好选择。有很多方法可以实现单例设计。在动作中,我最喜欢的方式是这样的:

//in SoundManager.as
public static var instance:SoundManager = new SoundManager();

简单,而且有效。由于计划是你只需要一个SoundManager,你现在可以在你的代码中的任何其他地方获得这样一个实例,如下所示:

var soundManager:SoundManager = SoundManager.instance;

//or, more likely you can just use it in-line like this
SoundManager.instance.myMethod();

所以现在你有了SoundManager。让我们设置它来保持声音的缓存,以便它们只被加载一次:

// in SoundManager.as

private var _soundCache:Array = [];

public function getSound(soundName:String):Sound {

    var testSound:Sound = _soundCache[soundName] as Sound;

    if(!testSound) {    //if the sound isn't loaded yet, testSound will be null

        //the sound isn't there, so lets load it
        var newSound:Sound = new Sound(new URLRequest(soundName));
        _soundCache[soundName] = newSound;
        return newSound;

    }

    //if we made it this far it means the sound was in the cache, so we return it
    return testSound;

}

而且,你只需加载一次声音!当你想获得声音时,它就像:

一样简单
var mySound:Sound = SoundManager.instance.getSound("mySound.mp3");

如果您遇到任何此类代码遇到问题,请告诉我,但希望这足以让您走上正确的道路。

答案 2 :(得分:1)

在我看来,您应该在开始时加载所有声音,并在任何时候可以访问的地方存储对每个声音的引用。一个简单的例子是将每个声音存储在一个数组中。我已经为这个例子创建了一个类似但更强大的应用程序:

<强> sounds.xml

<?xml version="1.0" encoding="utf-8" ?>
<sounds>
    <sound name="sound1" url="sound/sound1.mp3" />
    <sound name="sound2" url="sound/sound2.mp3" />
    <sound name="sound3" url="sound/sound3.mp3" />
    <sound name="sound4" url="sound/sound4.mp3" />
    <sound name="sound5" url="sound/sound5.mp3" />
</sounds>

Main.as(文档类):

package 
{
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.media.SoundChannel;
    import flash.net.URLLoader;
    import flash.net.URLRequest;

    public class Main extends Sprite 
    {
        private var _soundLibrary:SoundLibrary;

        public function Main():void 
        {
            if (stage) init() else addEventListener(Event.ADDED_TO_STAGE, init);

        }// end function

        private function init(e:Event = null):void 
        {
            removeEventListener(Event.ADDED_TO_STAGE, init);

            var urlLoader:URLLoader = new URLLoader(new URLRequest("xml/sounds.xml"));
            urlLoader.addEventListener(Event.COMPLETE, onUrlLoaderComplete);

        }// end function

        private function onUrlLoaderComplete(e:Event):void
        {
            _soundLibrary = new SoundLibrary(XML(URLLoader(e.target).data));
            _soundLibrary.addEventListener(Event.COMPLETE, onSoundLibraryComplete);

        }// end function

        private function onSoundLibraryComplete(e:Event):void
        {
            var soundChannel:SoundChannel = _soundLibrary.getSound("sound3").play();

        }// end function

    }// end class

}// end package


import flash.events.Event;
import flash.events.EventDispatcher;
import flash.media.Sound;
import flash.net.URLRequest;

internal class SoundLibrary extends EventDispatcher
{
    private var _xml:XML;
    private var _length:int;
    private var _counter:int;
    private var _soundLibraryItems:Vector.<SoundLibraryItem>;

    public function SoundLibrary(xml:XML):void
    {
        _xml = xml;
        _length = _xml.children().length();
        _soundLibraryItems = new Vector.<SoundLibraryItem>();

        loadSounds();

    }// end function

    public function getSound(name:String):Sound
    {
        var sound:Sound;

        for (var i:int = 0; i < _soundLibraryItems.length; i++)
        {
            if (_soundLibraryItems[i].name == name)
            sound = _soundLibraryItems[i].sound;

        }// end for

        if (!sound) throw new ArgumentError("No sound object matches specified name");

        return sound;

    }// end function

    private function loadSounds():void
    {
        for (var i:int = 0; i < _length; i++)
        {
            var sound:Sound = new Sound(new URLRequest(_xml.children()[i].@url));
            sound.addEventListener(Event.COMPLETE, onSoundComplete);    

        }// end for

    }// end function

    private function onSoundComplete(e:Event):void
    {
        _soundLibraryItems.push(new SoundLibraryItem(_xml.children()[_counter].@name, Sound(e.target)));

        if (++_counter == _length) dispatchEvent(new Event(Event.COMPLETE));

    }// end function

}// end class

internal class SoundLibraryItem
{
    private var _name:String; 
    private var _sound:Sound;

    public function get name():String { return _name }
    public function get sound():Sound { return _sound }

    public function SoundLibraryItem(name:String, sound:Sound)
    {
        _name = name; _sound = sound;

    }// end function

}// class

<强> [UPDATE]

<强>摘要

首先加载sounds.xml,然后在完成时将其解析为SoundLibrary的新实例。

SoundLibrary处理从xml加载声音,然后将每个加载的Sound对象解析为SoundLibraryItem的新实例。

SoundLibraryItem只存储Sound对象的名称以及Sound对象本身。创建所有SoundLibraryItem个对象后,SoundLibrary对象将调度Event类型为Event.COMPLETE的对象。

调度事件时,SoundLibrary对象上的事件侦听器会调用onSoundLibraryComplete()事件处理程序。

最后,SoundLibrary对象的getSound()方法用于通过Sound参数获取之前加载的name对象之一。然后使用SoundChannel对象调用Sound对象的play()方法。

答案 3 :(得分:1)

在我看来

  

嵌入东西永远不是一个approuch

优点:

  1. 您在同一个文件中有任何内容= 1次加载( 好吧,这不是真正的专业...)
  2. 缺点:

    1. 加载整个文件需要更长的时间 应用程序(用户不喜欢 等)

    2. 如果你想改变声音,你必须再次编译所有内容

    3. 可扩展性优势

    4. 我相信人们可以帮助我更多的缺点;)

    5. 希望有所帮助

相关问题