2006/03/06 | [文献]使用Director MX和Flash Communication Server MX制作视音频通讯
类别(开发文献) | 评论(0) | 阅读(546) | 发表于 09:58
使用Director MX和Flash Communication Server MX制作视音频通讯
翻译:十年磨一剑
 
 
使用Director MX,你可以在你的Director影片中使用Flash MX的高级特性。包括使用Flash Communication Server MX来发送与接收视频流。一些Flash MX的特性可以在Director中只用Lingo程序就可以调用了,而另一些特性则必须要有一个Flash角色才可以调用。
 
使用Flash Communication Server MX来发送与接收视频流需要一个舞台上有名为视频剪辑实例的Flash演员。本文详细描述了名为"Lingo_Videochat.dir"的Director例子,它包括了所使用的Flash演员和控制该演员的Lingo程序。
 
浏览Lingo_Videochat.dir影片
 
例子影片被设计为展示如何建立NetConnection object以能够与Flash Communication Server MX进行通讯,建立Camera and Microphone objects以能够访问本地计算机上的摄像头和话筒硬件,建立NetStream objects以能够发送与接收视频流。所有这些被影片Lingo程序建立的objects都是ActionScript objects。一旦它们被创建,就可以用它们原有的ActionScript方法来操作它们。
 
例子影片包括两个场景。第一个场景允许使用者输入他自己的名字和他想进行视频通讯的人的名字。这个场景发生在第2帧上。第二个场景了用于显示从另一通讯者处传过来的视频流的Flash精灵。这个场景发生在第4帧上。
 
在第一个场景,使用者输入他自己的名字和他交谈的朋友的名字。在这一场景中的"Connect"按钮被加上了名为"connect button behavior"的行为。这个行为在下面的部分会详细讨论。
 
在第二个场景,从另一通讯者处传过来的视频流会被显示在Flash精灵上。这个Flash精灵的Flash演员是十分简单的,它仅是舞台上有一个名为视频剪辑的实例的Flash影片。该Flash影片的SWFFLA版都包含在本文的下载包中了。打开"simplevideo.fla"文件,你可以看到只有一个简单的名叫"VideoClip"的视频剪辑实例。这个Flash精灵被附上了名为"Flash sprite behavior"的行为。这个行为执行创建NetConnection, Microphone, Camera, and NetStream objects的主要工作。这些都是你可以用Lingo来创建和控制的Flash ActionScript objects。第二个场景也包括了一个用于结束与Flash Communication Server MX连接的"Disconnect"按钮。
 
"Connect"按钮的行为
 
"Connect"按钮上附上的行为包含以下Lingo:
 
global gNames
 
property pSprite
 
on beginSprite (me)
 
-- initialize a sprite reference
pSprite = sprite(me.spriteNum)
 
-- initialize the sprite's cursor
pSprite.cursor = 280
 
end beginSprite
 
on mouseDown (me)
 
-- pull each name entry
tPublishName = me.stripSpaces( member("publish name").text )
tSubscribeName = me.stripSpaces( member("subscribe name").text )
 
-- verify that names have been entered
if ((tPublishName <> "") AND (tSubscribeName <> "")) then
 
