AS3 (25) 处理声音
从外部声音文件加载声音数据时,您可以在加载其余声音数据的同时开始播放声音文件的开头部分。虽然可以使用各种不同的声音文件格式对数字音频进行编码,但是 ActionScript 3.0、Flash Player 和 AIR 支持以 mp3 格式存储的声音文件。它们不能直接加载或播放其它格式的声音文件,如 WAV 或 AIFF。但从 Flash Player 9.0.115.0 开始,可使用 NetStream 类加载和播放 AAC 音频文件。使用 Adobe Flash CS4 Professional,可以导入 WAV 或 AIFF 声音文件,然后将其以 mp3 格式嵌入应用程序的 SWF 文件中。Flash 创作工具还可压缩嵌入的声音文件以减小文件大小,但会降低声音的品质。
可以使用五种方法将音频数据加载到Flash Player 或 AIR 中,以便通过 ActionScript 处理这些数据。您可以将外部声音文件(如 mp3 文件)加载到 SWF 中;可以在创建 SWF 文件时将声音信息直接嵌入到其中;可以使用连接到用户计算机的麦克风来获取音频输入;可以访问从服务器流式传输的声音数据;还可以处理动态生成的声音数据。
在 ActionScript 中处理声音时,可能会使用 flash.media 包中的某些类。Sound 类用于访问音频信息,方法是:加载声音文件或为对声音数据进行采样的事件分配函数,然后开始播放。开始播放声音后, Flash Player 和 AIR 为您提供对SoundChannel 对象的访问。因为已加载的音频文件只能是您在用户计算机上播放的几种声音之一,所以,所播放的每种单独的声音都使用自己的 SoundChannel 对象;混合在一起的所有 SoundChannel 对象的组合输出是实际通过计算机扬声器播放的声音。可以使用此 SoundChannel 实例来控制声音的属性以及停止其播放。最后,如果要控制组合音频,您可以通过SoundMixer 类对混合输出进行控制。
ActionScript 3.0 声音体系结构使用 flash.media 包中的以下类。
flash.media.Sound Sound 类处理声音加载、管理基本声音属性以及启动声音播放。
flash.media.SoundChannel 当应用程序播放 Sound 对象时,将创建一个新的 SoundChannel 对象来控制回放。SoundChannel 对象控制声音的左和右回放声道的音量。播放的每种声音具有其自己的 SoundChannel 对象。
flash.media.SoundLoaderContext SoundLoaderContext 类指定在加载声音时使用的缓冲秒数,以及 Flash Player 或 AIR 在加载文件时是否从服务器中查找策略文件。SoundLoaderContext 对象用作 Sound.load() 方法的参数。
flash.media.SoundMixer SoundMixer 类控制与应用程序中的所有声音有关的回放和安全属性。实际上,可通过一个通用 SoundMixer对象将多个声道混合在一起,因此,该 SoundMixer 对象中的属性值将影响当前播放的所有 SoundChannel对象。
flash.media.SoundTransform SoundTransform 类包含控制音量和声相的值。可以将 SoundTransform 对象应用于单个 SoundChannel 对象、全局 SoundMixer 对象或 Microphone 对象等。
flash.media.ID3Info ID3Info 对象包含一些属性,它们表示通常存储在 mp3 声音文件中的 ID3 元数据信息。
flash.media.Microphone Microphone 类表示连接到用户计算机上的麦克风或其它声音输入设备。可以将来自麦克风的音频输入传送到本地扬声器或发送到远程服务器。Microphone 对象控制其自己的声音流的增益、采样率以及其它特性。
Sound 对象调度事件描述
open (Event.OPEN) 就在声音加载操作开始之前进行调度。
progress (ProgressEvent.PROGRESS) 从文件或流接收数据时,在声音加载过程中定期进行调度。
id3 (Event.ID3) 当存在可用于 mp3 声音的 ID3 数据时进行调度。
complete (Event.COMPLETE) 在加载了所有声音资源的数据后进行调度。
ioError (IOErrorEvent.IO_ERROR) 在以下情况下进行调度:找不到声音文件,或者在收到所有声音数据之前加载过程中断。
package sound { import flash.events.Event; import flash.events.EventDispatcher; import flash.events.IOErrorEvent; import flash.events.ProgressEvent; import flash.events.SecurityErrorEvent; import flash.events.TimerEvent; import flash.media.Sound; import flash.media.SoundChannel; import flash.media.SoundLoaderContext; import flash.media.SoundMixer; import flash.net.URLRequest; import flash.utils.Timer; public class SoundFacade extends EventDispatcher { public var s:Sound; public var sc:SoundChannel; public var url:String; public var bufferTime:int = 1000; public var isLoaded:Boolean = false; public var isReadyToPlay:Boolean = false; public var isPlaying:Boolean = false; public var isStreaming:Boolean = true; public var autoLoad:Boolean = true; public var autoPlay:Boolean = true; public var pausePosition:int = 0; public static const PLAY_PROGRESS:String = "playProgress"; public var progressInterval:int = 1000; public var playTimer:Timer; public function SoundFacade(soundUrl:String, autoLoad:Boolean = true, autoPlay:Boolean = true, streaming:Boolean = true, bufferTime:int = -1):void { this.url = soundUrl; this.autoLoad = autoLoad; this.autoPlay = autoPlay; this.isStreaming = streaming; if (bufferTime < 0) { bufferTime = SoundMixer.bufferTime; } this.bufferTime = Math.min(Math.max(0, bufferTime), 30000); if (autoLoad) { load(); } } public function load():void { if (this.isPlaying) { this.stop(); this.s.close(); } this.isLoaded = false; this.s = new Sound(); this.s.addEventListener(ProgressEvent.PROGRESS, onLoadProgress); this.s.addEventListener(Event.OPEN, onLoadOpen); this.s.addEventListener(Event.COMPLETE, onLoadComplete); // this.s.addEventListener(Event.ID3, onID3); // this.s.addEventListener(IOErrorEvent.IO_ERROR, onIOError); // this.s.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onIOError); var req:URLRequest = new URLRequest(this.url); var context:SoundLoaderContext = new SoundLoaderContext(this.bufferTime, true); this.s.load(req, context); } public function onLoadOpen(event:Event):void { if (this.isStreaming) { this.isReadyToPlay = true; if (autoPlay) { this.play(); } } this.dispatchEvent(event.clone()); } public function onLoadProgress(event:ProgressEvent):void { this.dispatchEvent(event.clone()); } public function onLoadComplete(event:Event):void { this.isReadyToPlay = true; this.isLoaded = true; this.dispatchEvent(event.clone()); if (autoPlay && !isPlaying) { play(); } } public function play(pos:int = 0):void { if (!this.isPlaying) { if (this.isReadyToPlay) { this.sc = this.s.play(pos); this.sc.addEventListener(Event.SOUND_COMPLETE, onPlayComplete); this.isPlaying = true; this.playTimer = new Timer(this.progressInterval); this.playTimer.addEventListener(TimerEvent.TIMER, onPlayTimer); this.playTimer.start(); } } } public function onPlayTimer(event:TimerEvent):void { var estimatedLength:int = Math.ceil(this.s.length / (this.s.bytesLoaded / this.s.bytesTotal)); var progEvent:ProgressEvent = new ProgressEvent(PLAY_PROGRESS, false, false, this.sc.position, estimatedLength); this.dispatchEvent(progEvent); } public function stop(pos:int = 0):void { if (this.isPlaying) { this.pausePosition = pos; this.sc.stop(); this.playTimer.stop(); this.isPlaying = false; } } public function pause():void { stop(this.sc.position); } public function resume():void { play(this.pausePosition); } function onPlayComplete(event:Event) { } } }