如何以静默方式预加载有声音的影片剪辑?
Posted
技术标签:
【中文标题】如何以静默方式预加载有声音的影片剪辑?【英文标题】:How do I silently preload a movie clip with sound? 【发布时间】:2012-05-04 08:42:17 【问题描述】:我正在用 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】:您是否因为 SWF 位于网络服务器上而进行了预加载?如果是这样,一种选择是从服务器预加载字节,而不使用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 指出的那样,它们都是派生的从显示对象。虽然我相信任何来自 Flash Professional 的 SWF 输出总是来自于 MovieClip。
请注意,Loader 字节始终是 MovieClips
事实证明你是对的 - 一个加载常规旧图像的加载器,contentLoaderInfo.bytes 属性包含生成的 SWF 的字节,该 SWF 是一个简单的 MovieClip 包装器,图像作为子级。谁会猜到?!
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
【讨论】:
这正是我一直在寻找的东西。 相关问题:如果我实际上没有加载对象,那么确定它是否应该是图像的最佳方法是什么?过去我注意到加载图像数据的字节数组会产生一个影片剪辑。 我不确定我是否完全理解你的问题,但是你在使用 Loader.loadBytes 后你会得到一个 Event.COMPLETE,此时 Loader.content 应该是一个位图(如果字节例如,是 JPEG 或 PNG)或 MovieClip(如果字节是 SWF),因此您会知道是否可以与它交互(停止/播放)。Loader.content
是 DisplayObject
,而不是 MovieClip
真的
好吧,我试试。上次我尝试存储字节数组并稍后加载它时,它不断将图像转换为影片剪辑。我通过检查字节数组来自的内容类型来解决它。以上是关于如何以静默方式预加载有声音的影片剪辑?的主要内容,如果未能解决你的问题,请参考以下文章