-- store both names in a global variable
gNames = [:]
gNames.addProp(#publishName,tPublishName)
gNames.addProp(#subscribeName,tSubscribeName)
 
-- jump to the next marker
go next
 
end if
 
end mouseDown
 
on stripSpaces (me, aString)
 
-- clear all spaces from the string
repeat while offset(SPACE,aString)
tCharIndex = offset(SPACE,aString)
delete aString.char[tCharIndex]
end repeat
 
-- return the string
return aString
 
end stripSpaces
这个行为包含一个变量声明、一个属性声明和三个处理程序:on beginSpriteon MouseDown on stripSpaces。
全局变量gNames被用于储存一个包含两方使用者名字的属性列表。属性变量pSprite被用于储存"Connect"按钮精灵的引用。
 
on beginSprite处理程序包含以下Lingo:
on beginSprite (me)
 
-- initialize a sprite reference
pSprite = sprite(me.spriteNum)
 
-- initialize the sprite's cursor
pSprite.cursor = 280
 
end beginSprite
它开始于以对该行为附加于其上的精灵的引用来初始化属性变量pSprite。然后该处理程序设定精灵的cursor属性的值为280,这会使鼠标指针在该精灵上时会变为手指状。
 
on mouseDown处理程序使用on stripSpaces处理程序来删除输入的名字前的空格,然后使用以下Lingo来把名字存入变量gNames中:
on mouseDown (me)
 
-- pull each name entry
tPublishName = me.stripSpaces( member("publish name").text )
tSubscribeName = me.stripSpaces( member("subscribe name").text )
 
-- verify that names have been entered
if ((tPublishName <> "") AND (tSubscribeName <> "")) then
 
-- store both names in a global variable
gNames = [:]
gNames.addProp(#publishName,tPublishName)
gNames.addProp(#subscribeName,tSubscribeName)
 
-- jump to the next marker
go next
 
end if
 
end mouseDown
 
当使用者名字的列表被加入了变量gNames后,go next命令就会让播放头移动下一个标记(marker)处播放。这下一个标记是第4帧,就是第二个场景所在处。
 
Flash精灵的行为
 
影片的第二个场景包含了显示传入视频流的Flash精灵。该精灵上附上了名叫"Flash sprite behavior"的行为。这个行为包括了创建和控制传入和传出的视频流所需的所有ActionScript objects
 
通常来说,这个行为执行以下任务,将在这部分详细讨论它们:
* 声明变量与属性
* 创建新的NetConnection object
* 为当与服务器的连接建立时调用 on initiateStreams处理程序的NetConnection object的 onStatus 事件建立一个 callback 处理程序
* 使用NetConnection object的connect方法连接Flash Communication Server
* 创建新的ActionScript Camera and Microphone objects并对它们进行引用
* 创建新的名叫pOutStream的ActionScript NetStream object来传出视频流
* 把Camera and Microphone objects附上新的NetStream object
* 使用的NetStream object发布方法发布传出视频流给Flash Communication Server
* 创建新的名叫pInStream的NetStream object来接收传入视频流
* 用NetStream object的播放方法来鉴定传入视频流
* 用getVariable命令来创建一个对Flash精灵的movie clip的引用
* 用attachVideo方法把传入的NetStream object附于上Flash精灵的movie clip
* 当精灵完的时候关闭NetStream and NetConnection objects
 
更详尽地看这个行为脚本会揭示这个脚本为了成功地连上服务器、发送和接收视频流必须要做什么的细节。以下是这个脚本:
global gNames
 
property pCamera
property pInStream
property pMicrophone
property pNetConn
property pOutStream
property pSprite
 
on exitFrame (me)
 
-- initiate the connection if necessary
if voidP(pNetConn) then
me.initiateConnection()
end if
 
end exitFrame
 
on initiateConnection (me)
 
-- initialize a sprite reference
pSprite = sprite(me.spriteNum)
 
-- create a new NetConnection object
pNetConn = pSprite.newObject("NetConnection")
 
-- declare an onStatus callback handler
pSprite.setCallback(pNetConn,"onStatus",#myOnStatus,me)
 
-- set the connecting URL
tURL = "rtmp://diggler.macromedia.com/thiggins_simplechat"
 
-- connect the object to the server
pNetConn.connect(tURL)
 
end initiateConnection
 
on initiateStreams (me)
 
-- gain references to the camera and microphone
tCamObj = pSprite.newObject("Camera")
pCamera = tCamObj.get()
tMicObj = pSprite.newObject("Microphone")
pMicrophone = tMicObj.get()
 
-- create a NetStream object
pOutStream = pSprite.newObject("NetStream",pNetConn)
 
-- attach the camera and microphone to the outgoing stream
pOutStream.attachAudio(pMicrophone)
pOutStream.attachVideo(pCamera)
 
-- publish the outgoing stream
pOutStream.publish(gNames.publishName,"live")
 
-- create another NetStream object
pInStream = pSprite.newObject("NetStream",pNetConn)
 
-- play the friend's stream
pInStream.play(gNames.subscribeName)
 
-- get a reference to the video clip instance on stage
pVideoClip = pSprite.getVariable("VideoClip",FALSE)
 
-- attach the incoming stream to the video clip
pVideoClip.attachVideo(pInStream)
 
end initiateStreams
 
on endSprite
 
 
-- close the streams if necessary
if not( voidP(pOutStream) ) then
pOutStream.close()
end if
if not( voidP(pInStream) ) then
pInStream.close()
end if
 
-- close the NetConnection if necessary
if not( voidP(pNetConn) ) then
pNetConn.close()
end if
 
end endSprite
 
on myOnStatus me, aArg1, aArg2
 
if (aArg2.code = "NetConnection.Connect.Success") then
 
-- initiate streams
me.initiateStreams()
 
end if
 
end myOnStatus
 
这个行为的第一部分声明了一些要用到的变量与属性:
* 全局变量gNames包含参加聊天的使用者们的名字的属性列表。
* 属性变量pCamera将包含从使用者的计算机上提供传出视频的Camera object
* 属性变量pInStream将包含传入的NetStream object
* 属性变量pMicrophone将包含从使用者的计算机上提供传出音频的Microphone object
* 属性变量pNetConn将包含主宰传入和传出NetStream object的NetConnection object
* 属性变量pOutStream将包含传出NetStream object
* 属性变量pSprite将包含一个对这个行为附加于其上的精灵的引用。
 
第一个处理程序是一个on exitFrame处理程序,包括以下Lingo:
 
on exitFrame (me)
 
-- initiate the connection if necessary
if voidP(pNetConn) then
me.initiateConnection()
end if
 
end exitFrame
 
每次播放头离开包含Flash精灵的这帧时,这个处理程序就会使用voidP()功能来检查pNetConn这个NetConnection object是否存在。如果pNetConn object不存在,这个处理程序就调用on initiateConnection处理程序来建立它。一旦这个NetConnection object已经被建立,这个处理程序就会什么也不做。
 
initiateConnection处理程序
 
下一个处理程序是on initiateConnection处理程序。它开始于建立一个对这个行为附加于其上的精灵的引用:
 
pSprite = sprite(me.spriteNum)
 
然后,这个处理程序使用newObject()命令和Flash精灵的引用来建立一个新的ActionScript NetConnection object
 
pNetConn = pSprite.newObject("NetConnection")
 
这个NetConnection object被存储进了属性变量pNetConn中了。
 
一旦NetConnection object被建立,一个callback会因它的onStatus事件而被确定。当NetConnection object从服务器处接收到一个信息这个onStatus事件就会发生。在这儿,服务器返回的仅是连接确认信息。
 
这个callback处理程序被用setCallback()方法来确定:
 
pSprite.setCallback(pNetConn,"onStatus",#myOnStatus,me)
 
这个setCallback()方法包括NetConnection object、活动事件名字、callback处理程序名字和包含callback处理程序为参数的script object的名字。在这儿由于script object就是当前的程序,所以关键字me被使用。callback处理程序检查与服务器的连接正确然后调用处理程序on initiateStreams。
 
当callback处理程序被确定之后,就用以下语句来初始化与服务器的连接。
 
-- set the connecting URL
tURL = "rtmp://diggler.macromedia.com/thiggins_simplechat"
 
-- connect the object to the server
pNetConn.connect(tURL)
 
开始的两句把Flash Communication Server的网址存入本地变量tURL中。如果你想自己使用这个样本影片,可以以你自己的Flash Communication Server的网址来代替。Dirctor MX的光盘里有Flash Communication Server MX的安装程序。
下一句是用NetConnection object的connect()方法来连接服务器,以参数的形式来传送网址。
 
当connect()方法初始化与服务器的连接时,服务器会回复一个表明试图连接的成或败的onStatus信息。这个onStatus信息引发了先前确定的callback处理程序。
 
The myOnStatus callback handler
 
这个callback处理程序名为on myOnStatus,是在on initiateConnection处理程序中的setCallback()语句确定的。这个处理程序包括以下Lingo:
 
on myOnStatus me, aArg1, aArg2
 
if (aArg2.code = "NetConnection.Connect.Success") then
 
-- initiate streams
me.initiateStreams()
 
end if
 
end myOnStatus
 
当服务器回复一个尝试连接时,它会传送两个argument给callback处理程序。第二个argument包含有一个属性列表。在本例中,myOnStatus处理程序仅是简单地检查第二个argument中的属性code中的状态信息。如果code字符串表明连接是成功的,这个处理程序就会调用on initiateStreams处理程序。
 
这个onStatus的callback也可以用来作更复杂的错误和状态检测。要找到更多的关于如何在你的播放器上使用onStatus callback处理程序的信息,请查看Flash Communication Server的文档。
 
The initiateStreams handler
 
这个on initiateStreams处理程序开始于建立Flash Camera和Microphone object,然后使用成功建立的NetConnection object来建两个NetStream object。这些NetStream object是用来发送与接收视频流的。
 
处理程序的第一部分用以下Lingo建立Camera和Microphone object
 
-- gain references to the camera and microphone
tCamObj = pSprite.newObject("Camera")
pCamera = tCamObj.get()
tMicObj = pSprite.newObject("Microphone")
pMicrophone = tMicObj.get()
 
第一行用newObject()命令来建立新的ActionScript Camera object,然后把它存入本地变量tCamObj中。第二行用Camera object的get()命令来返回一个对已安装好的视频摄像头的引用,并把这个引用存在属性变量pCamera中。再对下两行是对一个新的Microphone object进行同样的处理。
 
下一行使用newObject()命令来建立新的用来发送传出视频流到服务器的ActionScript NetStream object
 
-- create a NetStream object
pOutStream = pSprite.newObject("NetStream",pNetConn)
 
newObject()命令的第一个参数是建立的object的类型。第二个参数是指定NetStream object用来与服务器通讯的NetConnection object。属性变量pOutStream成了这个新的NetStream object的一个引用。
 
一旦传出NetStream object被建立,就可以使用NetStream object的attachAudio()和attachVideo()方法把Camera和Microphone object附加于其上。对下两行可完成这个任务:
 
-- attach the camera and microphone to the outgoing stream
pOutStream.attachAudio(pMicrophone)
pOutStream.attachVideo(pCamera)
 
使用attachAudio()和attachVideo()方法来把以前建立的对Camera和Microphone的引用作为参数来传送。
 
当Camera和Microphone已经被附于传出NetStream object上时,它就可以随时进行发布了。处理程序的下一行就使用了NetStream object的publish()方法来发布这个视频流:
 
-- publish the outgoing stream
pOutStream.publish(gNames.publishName,"live")
 
publish()方法的第一个参数是发送视频流的使用者的名字,这个名字是保存在gNames属性列表变量的publishName属性变量中的。第二个参数是表明发布这个视频流的方式。在这里这个视频流以live方式发布。
 
下一个步骤是建立另一个NetStream object来接收传入视频流。处理程序的下一行建立一个NetStream object并把对它的引用分配给属性变量pInStream:
 
-- create another NetStream object
pInStream = pSprite.newObject("NetStream",pNetConn)
 
当新的NetStream object被建立了之后,这个object的play()方法可以把传入视频流与这个object相关且使它开始播放。处理程序的下一行使用以下Lingo:
 
-- play the friend's stream
pInStream.play(gNames.subscribeName)
 
play()方法的参数指定了传入视频流的发送者的名字。
 
最后,处理程序最末的两行建立一个对Flash精灵里的video clip object的引用且把传入视频流附于video clip上:
 
-- get a reference to the video clip instance on stage
pVideoClip = pSprite.getVariable("VideoClip",FALSE)
 
-- attach the incoming stream to the video clip
pVideoClip.attachVideo(pInStream)
 
getVariable()命令建立一个对Flash精灵里的video clip object的引用且把它存入属性变量pVideoClip中。它的第一个参数是Flash影片中的video clip的名字。第二个参数用"FALSE",是让getVariable()命令返回一个对video clip object的引用,而不是简单地返回代表它的字符串。
 
video clip object的attachVideo()方法使传入视频流对象附于video clip上。这允许传入视频流被显示于Flash精灵里的video clip object中。
 
一旦on initiateStreams处理程序完成之后,传入视频流就会在舞台上的Flash精灵中显示出来。
 
The endSprite handler
 
Flash精灵的行为中的on endSprite处理程序执行关闭两个NetStream object和NetConnection object的任务。每个object的close()方法是用来关闭它自身的。
 
on endSprite处理程序包含以下Lingo:
 
on endSprite
 
-- close the streams if necessary
if not( voidP(pOutStream) ) then
pOutStream.close()
end if
if not( voidP(pInStream) ) then
pInStream.close()
end if
 
-- close the NetConnection if necessary
if not( voidP(pNetConn) ) then
pNetConn.close()
end if
 
end endSprite
 
这个处理程序在使用close()方法来关闭object前使用voidP()命令来检查每一个object的存活。处理程序关闭NetConnection object之前先关闭两个NetStream object,是因为它们依赖于NetConnection object的关闭程序。
 
当使用者在视频场景点击Disconnect按钮时就会调用on endSprite处理程序。
 
以上所有这些处理程序说明了连接Flash Communication Server并发送与接收视频流的所有步骤。在你的播放器中应用这些步骤,你就可以在你的Director播放器中使用live视频了。 
 
0

评论Comments