录制和播放流媒体2.1.StreamingandBroadcasting(流和广播)FMS3可以录制和播放流媒体。流的性质和广播不一样。在广播中,发送者发送出一个单个信号。谁连接到该频道,发送信号都得到相同的流。这就像丢一个球到水中,在同一个圆心的波浪发出了一个“信号”。无论身在何处的观众或听众,当波到达他们时,他们得到相同的波浪,像一个电视画面或无线电传输,为其他所有人。当FMS3发送一个音频和视频的流的时候,它为每个接受者建立一个单独的流。其“广播”工作,更像一货车车轮上的辐条,每个人都连接获得他或她自己的流。因此,这里的“广播”的真正意义是streamcasting一种形式-每个人都得到一个单独的流的技术。如果一个人正在收听,我的应用程序只发送一个流,如果20个人在收听,它会产生20个流。因为服务器会自动为每个连接的用户建立一个单独的流。你不需要在你的代码里建立所有的流。不过,在决定如何设立您的应用程序时,对带宽的考虑,您需要考虑它可能会产生的流数量。如果你很少在线观看视频,您大概没有看到它的不同。如果你点击一个视频,要等很久,真正让你等待的是视频文件先下载,然后您的计算机上,播放保存到硬盘驱动器上的视频。这样的方式,你要等到文件完全下载之后,您才可以观赏。同样也增加了你的硬盘使用空间。第二种视频处理的类型叫:progressivedownload(渐进式下载),它就像一种混合下载和流的视频,同样视频文件会被下载,但是它不用等到全部下载完就可以播放了。无论如何,文件最后还是会下载到用户的硬盘中,这种处理也不是真正的流。第三种视频处理类型,如果在你的服务器上有FMS3,可以让视频流从你的服务器。这章向您展示了怎么样使用FMS3建立和播放流文件FlashVideo(FLV)。2.2.最简单的项目开始建立你的工程的时候,用AS3.0建立一个FLV文件最少需要以下的包和类(客户端):Packagesfl.controls.Button;fl.controls.TextInput;flash.display.Sprite;flash.net.NetConnection;flash.net.NetStream;flash.events.NetStatusEvent;flash.events.MouseEvent;flash.events.Event;flash.net.ObjectEncoding;flash.media.Camera;flash.media.Microphone;flash.media.Video;KeyClassesNetConnectionNetStreamCameraMicrophoneVideoButton以上列出的包和类都是使用FMS3录制和播放FLV文件所需要的,在这些包中,最重要的是导入ObjectEncoding包。FMS2(如果你使用它替换FMS3)要求NetConnection的属性defaultObjectEncoding的AMF默认值改为0,如下:NetConnection.defaultObjectEncoding=flash.net.ObjectEncoding.AMF0;对于FMS2的用户,如果你在客户端使用AS3.0,你将会在本书中看到这个属性,只好不要注释defaultObjectEncoding这行。一个更重要的琐事之事,在你取得实际编码之前。你需要一个叫vid2的服务端目录,这将会是你的FMS应用程序的目录,虽然它不需要一个服务器端(ASC)文件,但是运行你的应用程序是所必须的,当你第一次运行你的应用程序,你会发现在vid2目录下有一些其它的目录。2.2.1.摄像头和麦克风录制视频,你将需要一个摄像头和麦克风连接到了你的电脑上。一些网络摄像头有内置麦克风,许多电脑也有内置麦克风,尤其是笔记本和大多数的Macintosh电脑。在本章中的例子包含一些的摄像头设置,这些会在第3章中解释说明。下面一行代码设置摄像头的捕捉宽和高为240X180,帧率为24:cam.setMode(240,180,24);设置质量为90:cam.setQuality(0,90);对于本章中最简单的应用程序,这些你都需要知道。但是对于精调你的应用程序时,你需要花更多时间在这些设置和优化你的应用程序的效率上。2.2.2.用最少的代码来录制FLV文件对于AS3.0,你可以用最少的配置来建立你的完整的应用程序。对此,本书中的其它例子了,你将看到如何使用AS3.0,可以简单地来建立任何你所需要的事情。一开始,你需要建立一个MinRecord.fla文件,添加一个Button和TextInput组件到库中,这样你就可以用这些组件的类名来添加它们到舞台上。下面的代码片断展示了怎么样建立:varrecordBtn:Button=newButton();另外你还需要导入正确的类:fl.controls.Button。最后使用addChild()方法把组件添加到舞台上。使用实例的x和y属性,你可以把它们放置在舞台的任何地方。为了显示你的视频,你需要一个Video实例。Video实例是用来显示你的Camera对像(摄像头可以见到的东西)。同样,你需要一个Microphone实例来处理你的声音数据,好让它可以被录制。为了连接和串流声音及视频,你需要一个NetConnection实例和一个NetStream实例。把它们串在一起,你将需要做以下事件:为捕捉视频和声音建立camera和microphone对像放置一个video实例在舞台用RTMP地址连接到服务器(NetConnection.connect(”rtmp://url/app/inst”)),建立一个流,传输视频和声音到媒体服务器(它们将被录制成一个FLV文件)下面的伪代码说明了,用来传输声音和视频到媒体服务器的相关顺序:1.建立camera,microphone,andvideo实例varcam:Camera=Camera.getCamera();varmic:Microphone=Microphone.getMicrophone();varvid:Video=newVideo(w,h);2.设置网络连接和流varnc:NetConnection=newNetConnection();nc.connect(”rtmp://”);varns:NetStream=newNetStream(nc);3.添加摄像头到视频中和摄像头和麦克风添加到网络流中vid.attachCamera(cam);//Thisissothatyoucanseevideons.attachAudio(mic);//Giveaudioarideonthestreamns.attachCamera(cam);//Givevideoarideonthestream4.发布网络流ns.publish(”FLVname”,”record”);注意:当你实例化一个camera和microphone对像时,使用的是get方法,而不是new。实例化一个camera对像的正确语法如下:varmyCam:Camera=Camera.getCamera();实例化microphone:varmyMic:Microphone=Microphone.getMicrophone();FLV文件最后保存在你的应用程序目录中的streams目录中。在本例中,FMS服务器的目录排列看起来像这样:applications-vid2-streams-recordings-flvfiles在下面,将把它们集合在一起。大部分实例都声明为私有变量。一个重要的方法:checkConect,使用NetStatusEvent来检测连接是否连接成功。事件侦听器被添加到NetConnection实例nc上:nc.addEventListener(NetStatusEvent.NET_STATUS,checkConnect);如果连接成功,然后实例NetStream。这是重要的:在整个本书中保持这种做法,使您的应用程序,不会在没有连接到FMS时就尝试创建一个网络流。准备好后,然后执行下面步骤:打开一个新的Flash文件,保存为MinRecord.fla打开窗口-属性。在文档类中输入MinRecord,保存文件建立一个新的ActionScript文件,保存为MinRecord.as与MinRecord.fla同一目录在MinRecord.as文件中,添加Example2-1中的代码,保存Example2-1.MinRecord.asCodeView:package{importfl.controls.Button;importfl.controls.TextInput;importflash.display.Sprite;importflash.net.NetConnection;importflash.net.NetStream;importflash.events.NetStatusEvent;importflash.events.MouseEvent;importflash.events.Event;//importflash.net.ObjectEncoding;importflash.media.Camera;importflash.media.Microphone;importflash.media.Video;publicclassMinRecordextendsSprite{privatevarnc:NetConnection;privatevarns:NetStream;privatevarrtmpNow:String;privatevarmsg:Boolean;privatevarcam:Camera;privatevarmic:Microphone;privatevarvid1:Video;privatevarrecordBtn:Button;privatevarstopBtn:Button;privatevartextInput:TextInput;//ConstructorfunctionMinRecord(){//NetConnection.defaultObjectEncoding=flash.net.ObjectEncoding.AMF0;nc=newNetConnection();nc.addEventListener(NetStatusEvent.NET_STATUS,checkConnect);rtmpNow=”rtmp://192.168.0.11/vid2/recordings”;//rtmpNow=”rtmp:/vid2″;nc.connect(rtmpNow);addMedia();addUI();recordBtn.addEventListener(MouseEvent.CLICK,startRecord);stopBtn.addEventListener(MouseEvent.CLICK,stopRecord);}privatefunctionaddMedia():void{cam=Camera.getCamera();cam.setMode(240,180,24);cam.setQuality(0,90);mic=Microphone.getMicrophone();vid1=newVideo(cam.width,cam.height);vid1.attachCamera(cam);addChild(vid1);vid1.x=100;vid1.y=50;}privatefunctionaddUI():void{recordBtn=newButton();recordBtn.label=”Record”;recordBtn.x=100;recordBtn.y=50+(cam.height)+5;r