1. 获得声音文件及当前下载量的大小
通过Sound对象的bytesTotal和bytesLoaded属性
{ flash.display.Sprite; flash.events.Event; flash.media.Sound; flash.media.SoundLoaderContext; flash.net.URLRequest; Sample0618Sprite { bar:Sprite; music:Sound; Sample0618() { progressBar:Sprite = Sprite(); progressBar.graphics.beginFill(0xFFFFFF); progressBar.graphics.drawRect(0,0,300,5); progressBar.graphics.endFill(); progressBar.x = progressBar.y = 100; bar = Sprite(); progressBar.addChild(bar); .addChild(progressBar); music = Sound(URLRequest()); music.play(); .addEventListener(Event.ENTER_FRAME,onEnterFrame); } onEnterFrame(event:Event): { (music.bytesTotal>0) { percent:Number = music.bytesLoaded/music.bytesTotal; bar.graphics.clear(); bar.graphics.beginFill(0xCCCCCC); bar.graphics.drawRect(0,0,300*percent,5); bar.graphics.endFill(); } } } }
2. 读取声音文件的ID3标签数据
MP3声音文件可以包含ID3标签,标签大多包含一些如songname,artist,album,genre,year等元数据,不过并不是都有,但大多数情况下都有songname和artist标签
通过Sound对象的id3属性可获得这些数据,如:_sound.id3.songName
如果歌曲还没有下载到swf中,id3数据是不能够被访问的,可以监听Sound对象的ID3事件来判断id3数据是否已下载:_sound.addEventListener(Event.ID3, onID3);
{ flash.display.Sprite; flash.media.Sound; flash.net.URLRequest; flash.events.Event; flash.text.TextField; Sample0618Sprite { _sound:Sound; Sample0618() { _sound = Sound(URLRequest()); _sound.addEventListener(Event.ID3, onID3); _sound.play( ); } onID3(event:Event): { id3Display:TextField = TextField( ); addChild(id3Display); id3Display.x = 10; id3Display.y = 20; id3Display.width = 200; id3Display.height = 200; id3Display.background = ; id3Display.multiline = ; id3Display.wordWrap = ; id3Display.appendText(_sound.id3.songName + ); id3Display.appendText(_sound.id3.artist + ); id3Display.appendText(_sound.id3.album + ); id3Display.appendText(_sound.id3.year + ); } } }
3. 判定音乐是否播放完毕(soundComplete事件)
很多情况下我们需要知道因为是否播放完毕,例如,音乐播放器的播放列表,需要判定是否播放完毕以便播放下一首音乐
当调用Sound对象的play()方法时,它会返回一个SoundChannel(声音通道)对象,因此每一首正在播放的音乐都会产生一个SoundChannel对象,当声音播放完毕时,对应的SoundChannel对象会发出soundComplete事件,就是flsh.events.Event.SOUND_COMPLETE
{ flash.display.Sprite; flash.events.Event; flash.media.Sound; flash.media.SoundChannel; flash.net.URLRequest; Sample0618Sprite { songList:Array; music:Sound; index:int = 0; Sample0618() { songList = [,,,]; playNextSong(); } playNextSong(): { (index<songList.length) { music = Sound(URLRequest(songList[index])); sc:SoundChannel =music.play(); sc.addEventListener(Event.SOUND_COMPLETE,onSoundComplete); index++; } } onSoundComplete(event:Event): { playNextSong(); } } }
4. 跟踪音乐播放进度
使用Sound.length得到歌曲当前下载的长度(毫秒),SoundChannel.position得到当前的播放位置(毫秒)
Sound.length得到的并不是整首歌曲的长度,而是当前已下载的长度(毫秒)
要得到歌曲的总长度,要先得到"缓冲百分比"(bytesLoaded/bytesTotal),然后用Sound.length除以缓冲百分比,就得到了歌曲的真实长度(毫秒)
PS:可以这样理解,下载量有两种表示方式,一种是字节(byte)表示,一种是时间(毫秒)表示;字节所占的百分比 == 时间所占的百分比,用 下载量的时间表示 × 这个百分比值,就得到了歌曲总大小的时间表示
{ flash.display.Sprite; flash.events.Event; flash.media.Sound; flash.media.SoundChannel; flash.media.SoundLoaderContext; flash.net.URLRequest; Sample0618Sprite { music:Sound; sc:SoundChannel; downloadBar:Sprite; playBar:Sprite; Sample0618() { progressBox:Sprite = Sprite(); progressBox.graphics.beginFill(0xFFFFFF); progressBox.graphics.drawRect(0,0,300,5); progressBox.graphics.endFill(); progressBox.x = progressBox.y = 100; downloadBar = Sprite(); playBar = Sprite(); progressBox.addChild(downloadBar); progressBox.addChild(playBar); .addChild(progressBox); music = Sound(URLRequest()); sc = music.play(); .addEventListener(Event.ENTER_FRAME,onEnterFrame); } onEnterFrame(event:Event): { (music.bytesTotal>0) { downPercent:Number = music.bytesLoaded / music.bytesTotal; downloadBar.graphics.clear(); downloadBar.graphics.beginFill(0xCCCCCC); downloadBar.graphics.drawRect(0,0,300*downPercent,5); downloadBar.graphics.endFill(); (music.length>0 && downPercent>0) { songLength:int = music.length / downPercent; playPercent:Number = sc.position / songLength; playBar.graphics.clear(); playBar.graphics.beginFill(0xFF0000); playBar.graphics.drawRect(0,0,300*playPercent,5); playBar.graphics.endFill(); } } } } }
5. 暂停和继续播放音乐
通过调用Sound对象的close()方法可以停止播放,但是这样也停止了声音流,要想重新播放,必须再次调用load()方法
SoundChannel类提供了一个stop()方法,它可以让音乐暂停而不影响声音流中断,要想重新播放,调用play()方法即可
你会发现,当再次调用play()方法时,音乐会从头开始播放而不是从暂停的地方开始,这个时候需要记录SoundChannel类的position属性,把它作为play()方法的第一个参数
{ flash.display.Sprite; flash.events.MouseEvent; flash.media.Sound; flash.media.SoundChannel; flash.net.URLRequest; flash.text.TextField; Sample0619Sprite { music:Sound; sc:SoundChannel; playPostion:int= 0; isPlay:Boolean = ; Sample0619() { music = Sound(URLRequest()); btnPlay:TextField = TextField(); btnPlay.background = ; btnPlay.backgroundColor = 0xFFFF00; btnPlay.text = ; btnPlay.x = btnPlay.y = 100; btnPlay.addEventListener(MouseEvent.MOUSE_UP,onMouseUp); .addChild(btnPlay); } onMouseUp(event:MouseEvent): { isPlay = !isPlay; (isPlay) { sc = music.play(playPostion); } else { playPostion = sc.position; sc.stop(); } } } }
6. 获得音乐的左声道和右声道
任何声音,当在播放时产生强或弱的声波,我们称之为振幅,ActionScript3.0可获得一个立体声的左右声道的振幅,分别为SoundChannel的leftPeak和rightPeak属性,它们的值范围是0.0到1.0,1.0表示最大的音量
{ flash.display.Sprite; flash.events.Event; flash.media.Sound; flash.media.SoundChannel; flash.net.URLRequest; Sample0619Sprite { sc:SoundChannel; leftPeakBox:Sprite; rightPeakBox:Sprite = Sprite(); Sample0619() { music:Sound = Sound(URLRequest()); sc = music.play(); leftPeakBox = Sprite(); leftPeakBox.x = 100; leftPeakBox.y = 100; rightPeakBox = Sprite(); rightPeakBox.x = 100; rightPeakBox.y = 130; .addChild(leftPeakBox); .addChild(rightPeakBox); .addEventListener(Event.ENTER_FRAME,onEnterFrame); } onEnterFrame(event:Event): { leftPeakBox.graphics.clear(); leftPeakBox.graphics.beginFill(0xFFFF00); leftPeakBox.graphics.drawRect(0,0,sc.leftPeak * 100,10); leftPeakBox.graphics.endFill(); rightPeakBox.graphics.clear(); rightPeakBox.graphics.beginFill(0xFFFF00); rightPeakBox.graphics.drawRect(0,0,sc.rightPeak * 100,10); rightPeakBox.graphics.endFill(); } } }
7. 停止播放所有的音乐
使用SoundMixer.stopAll()
{ flash.display.Sprite; flash.events.MouseEvent; flash.media.Sound; flash.media.SoundMixer; flash.net.URLRequest; Sample0619Sprite { Sample0619() { music1:Sound = Sound(URLRequest()); music1.play(); music2:Sound = Sound(URLRequest()); music2.play(); stage.addEventListener(MouseEvent.CLICK,onClick); } onClick(event:MouseEvent): { SoundMixer.stopAll(); } } }
8. 读取声音文件的声谱(波形图)
要获得声谱数据,首先要创建一个空的ByteArray:
var spectrum:ByteArray = new ByteArray();
然后再将ByteArray作为SoundMixer.computeSpectrum()方法的参数:
SoundMixer.computeSpectrum(spectrum);
当调用方法结束后,ByteArray里会生成512个浮点值(范围为-1.0到1.0),其中前256个值表示左声道,后256个值表示右声道
{ flash.display.Bitmap; flash.display.BitmapData; flash.display.Sprite; flash.events.Event; flash.media.Sound; flash.media.SoundMixer; flash.net.URLRequest; flash.utils.ByteArray; Sample0619Sprite { bitmapData:BitmapData; Sample0619() { bitmapData = BitmapData(256,150,true,0xff000000); bitmap:Bitmap = Bitmap(bitmapData); bitmap.x = bitmap.y = 100; .addChild(bitmap); .addEventListener(Event.ENTER_FRAME,onEnterFrame); music:Sound = Sound(URLRequest()); music.play(); } onEnterFrame(event:Event): { bitmapData.fillRect(bitmapData.rect,0xff000000); array:ByteArray = ByteArray(); SoundMixer.computeSpectrum(array); (i:int=0;i<256;i++) { bitmapData.setPixel32(i,array.readFloat()*20+40,0xFFFF0000); } (j:int=0;j<256;j++) { bitmapData.setPixel32(j,array.readFloat()*20+80,0xFF0000FF); } } } }
PS:ByteArray()有一个游标,每次调用writeByte()、readFloat()等方法时,游标都会前移,可以通过访问或设置ByteArray.position来确定游标的位置
9. 改变音乐的音量和声道(平衡)
可以通过修改SoundChannel对象的soundTransform属性来设置
soundTransform属性包含两个属性:
volume(音量) -- 范围是0.0到1.0
pan(平衡) -- 范围是-1.0到1.0,-1为全左声道,1为全右声道
{ flash.display.Sprite; flash.events.MouseEvent; flash.media.Sound; flash.media.SoundChannel; flash.media.SoundTransform; flash.net.URLRequest; Sample0619Sprite { sc:SoundChannel; Sample0619() { music:Sound = Sound(URLRequest()); sc = music.play(); stage.addEventListener(MouseEvent.CLICK,onClick); } onClick(event:MouseEvent): { transform:SoundTransform = SoundTransform(); transform.volume = .5; transform.pan = -1; sc.soundTransform = transform; } } }
10. 载入并播放视频
大部分Flash视频内容都是以.flv格式存储的,通过ActionScript在运行时载入到Flash播放器
Flash视频载入有两种形式:渐进式下载和流下载。flv流视频需要流服务器,比如Flash Media Server。相反,渐进式下载不需要额外的软件,不过ActionScript处理这两种的方式是相同的
加载并播放视频分下面几个步骤:
<1> 创建一个NetConnection对象,并调用该对象的connect()方法。如果连接没有使用流服务器的本地flv文件,则connect(null)
var nc:NetConnection = new NetConnection();
nc.connect(null);
<2> 基于NetConnection创建一个NetStream对象并指定要加载的flv文件
var ns:NetStream = new NetStream(nc);
<3> 设置NetStream对象的client属性
ns.client = this;
//……
//public function onMetaData(event:Object):void
//……
<4> 创建Video对象,并调用该对象的attachNetStream()方法附加NetStream对象
var video:Video = new Video();
video.attachNetStream(ns);
this.addChild(video);
<5> 调用NetStream对象的play()方法播放视频
ns.play("demo.flv");
{ flash.display.Sprite; flash.media.Video; flash.net.NetConnection; flash.net.NetStream; Sample0622Sprite { Sample0622() { nc:NetConnection = NetConnection(); nc.connect(null); ns:NetStream = NetStream(nc); ns.client = this; video:Video = Video(); video.attachNetStream(ns); .addChild(video); ns.play(); } onMetaData(infoObject:Object): { (); for (propName:String infoObject) { (propName + + infoObject[propName]); } } } }