AS3中与声音控制有关的类有以下几个:
| 类 | 说明 |
1 | Sound类允许您在应用程序中使用声音。 | |
2 | SoundChannel类控制应用程序中的声音。 | |
3 | SoundMixer类包含 SWF 文件中全局声音控件的静态属性和方法。 | |
4 | SoundTransform类包含控制音量和平移的属性。 | |
5 | SoundLoaderContext类为加载声音的 SWF文件提供安全检查。 | |
6 | SoundCodec类是在设置 Microphone类的 codec属性时使用的常量值的枚举。 | |
7 | ID3Info类包含反映 ID3元数据的属性。 |
我们最常用的是该对象并播放该文件、关闭声音流,以及访问有关声音的数据,如有关流中字节数和 ID3元数据的信息。可通过以下项对声音执行更精细的控制:声音源(声音的 SoundChannel或 Microphone对象)和 SoundTransform类中用于控制向计算机扬声器输出声音的属性。前4个类,现在我们对以上各类的功能及使用一一学习。
一、Sound类:
AS3.0帮助文件中对Sound类做如下说明:
Sound类允许您在应用程序中使用声音。使用 Sound类可以创建新的 Sound对象、将外部 MP3文件加载到
理解:
这段文字告诉我们,一旦我们实例化Sound对象,就是告诉程序:我要使用声音文件了,实际上是一种授权,就是Sound对象授权程序可以使用声音文件,而且声音文件的使用也得靠Sound对象自己来完成,比如加载声音文件、播放声音文件、关闭声音流等工作都是由Sound对象自己来完成的。如果还要对声音文件进行更精细的控制,就得借助于其它相关类,比如,要控制声音的左右声道和播放位置就要借助于SoundChannel类,要控制音量就得借助于SoundTransform类。
以下示例演示如何告知程序要使用声音文件并加载、播放该声音文件:
准备工作:
在同一文件夹内放放一首MP3音乐,并新建一个fla文件,fla文件的场景中拖入一个按钮实例名分别为pl_btn,选中第一帧,打开动作面板,输入以下代码:
var url:URLRequest=new URLRequest("你怎么说.mp3");
//定义URLRequest对象,指定声音文件地址
var mySound:Sound=new Sound();
//定义Sound对象,告诉程序将要使用声音文件
mySound.load(url);
//Sound对象加载声音文件
pl_btn.addEventListener(MouseEvent.CLICK,onCLICK);
function onCLICK(e:MouseEvent) {
mySound.play();
//Sound对象播放声音文件
}
测试效果,源文件见所附文件夹内“认识Sound类”文件,至于对声音文件的更精细控制我们将在以后学习。
在 Flash Player 10和更高版本中,也可以使用此类来处理动态生成的声音。在这种情况下,Flash Player将使用您分配给 sampleData事件处理程序的函数来轮询声音数据。从用声音数据填充的 ByteArray对象检索声音的同时播放声音。可以使用 Sound.extract()从 Sound对象中提取声音数据,然后在将声音数据写回到流以进行播放之前可以对其进行操作。
示例一:(动态生成正弦声音)
新建fla文件,打动作面板,输入以下代码:
var mySound:Sound = new Sound();
//定义空的声音对象mySound,告知程序要使用声音文件
mySound.addEventListener(SampleDataEvent.SAMPLE_DATA, sineWaveGenerator);
//mySound对象添加SampleDataEvent侦听器
mySound.play();
//播放声音时播放器将继续发送SampleDataEvent事件,类似侦频事件,只要声音播放,就会不停的触发SampleDataEvent事件
function sineWaveGenerator(e:SampleDataEvent):void {
for (var i:int = 0; i < 8192; i++) {
var n:Number=Math.sin(i*180/Math.PI);
e.data.writeFloat(n);
}
}S
//此函数使用writeFloat()方法写入数据n到ByteArray对象 (e.data)。
测试效果,源文件见所附文件夹内“动态生成声音”文件。
说明:以上代码中Sound对象并不包含声音数据,他只是通过SampleDataEvent.SAMPLE_DATA事件侦听sineWaveGenerator函数,而sineWaveGenerator函数生成声音数据通过BytesArray对象的writeFloat方法写入到BytesArray对象中去,然后再由Sound对象检索BytesArray对象对象中的声音数据并播放。此过程中只要声音不停止,就会持续发送SampleDataEvent事件,持续执行sineWaveGenerator函数为Sound对象提供声音数据,一旦停止声音播放,如SoundChannel.stop()
,就会停止发送事件。
使用 Sound.extract()方法提取 Sound对象中的数据。可以使用(和修改)该数据,将其写入另一个 Sound对象的动态流以进行播放。例如,以下代码使用加载的 MP3文件的字节,并通过过滤函数 upOctave()进行传递:
示例二(修改已知声音文件数据并播放,起到快进效果)
var mySound:Sound = new Sound();
//创建空的Sound类对象待注入数据用于最后播放
var sourceSnd:Sound = new Sound();
//创建空的Sound类对象(源对象)用于加载已有的声音文件
var urlReq:URLRequest=new URLRequest("你怎么说.mp3");
sourceSnd.load(urlReq);
//源对象加载声音文件“你怎么说.mp3”
sourceSnd.addEventListener(Event.COMPLETE, loaded);
//源对象添加加载完成侦听事件
function loaded(event:Event):void {
mySound.addEventListener(SampleDataEvent.SAMPLE_DATA, processSound);
//待注入数据声音对象添加SampleDataEvent侦听事件,以注入数据
mySound.play();
//播放声音文件并继续触发SampleDataEvent侦听事件,以不断地注入数据
}
function processSound(event:SampleDataEvent):void {
var bytes:ByteArray = new ByteArray();
//实例化ByteArray对象用以从源对象提取数据
sourceSnd.extract(bytes, 8192);
//ByteArray对象从源对象提取数据
event.data.writeBytes(upOctave(bytes));
//注入数据
}
function upOctave(bytes:ByteArray):ByteArray {
var returnBytes:ByteArray = new ByteArray();
bytes.position=0;
while (bytes.bytesAvailable > 0) {
returnBytes.writeFloat(bytes.readFloat());
returnBytes.writeFloat(bytes.readFloat());
if (bytes.bytesAvailable>0) {
bytes.position+=8;
}
}
return returnBytes;
}
测试效果,源文件见所附文件夹内“修改已有声音文件并播放”文件。
若要控制嵌入到 SWF文件的声音,请使用 SoundMixer类中的属性。
理解:所谓嵌入到 SWF文件的声音是指导入到flash软件库中的声音,以拉到时间轴或按钮上,或在库中链接类名使用的声音文件,
注意:ActionScript 3.0的 Sound API与 ActionScript 2.0不同。在 ActionScript 3.0中,将无法采用声音对象并在层次结构中对其进行排列以控制其属性。
使用此类时,请考虑 Flash Player安全模型(这些考虑不适用于动态生成的声音):
如果执行调用的 SWF文件在网络沙箱中,并且要加载的声音文件是本地文件,则不允许加载和播放声音。
默认情况下,若执行调用的 SWF文件是本地文件并且试图加载和播放远程声音,则不允许加载和播放声音。用户必须授予明确许可以允许该操作。
某些处理声音的操作受到限制。除非您实现一个 URL策略文件,否则位于其他域中的 SWF文件无法访问已加载声音中的数据。受此限制约束的与声音相关的 API为Sound.id3、SoundMixer.computeSpectrum()、SoundMixer.bufferTime和 SoundTransform类。
以上黑字部分是对Sound类的总体说明,下面将具体学习此类的各种方法、属性及相关事件。
㈠属性:帮助文件中有以下属性
属性 | 定义方 | |
1 | [只读 (read-only)]返回此声音对象中当前可用的字节数。 | Sound |
2 | [只读 (read-only)]返回此声音对象中总的字节数。 | Sound |
3 | [只读 (read-only)]提供对作为 MP3 文件一部分的元数据的访问。 | Sound |
4 | [只读 (read-only)]返回外部 MP3 文件的缓冲状态。 | Sound |
5 | [只读 (read-only)]当前声音的长度(以毫秒为单位)。 | Sound |
6 | [只读 (read-only)]从中加载此声音的 URL。 | Sound |
⑴bytesLoaded : uint
⑵bytesTotal : int
这两个属性分别返回声音对象的当前可用字节数和总字节数,此处“当前”二字值得我们注意,当我们使用嵌入声音或本地加载声音时,会感觉不到bytesLoaded与bytesTotal的区别,因为声音文件已经存在于SWF文件中,或瞬间加载到SWF文件中,所以它们的输出值相同,只有在网络加载某些声音文件时才有可能感觉到二者的区别,这里说可能,是因为如果网络资源好的话也会瞬间加载完成,从而感觉不到二者区别,最好找一个网络资源比较差的声音文件加载,才能明显感觉二者的区别,网络资源越差越好。这种情况下,当前bytesLoaded也就是指已加载声音文件字节数,所以帮助文件中说bytesLoaded通常只对从外部加载的文件有用。而我通过测试敢说它不仅只对外部加载有用而且只对网络加载有用,只对网络资源差的声音文件加载有用。而bytesTotal做为一个声音文件的属性可以在加载一开始的时候就能读出来,而且从开始到结束都可以读出来。
示例一:(网络加载歌曲并输出当前加载字节数)
var sound:Sound=new Sound();
sound.load(new URLRequest("http://singsong.us/cms/files/chuangmatou.mp3"));
sound.addEventListener(Event.COMPLETE,c);
function c(e:Event) {
sound.play();
trace(sound.bytesTotal)
}
addEventListener(Event.ENTER_FRAME,f);
function f(e:Event) {
trace("已加载字节数:"+"*******************"+sound.bytesLoaded+"总字节数:"+sound.bytesTotal);
}
测试效果,输入以下结果:
已加载字节数:*******************0总字节数:0
已加载字节数:*******************0总字节数:4351246
已加载字节数:*******************0总字节数:4351246
已加载字节数:*******************262144总字节数:4351246
已加载字节数:*******************917504总字节数:4351246
已加载字节数:*******************1572864总字节数:4351246
已加载字节数:*******************2162688总字节数:4351246
已加载字节数:*******************2621440总字节数:4351246
已加载字节数:*******************3276800总字节数:4351246
已加载字节数:*******************3604480总字节数:4351246
已加载字节数:*******************3997696总字节数:4351246
加载完成时显示总字节数为:4351246
并不是每次输出都是以上结果,因为每次加载的时候网络状况并不一样,所以输出数据也不一样。以上输出结果第一行没有读出来总字节数是因为还没有加载到声音文件,因为从开始加载声音文件到加载到一点点声音文件需要一个过程。此效果源文件见所附文件夹内“bytesLoaded属性”文件
示例二:(外部加载声音进度条)
var sp0:Sprite=new Sprite();
addChild(sp0);
sp0.x=sp0.y=50;
var g0:Graphics=sp0.graphics;
g0.lineStyle(3,0x00ff00);
g0.drawRect(0,0,200,20);
var sp1:Sprite=new Sprite();
addChild(sp1);
sp1.x=sp1.y=50;
var g1:Graphics=sp1.graphics;
var txt:TextField=new TextField();
addChild(txt);
txt.y=50;
txt.autoSize="left";
txt.text="0%";
txt.x=150-txt.width/2;
var sound:Sound=new Sound();
sound.load(new URLRequest("http://singsong.us/cms/files/chuangmatou.mp3"));
sound.addEventListener(Event.COMPLETE,c);
function c(e:Event) {
sound.play();
}
addEventListener(Event.ENTER_FRAME,f);
function f(e:Event) {
var i:Number=sound.bytesLoaded;
var j:Number=sound.bytesTotal;
if (j!=0) {
var k:Number=i/j*200;
g1.clear();
g1.beginFill(0xff0000);
g1.drawRect(0,0,k,20);
var n:Number=int(k/2);
txt.text=n+"%";
txt.x=150-txt.width/2;
}
if (i==j&&i!=0) {
removeEventListener(Event.ENTER_FRAME,f);
g1.beginFill(0xff0000);
g1.drawRect(0,0,200,20);
}
}
测试效果,要想看到很好的效果,也应该找一个资源比较差的网络声音文件,我这个测试加载时间大概在二十分钟左右,过期可不一定行了啊,如果第二次测试进度直接百分百,请清除IE所有临朝文件再测试。因为第一次完整测试之后,声音文件已全部下载到IE临时文件夹了。
此效果源文件见所附文件夹内“加载进度条”文件。
提供对作为 MP3文件一部分的元数据的访问。 MP3 声音文件可以包含 ID3标签,ID3 标签提供有关该文件的元数据。如声音文件的类型、录制时间、长度、大小等, 如果使用 Sound.load()方法加载的 MP3 声音包含ID3 标签,则可以查询这些属性。 只支持使用 UTF-8字符集的 ID3 标签。我们可以通过下面的小例子来看看id3属性到底能为我们提供哪些元数据。
示例
示例待完成,因为找不到有ID的声音文件
判断播放器是否处于缓冲状态,缓冲是指载网络声音或视频文件时为了使播放更流畅事先下载的部分文件,便于在播放过程中调节播放流畅性。
以时间长度为单位返回声音文件的长度,时间单位是毫秒。
当前加载声音文件的地址,注意,只要有当前声音文件已加载字节数不为0的时间才能返回地址。
㈡方法:帮助文件中有以下方法
方法 | 定义方 | |
1 | Sound(stream:URLRequest = null, context:SoundLoaderContext = null) 创建一个新的 Sound对象。 | Sound |
2 | 关闭该流,从而停止所有数据的下载。 | Sound |
3 | extract(target:ByteArray, length:Number, startPosition:Number = -1):Number 从 Sound对象提取原始声音数据。 | Sound |
3 | extract(target:ByteArray, length:Number, startPosition:Number = -1):Number 从 Sound对象提取原始声音数据。 | Sound |
4 | load(stream:URLRequest, context:SoundLoaderContext = null):void 启动从指定 URL加载外部 MP3 文件的过程。 | Sound |
5 | play(startTime:Number = 0, loops:int = 0, sndTransform:SoundTransform = null):SoundChannel 生成一个新的 SoundChannel对象来回放该声音。 | Sound |
⑴Sound(stream:URLRequest = null, context:SoundLoaderContext = null)
创建一个新的声音对象,用于动态创建声音或加载声音,此方法接收两个可选参数:
①stream:URLRequest = null,是要加载声音的地址,默为为空。如果我们在创建声音对象时给定这个地址,那么该Sound对象就会自动调用load()方法加载声音文件。
如:
/var url:URLRequest=new URLRequest("你怎么说.mp3");
var sound:Sound=new Sound(url);
sound.play();
//以前效果等价于下面代码
var url:URLRequest=new URLRequest("你怎么说.mp3");
var sound:Sound=new Sound();
sound.load(url)
sound.play();
②context:SoundLoaderContext = null,MP3 数据保留在 Sound对象的缓冲区中的最小毫秒数。 在开始回放以及在网络中断后继续回放之前,Sound 对象将一直等待直至至少拥有这一数量的数据为止。默认值为1000(1秒)。
关闭该流,从而停止所有数据的下载。
⑶extract(target:ByteArray, length:Number, startPosition:Number = -1):Number
从 Sound对象提取原始声音数据。具体用法见所附文件夹内“修改已有声音文件并播放”文件。
⑷load(stream:URLRequest, context:SoundLoaderContext = null):void
启动从指定 URL加载外部 MP3 文件的过程。它接受两个参数,这两个参数功能及用法和前面的Sound()方法一样,具体请上述内容。
⑸play(startTime:Number = 0, loops:int = 0, sndTransform:SoundTransform = null):SoundChannel
生成一个新的 SoundChannel对象来回放该声音。此方法返回 SoundChannel 对象,访问该对象可停止声音并监控音量。 (若要控制音量、平移和平衡,请访问分配给声道的 SoundTransform对象。)
它接受3个参数:
① startTime:Number = 0,指定从什么时间位置播放该声音文件。
② loops:int = 0,声音循环回startTime
值的次数。或者说是声音重复播放次数。
③ sndTransform:SoundTransform = null分配给该声道的初始 SoundTransform对象。默认值为空,此参数控制声音对象的音量、平移和平衡。这个参数的说明会在以后实例中体现。
㈢事件
事件 | 摘要 | 定义方 | |
1 | 成功加载数据后调度。 | Sound | |
2 | 在存在可用于 MP3 声音的 ID3 数据时由 Sound 对象调度。 | Sound | |
3 | 在出现输入/输出错误并由此导致加载操作失败时调度。 | Sound | |
4 | 在加载操作开始时调度。 | Sound | |
5 | 在加载操作进行过程中接收到数据时调度。 | Sound | |
6 | 当播放器请求新的音频数据时调度。 | Sound |
文章来源于百度文库