ActionScript 3.0音频编程


第 20 章 音 频 编 程 音频是制作 Flash 多媒体内容不可或缺的重要组成部分, 音频内容使 Flash 变得更加丰 富多彩。ActionScript 3.0 中音频编程包括音频内容的回放和麦克风的使用。麦克风的使用 目的是为了录制音频内容,所以本章也将提及音频录制技术的部分内容。音频内容回放的 重点在于音频内容的载入和音频回放参数的控制。麦克风的使用则重点在于获取麦克风设 备的引用并对麦克风的采样参数进行调整。本章将对音频回放、麦克风的使用以及音频录 制等音频编程技术进行详细介绍。 20.1 音 频 概 述 在收音机或录音机中使用的声音都是模拟信号,模拟信号以正弦波或余弦波的形式输 入这些设备从而使它们发出声音。通过模拟信号传输的声音信号是连续的。自动多媒体计 算机出现后,声音信号就被数字化,通过二进制形式存储在磁盘或在网络中传输。 音频信号是通过麦克风输入的,从麦克风输入的音频信号也是模拟信号。把这些模拟 信号转换成计算机可以识别的数字信号的过程叫做采样。采样时计算机以一定的频率捕获 当前时间点上的音频信号,把这个信号表示成二进制形式。 根据声卡解析度的不同,例如 8 位声卡只可以把采集的音频信号表示成 8 位的二进制 形式,而 16 位显卡则可以把音频信号采集为 16 位的二进制形式。音频采集的解析度成为 采样精度,采样精度越高则采集的声音越接近原始声音。计算机采集音频信号的频率成为 采样频率,采样频率以赫兹( Hz)为单位。采样频率越高保真度也就越高, 11KHz 的采样 频率接近于电话的声音, 22KHz 的采样频率接近广播的声音, 44KHz 的采样频率则接近 CD 音效。 由于通过采样得到的音频数据很大,不利于存储和网络传输。这样就需要通过一定的 压缩算法对采集的音频数据进行压缩。音频压缩的算法有很多,目前比较流行和常用的是 MP3 压缩格式。 ActionScript 3.0 仅支持 MP3 压缩格式的音频文件。 MP3 格式的音频文件 存储了其他的一些信息,这些信息叫做 ID3 标签。 ID3 标签记录了音频的标题、作者、专 辑等信息。 ActionScript 3.0 支持 MP3 文件中的 ID3 信息的读取。 20.2 播 放 声 音 在 Flash Player 中播放的音频可以通过多种方式载入。 最简单直接的方法就是把音频文 件直接嵌入到 SWF 文件,这种方法虽然简单快速但是会大大增加 SWF 文件的存储容量。 第 20 章 音频编程 ·419· 第二种方法是从外部文件载入音频文件,被载入的文件可以位于网络上也可以位于本地机 器。第三种方法是直接从服务器获取流式的音频数据,支持 Flash 的流媒体服务器有 FMS、 RED5 等。 20.2.1 音频嵌入 音频嵌入式是在 Flash Player 中播放音频最简单而快速的方式, 它的缺点就是存储容量 大不利于 SWF 文件在网络上传输。通过以下步骤可以在 Flash CS3 IDE 中嵌入 MP3 音频 文件并进行播放。 (1)新建一个 Flash AS3 文档。选择 Flash CS3 IDE 的“文件”|“新建”命令,打开 “新建文档”对话框。单击“常规”标签,进入“常规”选项卡,在其中选择“ Flash 文件 (ActionScript)3.0”选项,单击“确定”按钮。 (2)导入 MP3 文件。选择 Flash CS3 IDE 菜单的“文件” |“导入” |“导入到库”命令, 打开“导入到库”对话框。在“导入到库”对话框中选择需要导入的 MP3 文件。单击“打 开”按钮完成导入,如图 20.1 所示。 单击“库”面板右上角的 按钮进行播放测试,单击 按钮停止播放测试。右击“库” 面板中的项目名称,在弹出的快捷菜单中选择“属性 …”命令,打开音频元件的“声音属 性”对话框,如图 20.2 所示。在“声音属性”对话框中可以设置音频的导出质量。另外, 在“声音属性”对话框中还可以更新、重新导入、音频测试等操作。 图 20.1 导入音频到库 图 20.2 “声音属性”对话框 (3)设置音频属性。或者右击“库”面板中的音频项目,在弹出的快捷菜单中选择“链 接”命令打开“链接属性”对话框。在“链接”中选择“为 ActionScript 导出”选项,在 “类”文本框中输入 amarantine,其他选项保持默认。单击“确定”按钮完成链接属性配置。 (4)编辑 ActionScript 代码。右击“时间轴”面板的第一帧,在弹出的快捷菜单中选 择“动作”命令。打开“动作”面板编辑代码如下: var snd:amarantine=new amarantine(); //创建一个声音实例 ActionScript 3.0 开发技术大全 ·420· snd.play(); //播放声音 设置链接属性时已经把导入的音频文件发布为名为 amarantine 的 ActionScript 3.0 类。 如果没有完成 amarantine 类的定义则 Flash Player 在运行时自动创建该类。在以上代码中, 通过 new 关键字调用 amarantine 类构造函数创建一个 amarantine 对象 snd。调用该对象的 play()方法开始音频文件播放。另外,直接拖动“库”面板中的声音项目到舞台也有同样的 效果。 (5)播放测试。选择 Flash CS3 IDE 的“控制”|“测试影片”命令,或按下 Ctrl+Enter 键进行音频播放测试。 与 Flash CS3 IDE 一样,Flex Builder 3 中的 ActionScript 项目和 Flex 中都可以嵌入音频 文件。在 Flash CS3 IDE 中嵌入外部资源时使用 Embed 标签修饰一个 Class 类型的属性。 代码如下: import flash.display.Sprite; import flash.media.Sound; public class EmbedSound extends Sprite { [Embed(source="amarantine.mp3")] //嵌入 mp3 作为一个类型 public var Amarantine:Class; public function EmbedSound() { var snd:Sound=new Amarantine(); //创建声音类的实例对象 snd.play(); //播放 } } 以上代码创建了一个名为 EmbedSound 的类。对 Amarantine 属性使用 Embed 标签,表 示这个属性指向一个嵌入到 SWF 中的资源。本例中,指定 Embed 标签的 source 属性为一 个 MP3 文件,所以 Amarantine 是一个继承自 Sound 类的嵌入资源。在 EmbedSound 类的 构造函数中使用 new 关键字调用 Amarantine 类型的构造函数创建一个 Sound 类的实例对 象,并调用 Play 方法进行播放。事实上,Embed 标签不仅可以嵌入声音文件,还可以嵌入 诸如图片、SWF 文件、字体等的外部资源文件。 20.2.2 音频载入 从外部载入音频文件需要使用到 ActionScript 的 Sound 对象。使用 Sound 对象载入外 部音频与使用 Loader 对象载入外部图片的过程非常相似,它们都会用到 URLRequest 对象。 外部音频文件载入过程包括了一些列的事件调度过程。当加载开始时,程序会调度 open 事件。在加载过程中如果有数据到达则程序调度 progress 事件。如果被载入的 MP3 文件存 在 ID3 信息,则程序调用 ID3 事件。音频在载入过程中也会发生错误,当错误发生时程序 调用 IOError 事件。最后,当外部音频载入完成时程序调度 complete 事件。音频文件载入 过程是一个异步过程,音频文件可以边播放边载入,这样可以减少用户的等待事件。以下 是使用 Sound 对象载入外部 MP3 音频文件的示例代码。 import flash.display.Sprite; import flash.events.Event; import flash.events.IOErrorEvent; 第 20 章 音频编程 ·421· import flash.events.ProgressEvent; import flash.media.ID3Info; import flash.media.Sound; import flash.media.SoundChannel; import flash.net.URLRequest; public class SoundDemo extends Sprite { private var snd:Sound; private var sndchn:SoundChannel; public function SoundDemo() { var mp3url:URLRequest = new URLRequest("http://www1.gdufs.edu.cn/beschool/trans/upload files/2006102421225108.mp3"); //var mp3url:URLRequest = new URLRequest("amarantine.mp3"); snd = new Sound(); snd.addEventListener(Event.ID3, onID3); //ID3 事件 snd.addEventListener(Event.OPEN,onOpen); //启动载入事件 snd.addEventListener(ProgressEvent.PROGRESS,onPrg); //载入过程事件 snd.addEventListener(Event.COMPLETE,onComp); //载入完成事件 snd.addEventListener(IOErrorEvent.IO_ERROR,onError); //载入过程异常事件 snd.load(mp3url); //开始载入 } private function onError(e:IOErrorEvent):void //载入过程发生异常时调度 { trace("载入过程发生异常! "); } private function onPrg(e:ProgressEvent):void //载入过程中被调度 { var pct:int=Math.round(snd.bytesLoaded*100/snd.bytesTotal); trace("进度:"+pct+"%"); if(pct>5 && sndchn==null) //如果加载进度超过 5% { sndchn=snd.play(); //开始播放 } } private function onOpen(e:Event):void //载入过程开启后被调度 { trace("mp3 加载过程开始 ..."); } private function onComp(e:Event):void { trace("mp3 加载完成..."); } private function onID3(event:Event):void { var id3info:ID3Info = event.target.id3; trace("ID3 信息:"); //输出 ID3 信息 for (var itemName:String in id3info) { trace(itemName + " : " + id3info[itemName]); } } } 以上代码创建了一个 SoundDemo 类,在该类的构造函数中创建 Sound 对象,并从外 ActionScript 3.0 开发技术大全 ·422· 部载入 MP3文件。 Sound对象的 load()方法用于载入 MP3文件,该方法需要一个 URLRequest 类型的参数,该参数包含了需要被载入的音频文件的 URL 信息。 另外, SoundDemo 类还定义了若干方法用于处理音频载入过程中的各个事件。 Event.ID3 事件在 MP3 文件的 ID3 信息到达时被触发,本例中程序输出的 ID3 信息如下 所示。 COMM : ..:: JUST4FUN ::.. TCOM : Enya/Roma Ryan TPUB : Reprise TIT2 : Amarantine TPE2 : Enya TPE1 : Enya TYER : 2005 TALB : Amarantine TRCK : 2 TCON : (13) 这些输出的 ID3 信息中包含了注释、艺术家、标题、发行年份等歌曲信息。并不是所 有的 MP3 文件都有 ID3 信息,如果被载入的 MP3 文件不包含 ID3 信息,则 ID3 事件不会 被触发。 ProgressEvent.PROGRESS 事件在实际的应用中会比较常用,该事件用于外部 MP3 文 件的载入进度。本例中 ProgressEvent.PROGRESS 事件调度了 onPrg()方法。在 onPrg()方法 中计算载入的百分比,通过该进度值控制进度条。 20.2.3 流式音频 流式音频由 FMS、RED5 等流媒体服务器提供。当 Flash Player 客户端连接到流媒体服 务器后,ActionScript 就可以获取流媒体中的音频和视频数据。流式音频的播放需要用到 NetConnection 对象和 NetStream 对象。NetConnection 对象用于服务器连接,当 NetConnection 对象连接到服务器后,把已经连接到服务器的 NetConnection 对象作为参数 传递给 NetStream 的构造函数。 最后通过调用 NetStream 对象的 play()方法进行播放。 调用该方法时仅需要指定将要被 播放的 MP3 的文件名即可。本节示例将使用 RED5 作为流媒体服务器,完成 MP3 文件的 播放。关于 RED5 服务器的安装与配置在本书第 2 章已经有详细介绍。 在开始示例前,首先复制 MP3 文件到 RED5 的 streams 目录下。在 TOMCAT 安装目 录下的 bin 目录下找到 startup.bat 文件,双击启动 TOMCAT 服务器。 本示例将连接到 RED5 自带的 oflaDemo 示例。编辑 ActionScript 类文件如下: import flash.display.Sprite; import flash.events.Event; import flash.events.NetStatusEvent; import flash.net.NetConnection; import flash.net.NetStream; public class StreamDemo extends Sprite { private var con:NetConnection; //连接对象 private var stm:NetStream; //播放流 private var totalTime:Number; //播放时长 第 20 章 音频编程 ·423· public function StreamDemo() { con=new NetConnection(); //创建连接对象 con.client=this; //指定客户端 con.addEventListener(NetStatusEvent.NET_STATUS,onStatus); //添加网络状态事件 con.connect("rtmp://localhost/oflaDemo"); //连接 } public function onBWDone():void{} //带宽测试的回调函数 private function onStatus(e:NetStatusEvent):void { //如果连接成功 if(e.info.code=="NetConnection.Connect.Success") { stm=new NetStream(con); //创建播放流 stm.client=this;//指定客户端 stm.play("amarantine.MP3"); //播放制定文件 this.addEventListener(Event.ENTER_FRAME,checkPrg); } } private function checkPrg(e:Event):void //检查播放进度 { trace("已经播放 :"+stm.time+";缓冲长度 :"+stm.bufferLength); } public function onMetaData(e:Object):void //元数据事件 { totalTime= e["duration"]; //获取播放时长 } public function onPlayStatus(e:Object):void //播放状态事件 { if(e.code=="NetStream.Play.Complete") { trace("播放结束 "); } } } 以上代码定义了一个 StreamDemo 类,通过该类播放来自流媒体服务器的音频数据。 StreamDemo 类定义了三个属性。 con 属性是一个 NetConnection 类型的对象,用于连接到 流媒体服务器。 stm 属性指向一个音频流,通过该音频流播放声音。 totalTime 属性则是一 个 Number 类型的属性,该属性用于存储当前播放音频的总长度。 NetConnection 对象和 NetStream 对象都有一个 client 属性用于指定客户端。 client 属性 引用一个 Object 类型对象,在 Object 类型对象上定义若干方法以备 NetConnection 对象和 NetStream 对象调用。本例中,它们的 client 属性都指向了当前对象。当 NetConnection 对 象连接成功后,服务端会回调 NetConnection 对象的 client 属性的 onBWDone()方法。 onBWDone()方法是一个与网络带宽检测相关的方法。 NetStream 对象的 client 属性的定义 了 onMetaData()方法和 onPlayStatus()方法。 onMetaData()方法有点类似于 ID3 事件,从 onMetaData()方法的参数可以获得与播放音频相关的信息。 本例从 onMetaData()方法的参数 中得到了音频播放的时长。当播放结束时 onPlayStatus()方法被调用,参数的 code 属性是 一个表示播放结束的字符串。另外,本例中还定义了一个帧频事件用于检测播放进度。从 NetStream 对象的 time 属性获得当前已经播放的时间, 该属性可以用于控制播放头的位置。 ActionScript 3.0 开发技术大全 ·424· 在 StreamDemo 类的构造函数中创建 NetConnection 对象并调用它的 contact()方法进行 连接。 contact()方法连接的地址是一个 RTMP 协议的地址。 RTMP 协议是一个被广泛应用 于 Flash 与服务器通信的一个协议,是一个以 TCP 协议或轮询 HTTP 协议为基础的协议, 用于传输 AMF 格式的数据和 FLV 格式的数据。 AMP 是 Flash Player 与服务器进行数据通 信的一种格式, FLV 则是目前广泛流行的网络视频格式。 20.3 播 放 控 制 一个音频的播放控制包括载入进度的显示、播放中的控制、音频的响度和声道控制。 外部载入的音频和流式音频在播放控制上略有不同。由于流式音频的播放控制与食品的播 放控制类似,所以这部分的知识将在第 21 章“视频编程”中进行讲解。本节将着重讲解通 过 SoundChannel 类和 SoundTransform 类控制 Sound 对象的音频播放。 20.3.1 缓冲控制 声音在播放前首先会被载入,声音文件的载入过程是一个异步过程。在载入声音文件 的同时, Sound 对象可以播放已经载入部分的声音。 Sound 对象的 bytesTotal 属性表示被载 入的音频文件的总大小,而 bytesLoaded 属性则表示当前已经载入的量。通过 Sound 对象 的 bytesTotal 属性和 bytesLoaded 属性可以计算出已经被载入的声音文件的总大小。 以下是 载入百分比的计算方法: var percent:int=Math.round(snd.bytesLoaded*100/snd.bytesTotal); //计算载入百分比 由于声音在被载入的同时已经刚开始播放,所以在网速太慢的情况下,播放进度会赶 上载入进度。这样, Sound 对象就没有可播放的内容。此时, Sound 对象会暂停播放进行 缓冲,等载入一定量的音频文件后继续播放。在缓冲时, Sound 对象的 isBuffering 属性为 true。通过检查 Sound 对象的 isBuffering 属性可以判断 Sound 对象是否处于缓冲状态。 Sound 对象的 close()方法用于关闭载入过程。在某些网络播放器中,常常需要在乐曲 切换时首先需要关闭载入过程。例如,当前一个乐曲正在播放且只有部分被载入,此时用 户操作播放另一个乐曲。这样,就首先要调用 Sound 对象的 close()方法关闭当前乐曲的载 入过程。 20.3.2 回放控制 回放控制的内容包括回放监视、开始播放、暂停播放、继续播放、从某处开始播放等 操作。回放监视需要一个进度条监视播放过程的进度。播放过程中播放头会移动,用户也 可以移动播放头以播放指定位置的内容。播放监视使用需要获取声音的总长度以及当前播 放的长度。声音的播放总长度可以通过 Sound 对象的 length 属性获取,它表示播放当前已 经载入的声音所需要的毫秒数。 第 20 章 音频编程 ·425· 当前播放的长度需要使用 SoundChannel 对象的 position 属性获取。 Sound 对象的 play() 方法返回 SoundChannel 对象。计算当前回放进度时需要考虑是否载入完成。如果当前声音 文件未载入完成,则声音播放总长度需要通过计算而得到非直接使用 Sound 对象的 length 属性。 通过 SoundChannel 对象的 stop()方法可以停止声音播放。为了可以再次从停止的位置 继续播放声音,在停止播放时需要记住 SoundChannel 对象的 position 属性值。下次开始播 放时,把该值作为 Sound.play()方法的参数,则声音继续从原先停止的位置开始播放。通过 Sound 对象以及 SoundChannel 对象的这些特性可以非常容易地实现回放监视、开始播放、 暂停播放、继续播放、从某处开始播放等回放控制。 20.3.3 音效控制 音效控制包括控制整体音量控制、左右声道的音量,均衡度等。 Sound 对象在播放过 程中通过 SoundChannel 对象和 SoundTransform 对象控制播放时的音效。 SoundTransform 对象是 SoundChannel 对象的一个属性, SoundTransform 对象的 volume 属性用于控制声音 的音量,它的范围在 0~1 之间。直接设置 volume 属性值并不能够调整声音的音量。调整 音量需要新建一个 SoundTransform 对象并对 SoundChannel 对象的 soundTransform 属性赋 值。如下代码所示。 var stm:SoundTransform=new SoundTransform(); stm.volume=0.7; //设置音量值 sndchn.soundTransform=stm; //应用音效 以上代码创建了一个 SoundTransform 对象并设置它的 volume 属性值为 0.7。变量 sndchn 是一个由 Sound.play()方法返回的 SoundChannel 对象。把 SoundTransform 对象赋值 给 SoundChannel 对象的 soundTransform 属性后声音的音量发生改变。 SoundTransform 对象还包括了其他一些用于控制声音特性的属性。例如, SoundTrans form 对象的 pan 属性可以产生音源移动的效果。 SoundTransform 对象的 leftToLeft 属性、 leftToRight 属性、 rightToLeft 属性以及 rightToRigh 属性可以调节声音的左右输入量在左右 声道中的音量。另外,通过设置 SoundChannel 对象 leftPeak 属性和 rightPeak 属性也可以 非常方便地调节左右声道的音量。 20.4 MP3 播放器 了解 ActionScript 3.0 中声音的播放原理后就不难制作出一个简单的网络 MP3 播放器。 本节将结合之前学习的 ActionScript 3.0 声音播放原理建立一个简单的 MP3 播放器。该播 放器可以播放某个网络地址的 MP3 文件,显示载入进度。另外,在这个播放器中还可以拖 动播放进度条改变 MP3 音乐的播放头位置。本示例中的 MP3 播放器还实现了调节音量, 音源平移等功能。以下是创建步骤 MP3 播放器的具体步骤。 (1)新建 Flex ActionScript 项目。在 Flex Builder 3 中选择 File|New|ActionScript Project 命令,打开 New ActionScript Project 对话框。在 Project Name 文本框中输入项目名称为 ActionScript 3.0 开发技术大全 ·426· SimpleMP3Player,单击 Finish 按钮完成新建。 Flex Builder 3 同时创建了 SimpleMP3Player.as 文件。编辑 SimpleMP3Player.as 文件代码如下所示。 package { import flash.display.Sprite; import flash.events.Event; import flash.events.IOErrorEvent; import flash.events.ProgressEvent; import flash.media.Sound; import flash.media.SoundChannel; import flash.media.SoundTransform; import flash.net.URLRequest; public class SimpleMP3Player extends Sprite { private var snd:Sound; //Sound 对象 private var sndchn:SoundChannel; private var bufferBar:Bar; //缓冲进度条 private var playBar:Bar; //播放控制条 private var lbPlay:Label; private var isLoadComplete:Boolean=false; //是否已经完成载入 private var MP3url:URLRequest; //播放地址 private var volBar:Bar; //音量控制条 private var lrBar:Bar; //音源平移控制条 private var pausePos:Number; //暂停的时间点 public function SimpleMP3Player() { //创建缓冲进度标签和缓冲进度条 var bfText:Label=new Label("缓冲进度: "); bfText.x=10; bfText.y=10; this.addChild(bfText); bufferBar=new Bar(200,false); bufferBar.agToLeft(bfText); this.addChild(bufferBar); //创建播放进度标签和播放进度控制条 var playText:Label=new Label("播放进度: "); playText.agToUp(bfText); this.addChild(playText); playBar=new Bar(200); playBar.agToLeft(playText); this.addChild(playBar); playBar.addEventListener(BarEvent.PERCENT_CHANGED,seek); lbPlay=new Label("00:00:00"); lbPlay.agToLeft(playBar,5); this.addChild(lbPlay); //创建音量标签和音量控制条 var txtVol:Label=new Label("音量: "); txtVol.agToUp(playText); this.addChild(txtVol); volBar=new Bar(100); volBar.agToLeft(txtVol); this.addChild(volBar); volBar.addEventListener(BarEvent.PERCENT_CHANGING,changeVol); //创建平移标签和平移控制条 var txtlr:Label=new Label("平移:"); txtlr.agToUp(txtVol); 第 20 章 音频编程 ·427· this.addChild(txtlr); lrBar=new Bar(100); lrBar.agToLeft(txtlr); this.addChild(lrBar); lrBar.addEventListener(BarEvent.PERCENT_CHANGING,changeLR); //创建播放暂停按钮,并设置控制事件 var pausePlay:TextButton=new TextButton("暂停"); pausePlay.addEventListener(MouseEvent.CLICK,onPausePlay); pausePlay.agToUp(lrBar); this.addChild(pausePlay); startPlay(); //开始播放 } 以上代码定义了 SimpleMP3Player 类的各种属性作为控件,并在其构造函数中创建音 频播放器的界面元素。这些界面元素包括开始播放、停止播放的按钮、播放进度条,信息 显示标签等。 //播放暂停控制 private function onPausePlay(e:Event):void { var btn:TextButton = e.target as TextButton; if(btn.text=="暂停") { pausePos=sndchn.position; sndchn.stop(); btn.text="继续"; return; } if(btn.text=="继续") { startPlay(pausePos); //开始播放 btn.text="暂停"; return; } } //指定播放起点位置进行播放 public function startPlay(pos:Number=0):void { MP3url = new URLRequest("http://santia-sweater.com/s1.MP3"); snd = new Sound(); snd.addEventListener(Event.OPEN,onOpen); //启动载入事件 snd.load(MP3url); //开始载入 sndchn=snd.play(pos); } public function seek(e:BarEvent):void { sndchn.stop(); //停止播放 //计算播放起点位置 var pos:Number=(playBar.percent/100)*length; if(pos>length) pos=sndchn.position; startPlay(pos); //从指定的起点位置开始播放 } 以上代码定义了 SimpleMP3Player 类中用于音频播放控制的方法, startPlay()方法用于 启动音频播放过程, seek()函数用于寻找播放点。下面继续 SimpleMP3Player 类的定义。 ActionScript 3.0 开发技术大全 ·428· //载入过程开启后被调度 private function onOpen(e:Event):void { volBar.percent=50; lrBar.percent=50; if(!isLoadComplete) //如果载入未完成 { snd.addEventListener(ProgressEvent.PROGRESS,onPrg); //载入过程事件 snd.addEventListener(Event.COMPLETE,onComp); //载入完成事件 snd.addEventListener(IOErrorEvent.IO_ERROR,onError); //载入过程异常事件 } this.addEventListener(Event.ENTER_FRAME,checkState); } //使音源发生平移 private function changeLR(e:BarEvent):void { var pen:Number= (lrBar.percent-50)/50; var stm:SoundTransform=new SoundTransform(sndchn.soundTrans form.volume,pen); sndchn.soundTransform=stm; } //使音量发生变化 private function changeVol(e:BarEvent):void { var stm:SoundTransform=new SoundTransform(); stm.volume=e.percent/100; sndchn.soundTransform=stm; } //载入过程发生异常时调度 private function onError(e:IOErrorEvent):void { trace("载入过程发生异常! "); } //载入过程中被调度 private function onPrg(e:ProgressEvent):void { var pct:Number=Math.round(snd.bytesLoaded*100/snd.bytes Total); bufferBar.percent=pct; } //载入完成时被调度 private function onComp(e:Event):void { trace("MP3 加载完成..."); isLoadComplete=true; bufferBar.percent=100; } 以上代码定义了用于音频播放控制相关的函数。这些控制包括开始播放、暂停播放、 播放位置拖动、音量控制等。 //检查播放进度 public function checkState(e:Event):void { 第 20 章 音频编程 ·429· if(isLoadComplete) //加载完成后计算的播放进度 { playBar.percent=sndchn.position*100/length; } else //加载未完成时计算播放进度 { playBar.percent= (sndchn.position*100)/ length ; } lbPlay.text=getTimeFmt(sndchn.position); } //得到播放时间 public function get length():Number { if(isLoadComplete) //加载完成后计算的播放时间 { return snd.length; } else //加载未完成时计算播放时间 { return (snd.length*snd.bytesTotal /snd.bytesLoaded); } } //从毫秒数得到一个时间格式 public static function getTimeFmt(ms:Number):String { var s:int=int(ms/1000); var m:int=int(s/60); s-=m*60; var h:int; h=int(m/60); m-=h*60; return make2Str(h)+":"+make2Str(m)+":"+make2Str(s); } //使数字时钟保持两位 public static function make2Str(i:int):String { if(i<10) return "0"+i; else return ""+i; } } } 以上代码创建一个 SimpleMP3Player 类,在该类的构造函数中创建并布局相关组件。 在本例中,自定义了三个简单组件: Label 组件、TextButton 组件以及 Bar 组件。这些组件 的定义类将在稍后给出。这些类中都定义了布局和对齐的方法,使它们很容易地放置到指 定的位置。完成布局后,调用 startPlay()方法播放制定 URL 的 MP3 音乐。startPlay()方法 需要指定起始播放位置参数,该方法是实现暂停播放和继续播放的基础。本例实现了简单 的暂停播放和继续播放功能,另外拖动播放控制条还可以改变当前播放位置。 SimpleMP3Player 类还实现了播放过程中的音量控制功能。通过拖动音量控制条控制 声音的响度。另外, SimpleMP3Player 类还添加了声音播放时音源平移功能,拖动控制条 就可以使音源发生左右移动。 SimpleMP3Player 类中没有实现 SoundChannel 类和 SoundTransform 对象中其他的声音控制特性,有兴趣的读者可以尝试使用这些控制来控制 声音播放时的一些特性。 (2)新建进度条类 Bar 并编辑代码。在 Flex Navgator 视图中的 SimpleMP3Player 项目 ActionScript 3.0 开发技术大全 ·430· 名下右击,在弹出的快捷菜单中选择 New|ActionScript Class 命令打开 New ActionScript Class 对话框。在 New ActionScript Class 对话框的 Class 文本框中输入 Bar,单击 Finish 按 钮完成 Bar 类新建。编辑 Bar.as 文件,代码如下: package { import flash.display.DisplayObject; import flash.display.Shape; import flash.display.Sprite; import flash.events.MouseEvent; public class Bar extends Sprite //进度条 { public static const HEIGHT:Number=12; //默认高度 protected var frame:Shape; //进度条外框 protected var bar:Sprite; //进度条 private var userChangeAble:Boolean=true; //是否允许用户拖动 //构造函数,指定宽度、是否允许用户拖动,底色、前景色参数 public function Bar(w:Number=100,ucb:Boolean=true, frameColor:uint=0xffffff,barColor:uint=0x666666) { userChangeAble=ucb; //绘制进度条背景 frame=new Shape(); frame.graphics.beginFill(frameColor); frame.graphics.drawRect(0,0,w,HEIGHT); this.addChild(frame); //绘制进度条 bar=new Sprite(); bar.graphics.beginFill(barColor); bar.graphics.drawRect(0,0,w,HEIGHT); bar.width=0; this.addChild(bar); if(userChangeAble) { //添加鼠标事件 this.addEventListener(MouseEvent.MOUSE_UP,onMouseUp); this.addEventListener(MouseEvent.MOUSE_MOVE,onMouseMove); } } 以上代码定义了 Bar 类的相关属性和构造函数, Bar 控件在应用程序中实现定位播放、 音量控制等功能。下面继续 Bar 类的定义。 private function onMouseMove(e:MouseEvent):void // 鼠标移动 时被调度 { if(e.buttonDown) //如果鼠标是按下状态,则拖动 { this.percent=(this.mouseX*100/this.width); //重新计算设置百分比 e.updateAfterEvent(); } } private function onMouseUp(e:MouseEvent):void //鼠标释放时被调度 { this.percent=(this.mouseX*100/this.width); //重新计算设置百分比 //调度自定义事件 第 20 章 音频编程 ·431· this.dispatchEvent(new BarEvent(BarEvent.PERCENT_CHANGED, this.percent)); e.updateAfterEvent(); } public function get percent():Number //获取百分比值 { return Math.round(bar.width*100/this.width); } public function set percent(pct:Number):void //设置百分比值 { //值判断 if(pct<0) pct=0; if(pct>100) pct=100; //修正误差 if(pct>=99) pct=100; if(pct<=1) pct=0; if(this.percent!=pct) { bar.width=(pct/100)*this.width; //重新设置长度 //调度自定义事件 this.dispatchEvent(new BarEvent(BarEvent.PERCENT_CHANGING, pct)); } } //与某个可视对象纵向左对齐 public function agToUp(obj:DisplayObject,dis:Number=10):void { this.x=obj.x; this.y=obj.y+obj.height+dis; } //与某个可视对象横向中线对齐 public function agToLeft(obj:DisplayObject,dis:Number=8):void { this.y=(obj.y+obj.height/2)-this.height/2; this.x=obj.x+obj.width+dis; } } } Bar.as 文件显现了进度条和控制条,进度条是不可以被用户拖动的,而控制条则可以 被用户拖动。所以 Bar 类要使用两种模式,通过参数指定是否接受用户的控制。 Bar 由背 景条和前景条两部分组成,背景条作为铺垫,前景条则显示进度或让用户通过鼠标进行 拖动。 percent 属性是 Bar 的一个非常重要的属性,直接设置 percent 属性值可改变前景条的 长度。改变 percent 属性的同时也触发了 PERCENT_CHANGING 事件,该事件和 PERCENT_CHANGED 事件是本例中自定义的两个事件。可以在外部设置监听器函数处理 这两个事件。 (3)新建进度条事件类 BarEvent 类并编辑代码。 在 Flex Navgator 视图中的 SimpleMP3 Player 项目名下右击,在弹出的快捷菜单中选择 New|ActionScript Class 命令打开 New ActionScript Class对话框。在New ActionScript Class对话框的Class文本框中输入 BarEvent, 单击 Finish 按钮完成 BarEvent 类新建。编辑 BarEvent.as 文件,代码如下: package { ActionScript 3.0 开发技术大全 ·432· import flash.events.Event; public class BarEvent extends Event //自定义事件 { public static const PERCENT_CHANGING:String="percent_changing"; public static const PERCENT_CHANGED:String="percent_changed"; private var _percent:Number=0; //百分比参数 public function BarEvent(type:String,pct:Number=0, bubbles:Boolean=false, cancelable:Boolean=false) { super(type, bubbles, cancelable); _percent=pct; } public function get percent():Number //获取百分比 { return _percent; } } } BarEvent 类继承自 Event 类,是一个事件类。 BarEvent 对象扩展了一个只读的 percent 属性,通过该属性读取事件出发时进度条或控制条的值。 (4)新建标签类 Label 类并编辑代码。在 Flex Navgator 视图中的 SimpleMP3Player 项 目名下右击,在弹出的快捷菜单中选择 New|ActionScript Class 命令打开 New ActionScript Class 对话框。在 New ActionScript Class 对话框的 Class 文本框中输入 Label,单击 Finish 按钮完成 Label 类新建。编辑 Label.as 文件,代码如下: package { import flash.display.DisplayObject; import flash.text.TextField; import flash.text.TextFieldAutoSize; public class Label extends TextField //定义一个不可修改的文本类型 { public function Label(txt:String) { super(); this.text=txt; this.autoSize=TextFieldAutoSize.LEFT; //设置自定对齐 this.height=10; this.selectable=false; } //与某个可视对象纵向左对齐 public function agToUp(obj:DisplayObject,dis:Number=10):void { this.x=obj.x; this.y=obj.y+obj.height+dis; } //与某个可视对象横向中线对齐 public function agToLeft(obj:DisplayObject,dis:Number=15):void { this.y=(obj.y+obj.height/2)-this.height/2; this.x=obj.x+obj.width+dis; } } 第 20 章 音频编程 ·433· } 以上代码定义 Label 类实现标签功能。 Label 类继承自 TextField 类并对 TextField 类做 了适当的扩展。 Label 类多了两个对齐功能,它可以与指定的可视对象垂直左对齐或水平 中线对齐。Label 类的整个特性使它在程序界面很容易被摆放,所有的组件只要有一个参 考对象就可以完成摆放。 (5)新建按钮类 TextButton 类并编辑代码。 在 Flex Navgator 视图中的 SimpleMP3Player 项目名下右击, 在弹出的快捷菜单中选择 New|ActionScript Class 命令打开 New ActionScript Class 对话框。在 Class 文本框中输入 TextButton,单击 Finish 按钮完成 TextButton 类新建。 编辑 TextButton.as 文件,代码如下: package { import flash.display.DisplayObject; import flash.events.Event; import flash.events.MouseEvent; import flash.text.TextField; import flash.text.TextFieldAutoSize; //定义一个用 TextField 实现的按钮 public class TextButton extends TextField { public function TextButton (txt:String="") { this.text=txt; this.autoSize=TextFieldAutoSize.CENTER; this.height=20; this.selectable=false; this.background=true; this.backgroundColor=0xffffff; //为按钮添加事件,对鼠标产生反应 this.addEventListener(MouseEvent.MOUSE_OVER,onOver); this.addEventListener(MouseEvent.MOUSE_OUT,onOut); } private function onOver(e:Event):void //鼠标移上事件 { this.backgroundColor=0x333333; this.textColor=0xffffff; } private function onOut(e:Event):void //鼠标移除事件 { this.backgroundColor=0xffffff; this.textColor=0x000000; } //与某个可视对象纵向左对齐 public function agToUp(obj:DisplayObject,dis:Number=10):void { this.x=obj.x; this.y=obj.y+obj.height+dis; } //与某个可视对象横向中线对齐 public function agToLeft(obj:DisplayObject,dis:Number=15):void { this.y=(obj.y+obj.height/2)-this.height/2; this.x=obj.x+obj.width+dis; } } } ActionScript 3.0 开发技术大全 ·434· 以上代码实现了 TextButton 类,TextButton 类也继承自 TextField 类。该类通过 TextField 类快速实现按钮功能。另外, TextButton 类也包含了对齐方法,方便它在界面摆放。 (6)测试程序。依次选择 Run|Debug SimpleMP3Player 命令,或直接按下 F11 快捷键 启动调试。启动调试后,播放器将开始播放指定地址下的 MP3 音乐。程序界面如图 20.3 所示。 图 20.3 MP3 播放器 20.5 使用麦克风 麦克风是在计算机中能用于音频信号输入的设备,由麦克风采集的音频信号经由声卡 转换为数字信号。 Microphone 类用于在 ActionScript 3.0 中使用计算机上的麦克风,通过 Microphone 对象获取音频输入的数字信号。 ActionScript 3.0 可以设置 Microphone 对象的采 样频率、放大倍数以及其他的各个参数,本节将对如何获取麦克风以及如何设置麦克风作 详细介绍。 20.5.1 获取麦克风 获取麦克风不能像创建一般类的对象那样,通过 new 关键字构造实例。获取麦克风需 要使用 Microphone 类的静态方法 getMicrophone(),该方法包含一个 int 型参数作为麦克风 序号。一般情况下,计算机只带有一个麦克风,所以该参数的默认值为 0。在带有多个麦 克风的计算机中可以通过该参数获取指定序号的麦克风。以下是获取麦克风的示例代码。 var mic:Microphone=Microphone.getMicrophone(); //获得麦克风对象 以上代码获得一个默认的麦克风引用。如果当前计算机没有安装麦克风或者当前的麦 克风被其他应用程序独占,则 Microphone.getMicrophone()方法返回 null。如果要知道当前 计算机上安装的麦克风列表则可以调用 Microphone.names()方法,该方法得到一个包含了 所有麦克风名称的数组对象。 默认情况下, Microphone.getMicrophone()方法得到的是一个默认麦克风设备。如果计 算机带有多个麦克风设备,除了为 Microphone.getMicrophone()方法指定序号参数外,还可 以在设置面板中设置默认麦克风。麦克风设置面板可以通过以下语句调出: import flash.system.Security; Security.showSettings(SecurityPanel.MICROPHONE); //打开麦克风设置面板 第 20 章 音频编程 ·435· 麦克风设置面板不仅可以设置默认麦克风,还可以调节麦克风的输入音量,如图 20.4 所示。在计算机中使用麦克风设置,需要得到用户的许可。当 ActionScript 第一次使用麦 克风时,Flash Player 会弹出对话框与用户确认是否可以使用麦克风,如图 20.5 所示。用户 可以使用以下语句调出该设置界面。 import flash.system.Security; Security.showSettings(SecurityPanel.PRIVACY); //打开隐私面板 以上代码导入了 flash.system.Security 类,调用 Security.showSettings()方法调出设置面 板。在该模板中选择是否允许程序使用麦克风。麦克风是否允许使用的设置被改变后,程 序将调度 status 事件。 图 20.4 麦克风设置 图 20.5 是否允许使用麦克风 以下是使用麦克风 status 事件的示例代码。 mic.addEventListener(StatusEvent.STATUS,onStatu); //处理麦克风的状态事件 private function onStatu(e:StatusEvent):void { trace(e.code); trace(mic.muted); } 以上代码为麦克风对象添加了 status 事件,麦克风的 muted 属性表示是否允许使用麦 克风。如果 muted 属性的值为 true 则表示不允许使用麦克风,否则表示允许使用麦克风。 另外,通过事件对象的 code 属性值也可以判断麦克风是否可用,当 code 属性值为 Microphone.Muted 时,表示麦克风不可用,而 Microphone.Unmuted 表示麦克风可用。 设置 Microphone 对象的 gain 属性可以起到调节输入音量的作用。 gain 属性是一个 Number 类型的属性,取值范围在 0~100 之间,它表示音频输入信号的放大倍数。 gain 属 性值为 50 则表示正常输入音量,改变属性值可以使输入音量增加或减小。 Microphone 对 象的 rate 属性用于控制麦克风的采样频率, rate 属性是一个 int 类型的值,可选值包括 5, 8,11,22,44。采样频率会影响到声音的质量,同时也会影响到声音的存储量。所以在进 行 WEB 录音的过程中应该根据实际网络带宽适当控制音频采样频率。 20.5.2 回环模式 回环模式下的麦克风使从麦克风输入的音频信号同时输出到扬声设备。使用回环模式 的好处是可以使输入的声音直接在本地音响输出, 从而直接感受到 Microphone 对象的各种 参数对音频采集所起到的作用。设置麦克风的回环模式可以直接调用以下代码。 mic.setLoopBack(true); //启动回环模式 ActionScript 3.0 开发技术大全 ·436· 以上代码直接调用 Microphone 对象的 setLoopBack()方法开启回环模式。如果传递参 数值为 true,则表示开启回环模式,设置参数值为 false 则表示关闭回环模式。在回环模式 下,设置 Microphone 对象的 soundTransform 属性可以调节本地音响设备的输出音效。 由于回环模式会把音响的声音再次输入到麦克风而产生回音, 而 Microphone 对象可以 调用 setUseEchoSuppression()方法适当抑制回音。 setUseEchoSuppression()方法带一个逻辑 型参数,当参数值为 true 时表示抑制回音,当参数值为 false 时则表示取消回音抑制。 20.5.3 静音设置 静音设置用于设置麦克风的敏感度,指定麦克风认为是静音的音量下线有利于合理利 用网络带宽。麦克风的音频信号感知是一个断续的过程。麦克风对象需要一个最低输入音 量值,如果输入麦克风的音量大于这个值,麦克风就把音频信号传递给声卡进行采样,调 度 Microphone 对象的 active 事件。 当声音低于这个下限时,麦克风并不是立即停止输入采样,而是要等待一定的时间。 当停止采样时,程序再次调度 Microphone 对象的 active 事件。设置麦克风的静音级别可以 调用 Microphone.setSilenceLevel(),代码如下: mic.setSilenceLevel(10,2000); //设置静音级别 以上代码调用 setSilenceLevel()方法设置静音级别,该方法带两个参数。第一参数用于 指定最低音量级别,第二参数表示外部输入的音量小于第一个参数时等待的时间,单位为 毫秒。默认情况下,静音等待事件为 2 秒钟。 为了感知麦克风的输入音量, Microphone 对象提供了 activityLevel 属性。该属性是一 个 Number 类型且范围在 0~100 的数值。通过不断检查这个参数的值来感知麦克风音量的 变化。通过该属性值,可以检查麦克风是否感受到外部音量,这样就可以绘出制音频的波 动图像。使用 activityLevel 属性时需要设置麦克风为回环模式。 20.6 录制音频到 RED5 服务器 本节是一个使用麦克风进行音频录制的范例。该范例程序把从麦克风输入的音频信号 录制到 RED5 服务器。程序的客户端包括麦克风调节模块和音频录制模块两个模块。麦克 风调节模块对麦克风的各个参数进行调节,使麦克风的各个性能适合用户的需求。音频录 制模块负责把麦克风的音频信号发送给 RED5 服务器。 以下是在 Flex Builder 3 中完成本示例的具体步骤。由于本示例的代码包括了 20.4 节 示例中建立的标签类、按钮类和进度条类,所以下面只给出步骤不再给出具体代码。 (1)新建 Flex ActionScript 项目。 在 Flex Builder 3 中选择菜单栏的 File|New|ActionScript Project 命令,打开 New ActionScript Project 对话框。在 Project Name 文本框中输入项目名 称为 RecDemo,单击 Finish 按钮完成新建。 Flex Builder 3 同时创建了 RecDemo.as 文件。 (2)复制类文件。 把 20.4 节示例项目中的 Bar.as、BarEvent.as、Label.as 及 TextButton.as 文件复制到 RecDemo 项目的 src 目录下。 第 20 章 音频编程 ·437· (3)新建录制器 MicRecorder 类并编辑代码。在 Flex Navgator 视图中的 RecDemo 项 目名下右击,在弹出的快捷菜单中选择 New|ActionScript Class 命令打开 New ActionScript Class 对话框。在 Class 文本框中输入 MicRecorder,单击 Finish 按钮完成 MicRecorder 类新 建。编辑 MicRecorder.as 文件,代码如下: package { import flash.events.NetStatusEvent; import flash.media.Microphone; import flash.net.NetConnection; import flash.net.NetStream; public class MicRecorder { private var con:NetConnection; private var stm:NetStream; private var mic:Microphone; public function MicRecorder(mic:Microphone) { con=new NetConnection(); //创建连接对象 con.client=this; //指定客户端 con.addEventListener(NetStatusEvent.NET_STATUS,onStatus); //添加网络状态事件 con.connect("rtmp://localhost/oflaDemo"); //连接 this.mic=mic; } public function onBWDone():void{} //带宽测试的回调函数 private function onStatus(e:NetStatusEvent):void { //如果连接成功 if(e.info.code=="NetConnection.Connect.Success") { stm=new NetStream(con); //创建播放流 stm.client=this; //指定客户端 stm.attachAudio(mic); //把麦克风与网络流关联 trace("已经连接到服务器 ...") } } //开始录制 public function startRec():void { var dt:Date=new Date(); stm.publish("mic_"+dt.getTime(),"record"); //开始录制 } //停止录制 public function stopRec():void { stm.close(); //关闭流 } } } 以上代码创建了 MicRecorder 类,作用是把从麦克风输入的音频信号输入录制到 RED5 服务器。 MicRecorder 类在其构造函数中创建 NetConnection 对象并连接到服务器。 连接完成后,程序创建一个 NetStream 对象并把 NetStream 对象与 Microphone 对象绑定。 MicRecorder 类还定义了开始录制方法 startRec()和停止录制方法 stopRec()。startRec() ActionScript 3.0 开发技术大全 ·438· 方法调用 NetStream 对象的 publish()方法把音频数据发布到服务器,发布时需要指定存储 文件的名称和操作类型。本例中,文件名使用一个日期对象得到,这样可以避免重复。操 作类型参数指定为 record,告诉服务器进行录制操作。 (4)编辑 RecDemo.as 文件。打开 RecDemo.as 文件,输入以下代码: package { import flash.display.DisplayObject; import flash.display.Sprite; import flash.events.ActivityEvent; import flash.events.Event; import flash.events.MouseEvent; import flash.events.StatusEvent; import flash.media.Microphone; import flash.system.Security; import flash.system.SecurityPanel; [SWF(width="800", height="600", frameRate="20", backgroundColor="#006 699")] public class RecDemo extends Sprite { private var mic:Microphone; //麦克风对象 private var ativityLevel_bar:Bar; //活动级别状态条 private var active_lb:Label; //活动级别标签 private var allmic_lb:Label; private var recoder:MicRecorder; //音频录制器 以上代码定义了 RecDemo 类的相关属性。mic 属性是对麦克风的引用。 recoder 属性用 于音频录制。下面继续定义 RecDemo 类的构造函数。 public function RecDemo() { mic=Microphone.getMicrophone(); //检查是否有麦克风 if(mic==null) { trace("没有找到麦克风设备! "); return; } //为模块对象添加事件 mic.addEventListener(ActivityEvent.ACTIVITY,onActivity); mic.addEventListener(StatusEvent.STATUS,onStatu); if(mic.muted) //检查麦克风是否启用 { Security.showSettings(SecurityPanel.PRIVACY); //显示面板 } //创建开启本地回放按钮 var openLoopBack_btn:TextButton=new TextButton("开启本地回放(目 前关闭)"); openLoopBack_btn.x=10; openLoopBack_btn.y=10; this.addChild(openLoopBack_btn); openLoopBack_btn.addEventListener(MouseEvent.CLICK,onOpenLoo pBackClick); //创建抑制回音按钮 var echo_btn:TextButton=new TextButton("抑制回音(目前关闭) "); echo_btn.agToLeft(openLoopBack_btn); this.addChild(echo_btn); 第 20 章 音频编程 ·439· echo_btn.addEventListener(MouseEvent.CLICK,onEchoBtnClick); //创建设置麦克风按钮 var micsetup_btn:TextButton=new TextButton("设置麦克风"); micsetup_btn.agToLeft(echo_btn); this.addChild(micsetup_btn); micsetup_btn.addEventListener(MouseEvent.CLICK,onMicSetupBtn Click); //创建麦克风是否允许使用的标签 allmic_lb=new Label("允许使用"); allmic_lb.agToLeft(micsetup_btn); this.addChild(allmic_lb); //创建静音状态的标签 active_lb=new Label("无声"); active_lb.agToLeft(allmic_lb); this.addChild(active_lb); //创建输入音量的标签和状态条 var ativityLevel_lb:Label=new Label("输入音量:"); ativityLevel_lb.agToUp(openLoopBack_btn); this.addChild(ativityLevel_lb); ativityLevel_bar=new Bar(150,false); ativityLevel_bar.agToLeft(ativityLevel_lb); this.addChild(ativityLevel_bar); this.addEventListener(Event.ENTER_FRAME,checkAtivityLevel); var disobj:DisplayObject; //创建输入增益的标签和控制条 disobj=createPair(ativityLevel_lb,"输入增益:",onGainBarChange, 66); //创建输入增益的标签和控制条 disobj=createPair(disobj,"采样频率:",onRateBarChange,11); //创建采样频率的标签和控制条 disobj=createPair(disobj," 敏感度:",onSilenceLevelChange,1); //创建静音等待的标签和控制条 disobj=createPair(disobj,"静音等待:",onSilenceLevelChange 2,1); //创建开始录音按钮 var rec_btn:TextButton=new TextButton("开始录音(目前关闭)"); rec_btn.agToUp(disobj); this.addChild(rec_btn); rec_btn.addEventListener(MouseEvent.CLICK,onRecBtnClick); onStatu(null);//检查麦克风状态 recoder=new MicRecorder(mic);//创建录制器 } 以上代码定义了 RecDemo 类的相关属性以及构造函数。其中 recoder 属性用于麦克风 的音频录制,构造函数中创建了录音机的基本界面。 private function checkAtivityLevel(e:Event):void { ativityLevel_bar.percent=mic.activityLevel; //显示音量输入 } private function onSilenceLevelChange(e:BarEvent):void { mic.setSilenceLevel(e.percent,mic.silenceTimeout); //设置静音显现 ActionScript 3.0 开发技术大全 ·440· } private function onSilenceLevelChange2(e:BarEvent):void { mic.setSilenceLevel(mic.silenceLevel,(e.percent/100)*10000); //设置静音等待 } //根据麦克风是否可用设置标签内容 private function onStatu(e:StatusEvent):void { if(mic.muted) { allmic_lb.text="禁止使用"; } else { allmic_lb.text="允许使用"; } } private function onEchoBtnClick(e:MouseEvent):void { var btn:TextButton=e.target as TextButton; if(btn.text=="抑制回音(目前关闭) ") { mic.setUseEchoSuppression(true); //开启回音抑制功能 btn.text="抑制回音(目前开启) "; return; } if(btn.text=="抑制回音(目前开启) ") { mic.setUseEchoSuppression(false); //关闭回音抑制功能 btn.text="抑制回音(目前关闭) "; return; } } private function onRateBarChange(e:BarEvent):void { mic.rate=(e.percent/100)*44; //设置采样频率 } private function onGainBarChange(e:BarEvent):void { mic.gain=e.percent; //设置麦克风增益 } private function onOpenLoopBackClick(e:MouseEvent):void { var btn:TextButton=e.target as TextButton; if(btn.text=="开启本地回放(目前关闭) ") { mic.setLoopBack(true); //开启本地回放 btn.text="关闭本地回放(目前开启) "; return; } if(btn.text=="关闭本地回放(目前开启) ") { mic.setLoopBack(false); //关闭本地回放 btn.text="开启本地回放(目前关闭) "; return; } } 第 20 章 音频编程 ·441· private function onActivity(e:ActivityEvent):void { //根据麦克风活动状态设置标签为有声或无声 if(e.activating) { active_lb.text="有声"; } else { active_lb.text="无声"; } } private function onMicSetupBtnClick(e:MouseEvent):void { Security.showSettings(SecurityPanel.MICROPHONE); //显示麦克风设置面板 } //创建标签和控制条 //需要制定向上对齐的可视对象,标签内容、控制条事件,控制条默认值、以及控制条 是否与用户交互 private function createPair(topOne:DisplayObject,lbtext:String, barEvent:Function, defPct:Number,usr:Boolean=true):DisplayObject { var lb:Label=new Label(lbtext); //创建标签 lb.agToUp(topOne); //对齐 this.addChild(lb); var bar:Bar=new Bar(150,usr); //创建控制条 bar.agToLeft(lb); //控制条对齐 this.addChild(bar); bar.addEventListener(BarEvent.PERCENT_CHANGING,barEvent); //添加控制条事件 bar.percent=defPct; //设置默认值 return lb; } private function onRecBtnClick(e:Event):void { var btn:TextButton=e.target as TextButton; if(btn.text=="开始录音(目前关闭) ") { recoder.startRec(); //开始录制 btn.text="停止录制(正在录制) "; return; } if(btn.text=="停止录制(正在录制) ") { recoder.stopRec(); //停止录制 btn.text="开始录音(目前关闭) "; return; } } } } 以上代码创建了 RecDemo 类,RecDemo 类完成对麦克风各项参数的控制,并调用 MicRecorder 对象录制音频到服务器。 RecDemo 类控制的项目包括:是否开启本地回放、 是否开始回音抑制、设置输入增益、设置采样频率、设置敏感度、设置静音等待时间。 ActionScript 3.0 开发技术大全 ·442· RecDemo 类还通过标签和进度条显示麦克风是否可用、麦克风是否静音以及麦克风的输入 音量。另外,在 RecDemo 类中还可以通过按钮调出麦克风设置面板、单击录制按钮进行音 频录制。 (5)测试程序。依次选择 Run|Debug RecDemo 命令或直接按下 F11 快捷键启动调试。 启动调试后,程序将检测麦克风并检测麦克风相关状态。如图 20.6 是本示例的程序界面, 通过程序界面的按钮和控制条控制麦克风的音量等参数。 图 20.6 示例程序界面 20.7 小 结 本章介绍了 ActionScript 3.0 中音频控制的基本方法。首先介绍了使用 ActionScript 3.0 播放声音,然后介绍在 ActionScript 3.0 中使用麦克风,并通过具体示例说明声音播放以及 声音录制的节本方法。本章学习的重点和难点在于音频播放和麦克风的使用。学习完 ActionScript 3.0 音频编程后,第 21 章将引领读者进入 ActionScript 3.0 视频编程的世界。
还剩24页未读

继续阅读

下载pdf到电脑,查找使用更方便

pdf的实际排版效果,会与网站的显示效果略有不同!!

需要 8 金币 [ 分享pdf获得金币 ] 0 人已下载

下载pdf

pdf贡献者

boostycs

贡献于2012-02-12

下载需要 8 金币 [金币充值 ]
亲,您也可以通过 分享原创pdf 来获得金币奖励!
下载pdf