如何以声音静默预加载影片剪辑?

时间:2012-04-23 17:49:46

标签: actionscript-3 flash audio movieclip moviecliploader

我正在AS3中编写一个程序,并希望预装将来需要的影片剪辑。不幸的是,我遇到了一个问题:影片剪辑在加载后立即播放声音(在我将它们添加到舞台之前)。

一旦加载几乎就停止影片剪辑解决问题,但有时我仍然会听到剪辑的开头。显然,剪辑在开始之前不会等待已完成的事件处理程序完成...?

// example of stopping a clip after it is loaded
// sound may still be heard for a moment
var loader: Loader = new Loader();
loader.addEventListener(Event.COMPLETE, function(e : *) : void {
    (loader.contentLoaderInfo.content as MovieClip).stop();
});
loader.load("a_loud_movie_clip.swf");

我还考虑在加载剪辑时将所有内容静音,但这对于可以播放声音的时候对程序的其余部分施加了相当严格的限制。

这个问题有标准解决方案吗?我觉得这应该是一个非常普遍的问题。

1 个答案:

答案 0 :(得分:3)

您是否正在预加载,因为您的SWF位于Web服务器上?如果是这样,一个选项是从服务器预加载字节而不使用URLLoader实际解释它们。然后,当您需要显示MovieClip时,使用Loader.loadBytes将预加载的字节(URLLoader.data)注入Loader以实际实例化MovieClip(并开始播放,声音和所有)。在实例化时间可能会有一个小的延迟,但它会比没有预加载器时小得多。

根据您关于loader.content类型的问题:

package
{
  import flash.display.Sprite;
  import flash.display.Loader;
  import flash.display.Bitmap;
  import flash.display.MovieClip;
  import flash.events.Event;
  import flash.utils.ByteArray;
  import flash.utils.getQualifiedClassName;

  public class tst extends Sprite
  {
    [Embed(source="any_image.png", mimeType="application/octet-stream")]
      private var img_bytes:Class;

    [Embed(source="any_swf.swf", mimeType="application/octet-stream")]
      private var swf_bytes:Class;


    public function tst():void
    {
      var b1:ByteArray = new img_bytes();
      var l1:Loader = new Loader();
      l1.contentLoaderInfo.addEventListener(Event.COMPLETE, function():void {
        trace(getQualifiedClassName(l1.content));
        trace(l1.content is Bitmap);
      });
      l1.loadBytes(b1);

      var b2:ByteArray = new swf_bytes();
      var l2:Loader = new Loader();
      l2.contentLoaderInfo.addEventListener(Event.COMPLETE, function():void {
        trace(getQualifiedClassName(l2.content));
        trace(l2.content is MovieClip);
      });
      l2.loadBytes(b2);

    }
  }
}

(注意:这只是演示代码 - 不要像这样添加带有函数闭包的事件监听器,它会导致内存泄漏。我也跳过URLLoader并简单地嵌入来获取我的字节,但它们是无论如何都是相同的字节。)

输出是:

flash.display::Bitmap
true
test_fla::MainTimeline
true

但是,Bitmap和MovieClip不是loader.content的唯一选项 - 加载从代码编译的SWF可以从Sprite派生,并且可以显示完全限定的类名,尽管www0z0k指出,它们都是派生的来自DisplayObject。虽然我相信Flash Professional的任何SWF输出总是来自MovieClip。

根据您的说明,Loader字节始终为MovieClips

事实证明你是对的 - 加载常规旧图像的Loader,contentLoaderInfo.bytes属性包含生成的SWF的字节,SWF是一个简单的MovieClip包装器,图像为Child。谁会想到?!

  var l3:Loader = new Loader();
  l3.contentLoaderInfo.addEventListener(Event.COMPLETE, function():void {
    trace("- l3:");
    trace(getQualifiedClassName(l3.content));
    trace(l3.content is Bitmap);

    // This ByteArray is a SWF!
    var b3:ByteArray = l3.contentLoaderInfo.bytes;

    var l4:Loader = new Loader();
    l4.contentLoaderInfo.addEventListener(Event.COMPLETE, function():void {
      trace("- l4:");
      trace(getQualifiedClassName(l4.content));
      trace(l4.content is Bitmap);
      trace(Object(l4.content).getChildAt(0) is Bitmap);
    });
    l4.loadBytes(b3);
    addChild(l4);

  });
  l3.load(new URLRequest("any_image.png"));

输出是:

- l3:
flash.display::Bitmap
true
- l4:
flash.display::MovieClip
false
true