咨询热线:020-82315523 18988993510 18988993505

Flash Media Server 4.5 (fms4.5)教程四:RTMP流式音频

在这一系列教程的前面几部分内容中,我们只是介绍了视频流文件的处理。但是,也有很多时候,我们想在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播放音频文件。这其实和流式视频没有太大的差别。

现在开始:

  1. 下载这篇教程所需文件并解压缩。
  2. 创建一个音频文件的应用程序。尽管我们的第二部分:流媒体视频点播中的内容已经涵盖了这一步操作,但我们要了解,流式音频应用程序文件夹结构与流式视频应用程序文件夹结构有着完全相同的创建方法,这对我们而言是非常重要的。在那个文件夹里创建一个名为streams的文件夹,并在streams文件夹中创建一个名为_definst_的文件夹。在这种情况下,需要被转化为流式的音频文件就存放在这个_definst_文件夹里。
  3. 在C:Program FilesAdobeFlash Media Server 4.5applications目录下创建一个名为AudioStreams的新文件夹,打开AudioStreams文件夹,在其中创建名为streams的新文件夹。在这个新文件夹中创建一个名为_definst_的新文件夹,并把Exercise中的4个音频文件复制到这个_definst_文件夹中。注意:作者在这里要感谢加拿大多伦多市的汉博公立理工学院(Humber Institute of Advanced Learning and Technology)中传媒研究和信息技术学院(School of Media Studies and Information Technology )的院长William Hanna,感谢他允许我们使用由Humber学院无线电广播(Radio Broadcast)项目的学生制作的AndreHprofile.mp3片段。
  4. 打开SimpleAudio.FLA文件。当这个文件被打开之后,你就会看到,我们在时间轴上添加了层(如图1所示)。这些层包含了界面和代码的动作层,这里的界面就是一个显示在服务器和SWF文件之间发生了什么的文本框。

flash  Flash Media Server 4.5入门 第四部分:RTMP流式音频

