在这一系列教程的前面几部分内容中,我们只是介绍了视频流文件的处理。但是,也有很多时候,我们想在Flash Media Server中导入音频文件。关于音频和Flash Media Server 4.5,我们首先应该知道,这和使用ActionScript 3处理本地音频文件完全不同。在ActionScript中,我们可以使用许多Sound选项来处理音频文件。但是在FMS4.5中,这些选项所起的作用就微乎其微了。原因很简单:文件被加入到了音频流中,就其本身而言,由于需要使用完全不同的传输方法,ActionScript 3中的attachAudio()
方法从各方面来说,都不起作用了。
Flash Media Server 4.5可以转化多种不同的音频格式为音频流:SPEEX、G.711、Nellymoser、MP3以及AAC等。同时还可以转化部分为Flash所支持的AAC格式的文件,如AAC+、HE-AAC、AAC v1以及AAC v2等。这是好的一方面。坏的一方面是,AAC格式文件只能在Adobe Flash Player 9.0.115.0及其以上版本中播放。正是由于2007年下半年Flash Player 更新的发布与H.264标准的重新启用的共同作用,才使得上述需求得以实现。但是,你所遇到的最通常的音频格式是MP3和AAC。要对AAC格式有一个宏观上的了解,可以参阅Fabio Sonnati的这篇博文:AAC是如何工作的。
既然你已经知道了你可以使用什么,现在我们就教你如何在实际操作中使用它。
在这个例子中,我们要向你展示如何通过Flash Media Server 4.5播放音频文件。这其实和流式视频没有太大的差别。
现在开始:
import flash.net.NetConnection;
import flash.net.NetStream;
import flash.events.NetStatusEvent;
var nc:NetConnection = new NetConnection();
var ns:NetStream;
当处理点播视频时,在音频播放之前,你需要创建一个NetConnection对象,并对其命名:在这种情况下命名为ns。在内务信息移开的情况下,你可以把注意力转移到连接到服务器和侦听服务器与Flash之间信息上来。
注意:在Adobe Flash Professional前面的几个版本中,当你对一个变量分级时,这个分级的输入语句是被加在Script窗格的顶端的。这是一个很好的特点,因为这是输入分级的一个常见的最佳做法。问题是,这在Flash中有点前后矛盾。这些语句只在有些情况下被添加了。意识到这一点之后,在Flash社区中,不依赖于这一特点,只在必要的时候手动添加输入语句已经成为了一个规矩。
在这个例子中,你将会用到一个常用的处理器(netStatusHandler
)来侦听四种特殊信息的连接和流动:连接成功,连接被拒,音频流开始播放,未找到音频流。下面是如何实现:
nc.connect("rtmp://localhost/AudioStreams");
nc.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
function netStatusHandler(e:NetStatusEvent):void {
traceField.text = e.info.code + "n" + traceField.text;
trace(e.info.code);
switch(e.info.code){
case "NetConnection.Connect.Success":
beginStream();
break;
case "NetConnection.Connect.Rejected":
break;
case "NetStream.Play.Start":
break;
case "NetStream.Play.StreamNotFound":
trace("Can't find the stream.");
break;
}
}
我们会向你简单介绍一下这个功能。它的目的是捕获四个特殊的NetStatusEvent事件并对其作出反应:连接成功,连接被拒,音频流开始播放,未找到音频流。当你测试一个项目时,如果这些事件发生,就会在层2中的文本框中显示出详细的音频流的活动记录。
显然,如果有连接的存在——NetConnection.Connect.Success
——音频文件就会开始播放(在这个例子中,通过调用beginStream()
功能)。如果没有连接的存在——NetConnection.Connect.Rejected
——核实你的FMS 4.5副本确实在运行,确认你的应用程序代码的拼写与应用程序文件夹相匹配。
接下来就是要核实音频流正在播放。NetStream.Play.Start
就是对此进行确认的信息。最后要核实的信息——NetStream.Play.StreamNotFound
——是可以自我说明的,通常可以通过确认你的文件夹结构以及音频文件路径是正确的来确认。
/* this function will handle creation of the NetStream object.
we invoke NetStream.play() to begin streaming. */
function beginStream():void {
ns = new NetStream(nc);
ns.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
ns.play("mp3:AndreHprofile");
}
正如你所看到的那样,其神奇之处就在于netStatusHandler()
函数的调用。第一步是在音频流中加入NetConnection,然后侦听服务器与SWF应用程序间的讯息流水平的信息。一切准备就绪之后,NetStream级的play()
程序就会寻找名为AndreHProfile的MP3文件,并把它添加到音频流中。
在前面的练习中,我们向你演示了如何创建一个音频文件流式转化的应用程序以及如何使其播放。如果我们的介绍到此结束,你可能就要开始抱怨。在一点也没有使用户避开讨厌的东西的情况下,这并不是播放音频文件的最佳做法。在下面的练习中,我们不仅要教会用户停止放音,还会向你演示如何显示时间以及如何暂停循迹。
现在开始:
import flash.net.NetConnection;
import flash.net.NetStream;
import flash.events.NetStatusEvent;
import flash.events.Event;
import flash.events.MouseEvent;
var isPlaying:Boolean = false;
var nc: NetConnection = new NetConnection();
var ns:NetStream;
addEventListener(Event.ENTER_FRAME, monitorTime);
nc.connect("rtmp://localhost/AudioStream");
nc.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
function netStatusHandler(e:NetStatusEvent):void {
traceField.text = e.info.code + "n" + traceField.text;
trace(e.info.code);
switch(e.info.code){
case "NetConnection.Connect.Success":
beginStream();
break;
case "NetConnection.Connect.Rejected":
break;
case "NetStream.Play.Start":
break;
case "NetStream.Play.StreamNotFound":
trace("Can't find the stream");
break;
}
}
这个代码和前面项目中的代码并没有很大的差别。但是,它有一些重要的添加。首先是isPlaying
变量的添加。我们打算在监测音频是否处于播放状态的过程中绑定几个功能。我们也想向用户演示音轨播放时有多少的时间流逝。为了做到这一点,我们创建了一个密切关注事件的监听器。
function beginStream():void {
ns = new NetStream(nc);
ns.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
ns.play("mp3:AndreHprofile");
ns.pause();
timeField.text = "ready";
}
乍看之下,你可能会觉得这样有点古怪,我们一打开音频流就暂停。我们必须这样,因为在通常情况下,我们一开始播放音频流,无线电波报就会马上从用户的扬声器发出。这不是我们想要的。我们想使用户有机会选择音频流的开关。
playBtn.addEventListener(MouseEvent.CLICK, playStream);
pauseBtn.addEventListener(MouseEvent.CLICK, pauseStream);
stopBtn.addEventListener(MouseEvent.CLICK, stopStream);
playStream()
开始的函数的代码了。输入下面的代码:function playStream(e:MouseEvent):void {
if(!isPlaying){
ns.resume();
isPlaying = true;
}
}
Play按钮的逻辑语言是相当有效的。点击按钮时,第一行的代码检测了音频流是否播放(!isPlaying
)。如果音频没有播放,只有三种可能的状况:beginNetStream()
函数暂停了音频流的播放,用户点击了Pause按钮,或者用户点击了Stop按钮。不管在哪种情况下,音频流被重新开始——音轨开始播放——isPlaying
变量的Boolean值被设置为真。
function pauseStream(e:MouseEvent):void {
if(isPlaying){
isPlaying = false;
ns.pause();
}
}
function stopStream(e:MouseEvent):void {
isPlaying = false;
ns.close();
timeField.text = "stopped";
}
除了在点击Stop按钮时,timeField区域的文字改为”stopped
“之外,这里并没有多少新的东西。如果你对数据流媒体的使用不是很熟悉,在使用Sound对象时,你开始、终止或是暂停的并不是音轨本身。你是在告知服务器不再向音频流发送音频数据还是重新向音频流发送音频数据。
function monitorTime(e:Event):void {
if(isPlaying){
timeField.text = Math.round(ns.time) + " seconds...";
}
}
除了在点击Stop按钮时,timeField区域的文字改为”stopped
“之外,这里并没有多少新的东西。如果你对数据流媒体的使用不是很熟悉,在使用Sound对象时,你开始、终止或是暂停的并不是音轨本身。你是在告知服务器不再向音频流发送音频数据还是重新向音频流发送音频数据。
这个练习之前的内容都是关于单个音频文件的播放。既然你已经知道了如何去实现它,我们接下来就向你演示如何使用户可以在多音频文件中选择播放。
我们其中一名作者的女婿,Phil Darling,是多伦多市一个相当火爆的”indie”乐队,TinBangs的低音歌手和创始人。这个乐队刚发布了一个包含有三首歌曲的EP唱片,计划把它们以音频流的形式发布出去,让他们的歌迷们听到他们的新作品。
注意:作者在这里要感谢Phil Darling和乐队的其他成员,感谢他们允许我们在这个例子中使用这些文件。
这就意味着要给用户提供可以在这三首歌曲中任意选择的机会。为了实现这一目的,我们选择了使用打包在Flash Professional CS 5.5软件中的List组件。
注意:也可以使用其他的方法来实现这个项目,从使用ComboBox组件到使用XML文件作为DataProvider都可以。由于空间的限制,我们选择了使用List组件。
现在开始:
import flash.net.NetConnection;
import flash.net.NetStream;
import flash.events.NetStatusEvent;
import flash.events.Event;
import flash.events.MouseEvent;
import fl.data.DataProvider;
import fl.controls.List
要使用List组件,你需要使用DataProvider级向List组件供给数据,使用controls软件包中的List级使组件运行。
import flash.net.NetConnection;
import flash.net.NetStream;
import flash.events.NetStatusEvent;
import flash.events.Event;
import flash.events.MouseEvent;
import fl.data.DataProvider;
import fl.controls.List
要使用List组件,你需要使用DataProvider级向List组件供给数据,使用controls
软件包中的List级使组件运行。
var playList:Array = new Array();
playList.push({label:"White Lies (Timekiller)",data:"WhiteLies(Timekiller)"});
playList.push({label:"Young Lions", data:"YoungLions"});
playList.push({label:"Your Sky Is Falling", data:"YourSkyIsFalling"});
audioList.dataProvider = new DataProvider(playList);
audioList.addEventListener(Event.CHANGE, switchStream);
我们通过创建一个名为playList
的数组开始。播放列表中的每一个项目都要在List组件中显示出来。这个组件需要两块的信息。第一块是标签,当应用程序运行时在组件中显示的文字信息。第二块是需要使用的数据,在这种情况下指的是音频文件的名字。List组件然后就会被告知,playList
会向其提供数据。我们也会听取用户在List ( Event.CHANGE
)中做出的选择,在检测到这一点之后,就开始执行switchStream()
函数。
switchStream()
函数:function switchStream(e:Event):void {
ns.play("mp3:" + e.target.selectedItem.data);
if(!isPlaying){
ns.pause();
}
}
这里最大的改变是在play()
方法上。你直接获取列表项目的数据部分并使用它,而不是输入名字。
这一系列教程的下一部分内容将会向你介绍HTTP动态流转化的过程,并向你演示如何使用Flash Media Server 4.5的多比特率的特性。下一篇教程再见。
机房名称 | 机房介绍 | 是否推荐 |
---|---|---|
广州较场西路机房 | 中国电信5星级机房,华南骨干出口,广州市中心机房,交通便利,总带宽200G,为华南骨干出口。 | |
广州人民中路机房 | 中国电信3星级机房,超高速的20Gx2主备双线路带宽直接接入ChinaNET骨干层。 | |
广州天河科技园机房 | 天河软件园建中路4号,中国互联网应急中心机房,国家政府机关直属。多线接入骨干BGP线路。 | |
电子商务部广州机房 | 天河软件建业路上(科韵路)的国际电子商务中心大厦甲级写字楼内,机房环境一流。多线接入骨干BGP线路。 | |
广州电信加速器机房 | 位于广州市萝岗区开源大道1号企业加速器B1栋一楼,按照国际T3+及国标B+级标准建造,机房环境一流。多线接入骨干网。 | |
广州移动旗锐机房 | 广州科学城南翔二路1号旗锐数字科技园区内,属于第三方私立机房,现由移动运营,从粤西汇聚节点直连CMNET骨干网。 | |
广州移动南方基地机房 | 中国移动广州南方基地机房位于广州市天河软件园高塘大道333号,用于移动骨干网线路,是移动服务器托管优质机房。 | |
东莞电信道滘机房 | 中国电信4星级机房,总带宽320G,可提供电信和多线BGP线路,华南骨干机房,稳定高速,性价比高。 | |
东莞电信东城机房 | 中国电信4星级机房,总带宽320G,性价比高,可提供电信和多线BGP线路和200G集群硬件防火墙VIP防护。 | |
东莞电信樟木头机房 | 中国电信4星级机房,总带宽320G,可提供电信和多线BGP线路和100G集群硬件防火墙企业级防护。 | |
深圳互联港湾机房 | 深圳南山高新区中区软件大厦四楼,电信3星级机房,20G带宽接入骨干网络。 | |
深圳南山科兴机房 | 位于深圳市南山区科技园科苑路15号科兴科学园,3星级机房,可提供双线接入等业务。 | |
深圳百旺信机房 | 深圳市南山区西丽松白公路百旺信工业区A区(一区)一栋属于第三方机房,可提供双线接入等业务。 | |
佛山电信信息大厦机房 | 佛山市汾江南路35号电信佛山分公司信息大厦8-9层,是中国电信3星级机房,可提供双线接入等业务。 | |
中山电信火炬机房 | 机房位于中山市火炬区康乐大道47号电信3楼,是中国电信3星级机房,可提供双线接入等业务。 | |
江苏徐州电信机房 | 机房位于江苏徐州市新城区镜泊东路4号,徐州市档案馆东侧,是中国电信3星级机房,可提供双线接入等业务。 | |
江苏常州电信机房 | 机房位于江苏省常州市清凉路108号常州信息港,是中国电信4星级机房,可提供双线接入等业务。 | |
香港TKO机房 | 机房靠近香港交易所的数据中心位置和香港商业中心,拥有PCCW、GTT、Cogent、Telia、TATA、CT、CN2、CU线路。 | |
香港将军澳机房 | 机房在香港新界將軍澳工業邨駿昌街22號,与阿里云香港机房同属一栋楼,拥有多种线路接入。 | |
香港新世界机房 | 香港新世界机房的海底电缆系统遍布全球,能直接连接多个国家,免备案,服务器租用、云服务器等业务。 | |
香港NTT机房 | 香港NTT电讯机房,是一座专用数据中心,在香港大埔,免备案,提供服务器租用、VPS云服务器等业务。 | |
美国洛杉矶机房 | 位于美国洛杉矶,直连全球,是全球带宽最集中的地方,是外贸企业首选,该机房只提供服务器租用业务。 | |
美国加州DCS机房 | 位于美国加州,直连全球,是美国的华人机房,是外贸企业首选,该机房只提供服务器租用业务。 | |
美国圣何塞机房 | 位于美国圣何塞,紧邻科技中心-硅谷,直连全球,是外贸企业首选,该机房只提供服务器租用业务。 | |
韩国首尔KT机房 | 韩国首尔的江南区道谷洞数据中心,光纤直连电信(CN2)、移动、PCCW、NTT等网络核心骨干。 | |
台湾中华电信机房 | 台湾中华电信机房位于台湾台北市114内湖区瑞光路68号3楼,是台湾对外最重要的电信枢纽之一。 | |
菲律宾PLDT机房 | 菲律宾PLDT机房拥有PCCW、TATA、CT、CN2等线路接入,优化线路到中国大陆速度快,延迟低,网络稳定。 |
¥99元/年起 网站空间 原价:199元
¥488/月起 物理机 原价:699元
¥580起 企业建站 原价:1999元起
迅恒专注于企业建站,海量精美网站风格模板供您选择!
网络营销推广的第一步就是做一个属于自己的网站
做网站,为什么要选迅恒建站?
专业的设计团队、技术团队,为客户提供专业的技术服务支持
客户查验合格,提供源码交付/FTP信息。网站商业授权,避免产权纠纷
网站能够在CP+平板+手机+小程序 完美响应展示。
所有收费项公开透明,正规签订合同,合同清楚明确
提供网站个性化定制设计,拒绝千篇一律
我司与华为云/腾讯云长期合作,采用安全稳定服务器,保障网站安全稳定运行