FMS3技术文档之五Word下载.docx
《FMS3技术文档之五Word下载.docx》由会员分享,可在线阅读,更多相关《FMS3技术文档之五Word下载.docx(28页珍藏版)》请在冰豆网上搜索。
第2章和第3章介绍了NetStream类,但是它们没有详细的介绍它。
本章中开始研究NetStream类用在现场流中,然后加入到最简单地例子中。
使用NetStream类,目的是捕捉从视频和麦克风传来的音频和视频输入,然后发送他们给另一个人看和听。
这个程序调用以下NetStream方法:
∙·
NetStream.connect(myNetConnection)
NetStream.attachAudio(microphone)
NetStream.attachVideo(camera)
NetStream.publish(“streamName“)
NetStream.play(“streamName“)
在看产生一个双向A/V连接顺序中所必需的,流通过NetConnection连接到服务器,用来建立一个在用户和应用程序之间的连接。
发布流的时候需要添加要发布在的摄像头和麦克风。
流发送到FMS3服务器,然后服务器发送它到连接上的客户端。
下面的代码片断展示了这些步骤:
//StreamOut
nsOut=newNetStream(nc);
nsOut.attachAudio(mic);
nsOut.attachCamera(cam);
nsOut.publish("
left"
"
live"
);
下面这些代码所做的事情:
建立一个流,联合一个网络连接到一个连接到FMS3
附加麦克风到流
附加摄像头到流
使用唯一的流名称发布流
现在在您已经有了发布的模块,设立一个播放的模块来捕获和播放被送往的流。
您不想捕捉你刚发布的相同的流,所以您将需要有一个除了”left”的流名称。
播放流将被称为”right”,要紧记,它代表了当前的接受者。
(其他接受者播放”right”和接收“left”)为了捕捉进来的流,你需要把流附加到Video对像上。
流包含音频和视频被处理为一个单一的单元—一个视频。
您不必把声音对象附加到一个对像上,当你发送视频时。
因此,你把流附加到视频对象上使用attachVideo()方法。
一旦流正在发送到正确的位置(嵌入式视频对象),所有你需要做的是就是播放流,如以下代码段所示:
//StreamIn
nsIn=newNetStream(nc);
nsIn.play("
right"
vidStream.attachNetStream(nsIn);
阅读和显示进来的流的顺序,然后将是:
把流附加到视频对像上
播放流
有更多方法创造一个双向的A/V应用程序,但核心这样做的是与NetStream类方法工作。
一旦您直接在您的心目中获得该命令,其余的相当容易。
5.4.世界上最简单的双向的A/V聊天的应用程序
为了制作一个简单的双向A/V聊天应用程序,需要两个模块。
紧记FMS3应用程序只是简单的表现在你使用的RTMPURL为简单的名称,你可以在一个应用程序中有多个模块。
换句话说就是,应用的名称是在服务端的目录的名称。
总而言之,你将要开始制作这个应用程序。
这个应用程序的名称将会很简单。
你将会有两个模块,Easy1和Easy2。
每个模块会通过存储在服务端的应用程序,连接到FMS3。
对于这个应用程序,每个模块将会写成用来接受其它人发送的流。
如你所见,一个简单的换来做所有真实的工作。
所以任务真正地包括写一个模块,然后复制它,做一些修改。
图5-2展示了两个视频将出现的区域,和它们的实例名:
图5-2.Videoinstances
开始之前,回顾一下需要的以下类和对像:
Classes
NetConnection
NetStream
NetStatusEvent
Camera
Microphone
Video
按以下步骤来制作这个聊天应用程序:
1.建立一个Easy1.fla
2.用文本工具添加一个文本,内容为Easy#1,x=205,y=223
3.在文档类中输入Easy1
4.建立一个Easy1.as与Easy1.fla同一目录
Example5-1.Easy1.as
CodeView:
package
{
importflash.display.Sprite;
importflash.events.NetStatusEvent;
import.NetConnection;
import.NetStream;
importflash.media.Camera;
importflash.media.Microphone;
importflash.media.Video;
publicclassEasy1extendsSprite
{
privatevarnc:
NetConnection;
privatevargood:
Boolean;
privatevarrtmpNow:
String;
privatevarnsIn:
NetStream;
privatevarnsOut:
privatevarcam:
Camera;
privatevarmic:
Microphone;
privatevarvidLocal:
Video;
privatevarvidStream:
publicfunctionEasy1()
rtmpNow="
rtmp:
//
nc=newNetConnection();
nc.connect(rtmpNow);
nc.addEventListener(NetStatusEvent.NET_STATUS,checkCon);
setCam();
setMic();
setVideo();
}
privatefunctioncheckCon(e:
NetStatusEvent):
void
good=e.info.code=="
NetConnection.Connect.Success"
;
if(good)
nsOut=newNetStream(nc);
nsOut.attachAudio(mic);
nsOut.attachCamera(cam);
nsOut.publish("
nsIn=newNetStream(nc);
nsIn.play("
vidStream.attachNetStream(nsIn);
privatefunctionsetCam()
cam=Camera.getCamera();
cam.setKeyFrameInterval(9);
cam.setMode(240,180,15);
cam.setQuality(0,80);
privatefunctionsetMic()
mic=Microphone.getMicrophone();
mic.gain=85;
mic.rate=11;
mic.setSilenceLevel(15,2000);
privatefunctionsetVideo()
vidLocal=newVideo(cam.width,cam.height);
addChild(vidLocal);
vidLocal.x=15;
vidLocal.y=30;
vidLocal.attachCamera(cam);
vidStream=newVideo(cam.width,cam.height);
addChild(vidStream);
vidStream.x=(vidLocal.x+cam.width+10);
vidStream.y=vidLocal.y;
}
6.确保rtmpNow=”rtmp:
//URL,不管它是在你本机,LANIP地址或者远程服务器的URL
7.发布HTML和SWF
这已经完成了第一个模块,测试它,你会在左边窗口中看到你自已。
下一步将简单的改变第一个模块。
8.Easy1.fla另存为Easy2.fla
9.把文本改为Easy2
10.把Easy1.as另存为Easy2.as
11.改变类名称和构造函数的名称为Easy2:
publicclassEasy2extendsSprite
....
publicfunctionEasy2()
12.在checkCon函数中,改变以下两行:
->
->
13.保存Easy2.as文件。
现在你的两个模块应用程序已经完成。
步骤12显示了应用程序中的关键几行,Easy1发布一个叫left的流和播放一个叫right的流。
Easy2刚好与Easy1相反,所以每个模块的用户可以播放另一个人的流。
测试这个应用程序,理论上你需要两个摄像头和两台电脑。
一个用户运行Easy1.html,另一个用户运行Easy2.html。
不管在LAN或者网上的远程服务器,两个模块都要能访问到FMS3服务器。
图5-3中当你运行两个模块时你应该看到的。
图5-3.Two-wayAudio-Videochat
5.5.一个更好的双向聊天应用程序
虽然两个模块的聊天室应用程序是很容易就建立和良好的工作,其唯一目的是显示创建一个双向聊天需要最少的代码。
更好的选择是一个双向的聊天室有一个单一的模块,并且可以告诉哪种方式来设定流。
最佳方法是将其写入服务器端脚本。
一个FMS3应用程序的概念是最好的赞赏,当你考虑一个脚本,所有用户使用相同的应用得到不同的信息。
您熟悉变量在一个非FMS应用程序改变,但是使用非服务端数据,像数据库。
但是,如果别人使用相同的应用,你这样做不会影响其他人使用相同的应用。
例如线上游戏,没有服务器端组件。
你的分数将不会影响玩同样游戏的其他人的分数。
换个方式来考虑这个应用程序不是一个共享的。
在第3章,“非持久客户端远程共享对像”,你学习了共享对象和看到几个用户如何通过一个共同的应用连接,可能会影响他人。
没有服务器端脚本应用在这些应用程序中,因为客户端脚本的沟通通过FMS而不需要一个脚本在服务器上。
这一章向您介绍服务器端脚本追踪,不管一个或两个用户在一时间内都使用相同的应用程序。
脚本与在前面讨论的两个模块的应用程序部分有很大的共通点,接下来这个应用程序只使用一个。
因为由两个模块所做的工作现在由服务器端脚本来操作了,您只需要一个单一的模块。
5.5.1.KeepingTrackofUsers跟踪用户
在开始服务端脚本之前,你必须转变一下你的思想:
不是使用ActionScript3.0的,对FlashMediaServer3.0,基本上是您使用的ActionScript1.0与少数的类。
(如果您不熟悉的ActionScript1.0,把该脚本想像为一个略加修改的JavaScript)。
这意味着数据没有类型(没有指定数据类型)和您可以使用prototype(原型)来创建类。
无论如何,这第一个脚本是只会做一件事。
使用一个数组与两个要素,它将使用array.pop()方法来提供两个字符串中的一个,left和right。
当客户端离开,使用array.push()来把元素放置回去。
了解这一切是如何工作的,您首先需要了解两个主要服务器端的类,Application和Client。
服务端ActionScript有大概-15个类。
其中三个类一个可以处理XML和两个处理SOAP。
实际上,你需要花大部分的时候在其它4个类上:
Application,Client,SharedObject和Stream。
在这个例子中,你只需要前面两个。
5.5.1.1.Application类
顾名思义,Application类处理整个应用程序。
每个应用程序,不管有多少客户端连接,都有一个单一的应用程序对象。
是什么使这个类不寻常的是,这是自动实例作为应用。
所以,当你写SSAS代码,您不必创建一个对象,它自动为您创建。
因此,使用这个类,您只需这样写:
application.doSomething...
这可能会混乱,想像这是少了一个步骤来实例化一个类的实例。
剩下的章节会探究服务端代码,将会进入到更多的服务端类中,同样也会涉及到Application类的更多的属性,方法,和事件,
Application事件
·
onAppStart
onConnect
onDisconect
Application方法
rejectConnection
acceptConnection
客户端只要连接到该应用程序就可以触发应用程序事件。
第一个客户端打开应用程序触发onAppStart事件。
随后使用者(客户)将不会影响这一事件,只要在应用程序运行时-其中最后客户离开了应用程序20分钟后,-事件并不触发。
每个连接连接到应用程序都会触发onConnect事件。
每个新连接都是通过RTMP来连接的,这个连接可以用Application方法来接受或者拒绝,acceptConnection或者rejectConnection
每当一个客户端断开,客户从客户数组中移除。
您也可以使用Application.onDisconnect事件来查找哪个客户断开了。
这出现在服务器端脚本中。
5.5.1.2.Client类
像Application类,Client类也自动建立一个它的实例。
每一个在应用程序中的客户,都变成应用程序的客户数组中的一部分,每个客户是一个数组元素。
例如,假设Nancy,PeteandJuan都连接到相同的应用程序中,Nancy是第一个连接,Juan是最后一个连接。
如下所示:
Nancy=application.clients[0];
Pete=application.clients[1];
Juan=application.clients[2];
注意Application的客户属性是带个s:
clinets(您可以节省大量的调试时间,记住这一点。
)像服务器端脚本显示,Client的实例名称是currentClient。
有点像下面这样:
currentClient=newClient();
然而,这并不是Client的实例名称如何生效。
相反,客户端从它连接到服务器的事件函数得到其参考的名字。
图5-4显示正确的命名程序。
图5-4.NamingClientinstance
currentClient实例对所有客户都有用处,但是紧记,每个连接到应用程序的用户都是Application.clients数组的一部分。
像所有类一样,这个实例也可以使用内置的属性,方法和事件。
可是,你也可以建立你自已的属性和方法和其它任何类一样。
在这章中的应用程序中,属性和方法是为application创建的。
脚本中包含用户的方法和属性:
用户的方法写成:
currentClient.streamSelect=function();
这个方法是由客户端调用的。
看看客户端脚本是怎么办调用的
添加到currentClient实例的属性叫cliNow,它指定为vidStreams数组的值
currentClient.cliNow=vidStreams.pop();
在脚本顶部中的数组,只有两个元素出现:
”right”和”left”。
在streamSelect方法中返回给客户端currentClient.clinow属性的值。
5.5.2.TheServer-SideScript服务端脚本
建立一个服务端脚本,产生一个只有两个参与的客户端名称和拒绝其它的客户端,跟随以下步骤:
1.建立一个deux.asc
2.输入以下代码
Example5-2.deux.asc
//Two-elementarray
vidStreams=["
];
//应用程序第一次启动
application.onAppStart=function()
trace("
Thedeuxisoutofthedeck"
};
//AcurrentClient(user)attemptstoconnect
application.onConnect=function(currentClient)
//如果数组是空的话就拒绝连接
//(当前有两个用户正在使用应用程序)
if(vidStreams.length<
=0)
application.rejectConnection(currentClient);
//StorearrayelementincurrentClientproperty
currentClient.cliNow=vidStreams.pop();
application.acceptConnection(currentClient);
currentClient.streamSelect=function()
Stream"
+currentClient.cliNow+"
used"
//SentthepropertytoClientobject
returncurrentClient.cliNow;
};
application.onDisconnect=function(currentClient)
//WhencurrentClientleavesputtheelementbackinarray
vidStreams.push(currentClient.cliNow);
3.在FlashMediaServer3目录下的application目录下建立一个deux的目录
4.保存deux.asc在deux目录下。
或者你也可以把它重命名为main.asc,根据你的喜好。
(我比较喜欢命名为应用程序的名称,如果我所有都命名为main.asc,一个不注意被覆盖或者移动,就非常难找了)
在开始写客户端脚本之前,你需要明白这个服务端脚本到底是在什么。
无论何时,一个客户端连接到应用程序时,它从数组中删除一个元素,然后通过客户端脚本返回它给客户端。
该脚本发送字符串,以确定流出的流和进来的流用什么名称。
一旦这两个元素的数组是空的,它不会允许任何其他客户端连接。
当一个客户端离开,它把元素放回数组中,然后现在不同的客户端可以加入聊天室了。
如果双方当事人离开,两个更多的客户可以使用它。
除其他事项外,此脚本保证一个私人的线上影音聊天室。
(当然,除非你自已对谈自己)。
5.5.3.TheClient-SideStrategy客户端策略
一旦你完成了服务端脚本,现在你可以来设置客户端脚本了。
你可以对前面制作的两个模块的应用程序进行简单的修改,把它转换为一个模块的聊天室
为了保证流声音和视频正确地输出,您只需要从服务器端脚本得到一个唯一的字符串。
该服务器端脚本返回两个字符串中的一个,用来命名流的名称-left和right。
AS3.0的Responder类用来捕捉服务器端的信息,这样您可以使用它在客户端脚本中。
5.5.3.1.Responder类
Responder类有处理返回的数据工作的参数,同样也可以处理错误,这个应用程序焦点只在第一个参数上,所以这个例子没有使用处理错误(后面的例子中会使用到)。
图5-5显示了呼叫服务端和回应者角色正在捕捉返回的数据:
Figure5-5.Responderinstanceandcalltoserver
在图5-5中,Responder实例指定了一个回调函数用来捕捉呼叫服务端所返回的。
NetConnection.call()[nc.call("
streamSelect"
responder);
]方法包含了服务端的函数名称,前面的呼叫指向到了下面这行(这行在服务端脚本中):
5.5.3.2.Responder回调函数
一旦发出呼叫和指定回应函数,回调