图1. 包含了显示在服务器和SWF文件之间发生了什么的文本框的界面
  1. 点击ActionScript 层中的Frame 1,打开动作面板。
  2. 动作面板打开后,点击Script窗格的Line 1,输入下面的代码:
  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)来侦听四种特殊信息的连接和流动:连接成功,连接被拒,音频流开始播放,未找到音频流。下面是如何实现:

  1. 击两次回车,添加如下代码:
  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——是可以自我说明的,通常可以通过确认你的文件夹结构以及音频文件路径是正确的来确认。

  1. 击两次回车,添加启动音频播放的代码:
  /* 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文件,并把它添加到音频流中。

  1. 保存并测试动画。

音频流控制

在前面的练习中,我们向你演示了如何创建一个音频文件流式转化的应用程序以及如何使其播放。如果我们的介绍到此结束,你可能就要开始抱怨。在一点也没有使用户避开讨厌的东西的情况下,这并不是播放音频文件的最佳做法。在下面的练习中,我们不仅要教会用户停止放音,还会向你演示如何显示时间以及如何暂停循迹。

现在开始:

  1. 打开你的Exercise文件夹中的ControlAudio.fla文件。文件被打开之后(如图2所示),你会看到,我们添加了层,并在Controls层中添加了几个源于Flash的按钮。如果你打开Properties面板,你也会注意到,我们给了每个按钮一个实体名。

flash  Flash Media Server 4.5入门 第四部分:RTMP流式音频

图2. 使用了源于Flsh公用图库按钮控制放音的项目
  1. 点击Actions层的Frame 1打开Actions面板。打开之后,在Script窗格中输入下面的代码:
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变量的添加。我们打算在监测音频是否处于播放状态的过程中绑定几个功能。我们也想向用户演示音轨播放时有多少的时间流逝。为了做到这一点,我们创建了一个密切关注事件的监听器。

  1. 击两次回车,输入下面的代码使音频流动起来:
function beginStream():void {     
ns = new NetStream(nc);
ns.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
ns.play("mp3:AndreHprofile");
ns.pause();
timeField.text = "ready";
}

乍看之下,你可能会觉得这样有点古怪,我们一打开音频流就暂停。我们必须这样,因为在通常情况下,我们一开始播放音频流,无线电波报就会马上从用户的扬声器发出。这不是我们想要的。我们想使用户有机会选择音频流的开关。

  1. 击两次回车,输入下面的为Control层按钮分配功能的代码来开始这个过程
playBtn.addEventListener(MouseEvent.CLICK, playStream);  
pauseBtn.addEventListener(MouseEvent.CLICK, pauseStream);
stopBtn.addEventListener(MouseEvent.CLICK, stopStream);
  1. 既然你已经告诉了Flash每一个按钮应该有什么用,是时候开始编写这三个以playStream()开始的函数的代码了。输入下面的代码:
function playStream(e:MouseEvent):void {     
if(!isPlaying){
ns.resume();
isPlaying = true;
}
}

Play按钮的逻辑语言是相当有效的。点击按钮时,第一行的代码检测了音频流是否播放(!isPlaying)。如果音频没有播放,只有三种可能的状况:beginNetStream()函数暂停了音频流的播放,用户点击了Pause按钮,或者用户点击了Stop按钮。不管在哪种情况下,音频流被重新开始——音轨开始播放——isPlaying变量的Boolean值被设置为真。

  1. 击两次回车,输入Pause和Stop按钮的函数算法:
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对象时,你开始、终止或是暂停的并不是音轨本身。你是在告知服务器不再向音频流发送音频数据还是重新向音频流发送音频数据。

  1. 最后需要输入的代码组是Output层的时间显示代码组。击两次回车,然后输入:
  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组件。

现在开始:

  1. 打开你的Exercise文件夹里的SelectAudio.fla文件。
  2. 打开文件之后,选择动作层的第一帧,打开Actions面板。
  3. 点击“脚本”面板的第一行,并键入下列代码,以导入下面的7个类:
  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级使组件运行。

  1. 确立分级之后,你现在就可以创建播放列表了。点击Script窗格的Line 6,然后输入:
  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()函数。

  1. 点击Script窗格的line 44,输入下面的代码来编写switchStream()函数:
  function switchStream(e:Event):void {     
ns.play("mp3:" + e.target.selectedItem.data);
if(!isPlaying){
ns.pause();
}
}

这里最大的改变是在play()方法上。你直接获取列表项目的数据部分并使用它,而不是输入名字。

  1. 保存并测试文件。正如你所看到(见图3)和听到的,你创建了一个你可以在三个文件中做选择的应用程序。它的圆滑之处在于,把三首歌扩展到30首甚至更多,在算法上并没有很大的

flash  Flash Media Server 4.5入门 第四部分:RTMP流式音频

图3. 填入了List组件,正在播放Young Lions

这一系列教程的下一部分内容将会向你介绍HTTP动态流转化的过程,并向你演示如何使用Flash Media Server 4.5的多比特率的特性。下一篇教程再见。

迅恒运营的IDC数据中心机房介绍
机房名称 机房介绍 是否推荐
广州较场西路机房 中国电信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等线路接入,优化线路到中国大陆速度快,延迟低,网络稳定。
迅恒十多年IT企业和IDC运维经验为您提供优质服务
迅恒专注网站建设10多年,几十人技术团队,品质卓越,服务有保障!
  • 云虚拟主机

    ¥99元/年起 网站空间 原价:199元

  • 独立物理服务器

    ¥488/月起 物理机 原价:699元

  • 网站建设

    ¥580企业建站 原价:1999元起

    迅恒建站·ABOUT US

    迅恒专注于企业建站,海量精美网站风格模板供您选择!

广州网站设计公司哪家好

    建站流程·PROCEDURE

    网络营销推广的第一步就是做一个属于自己的网站

  • 沟通联系

    提出需求,咨询报价
  • 达成协议

    交流达成详细建站协议
  • 支付费用

    支付建站相关费用
  • 建站开发

    根据客户需求,制作网站
  • 验收

    客户验收网站
  • 提交上线

    验收合格,解析域名上线
  • 售后服务

    一对一的售后服务客服
    • 我们的优势·OUR STRENGTHS

      做网站,为什么要选迅恒建站?

  • 技术团队

    专业的设计团队、技术团队,为客户提供专业的技术服务支持

  • 源码交付

    客户查验合格,提供源码交付/FTP信息。网站商业授权,避免产权纠纷

  • 四合一建站多终端展示

    网站能够在CP+平板+手机+小程序 完美响应展示。

  • 无隐形收费

    所有收费项公开透明,正规签订合同,合同清楚明确

  • 高端设计

    提供网站个性化定制设计,拒绝千篇一律

  • 安全稳定

    我司与华为云/腾讯云长期合作,采用安全稳定服务器,保障网站安全稳定运行

  • 迅恒累计为上万网站稳定运行 100000000
    机房接入电信带宽400G、联通带宽200G、移动带宽100G,直连核心骨干网络;
    所有重要网络节点和核心设备均采用华为电信级交换设备,网络总体交换能力高达684G,网络联通率达到99.99%,
    并且多点冗余备份,提高网络性能,避免单点故障。
  • 快速导航
  • 广州迅恒信息科技有限公司:
  • 增值电信业务经营许可证和ICP备案 粤B2-20061054
  • 公司业务咨询电话:
  • 020-82315523
  • 公司企业QQ/商务QQ:
  • 938040335 16764407 923109991 20300996
  • 销售经理:18988993510 13533213185
  • 备案咨询和售后服务电话:18988993505
  • 专注广州服务器托管
    请加销售经理微信
    Copyright 2005-2020 迅恒 版权所有   公司地址:广州市天河区中山大道中路77号  广州机房:较长西路21号广州电信超级信息港 香港机房:香港新界葵涌葵丰街钟意恒胜中心  粤公网安备44010602002183