1.工作原理
NetStream.publish方法的應用
publish () 方法:将音頻流、視訊流和文本消息流從用戶端發送到 Flash Media Server,并可選擇在傳輸期間錄制該流。 此方法僅供指定的流的釋出者使用。
第1個參數:辨別該流的字元串。
第2個參數:指定如何釋出該流的字元串。 有效值為“record”、“append”和“live”。 預設值為“live”。 (這3個參數差別如下:)
如果傳遞“record”,Flash Player 将釋出并錄制實時資料,同時将錄制的資料儲存到名稱與傳遞給 name 參數的值相比對的新檔案中。 該檔案儲存在伺服器上伺服器應用程式所在目錄的子目錄中。 如果該檔案存在,則覆寫該檔案。
如果傳遞“append”,Flash Player 将釋出并錄制實時資料,同時将錄制的資料附加到名稱與傳遞給 name 參數的值相比對的檔案中,該檔案存儲在伺服器上包含伺服器應用程式的目錄的子目錄中。如果未找到與 name 參數相比對的檔案,則建立一個檔案。
如果省略此參數或傳遞“live”,則 Flash Player 将釋出實時資料而不進行錄制。 如果存在名稱與傳遞給 name 參數的值相比對的檔案,則删除它。
關于NetStream.publish方法還可以看我上篇文章
<a href="http://www.cnblogs.com/aierong/archive/2009/01/10/flex_fms_video_start.html" target="_blank">http://www.cnblogs.com/aierong/archive/2009/01/10/flex_fms_video_start.html</a>
要實作視訊會議就是使用的“live”這一類型
來看一下原理圖,參加會議的使用者将自己本地攝像頭捕捉到的畫面publish到fms,存放在fms端userList這個集合對象中,集合中存放的是每個使用者名也就是他們釋出視訊的名字。每當用新使用者加入或者退出會議的時候,fms就把這個userList廣播給每個還線上的使用者。使用者取得userList隻需播放其他幾個使用者的視訊即可。怎麼樣原理很簡單吧!
2.準備工作
在fms安裝目錄下的application中,建立一個檔案夾test_video2,然後啟動fms伺服器
3.開始代碼
這次代碼分2部分:伺服器端的asc檔案和用戶端
asc檔案中有2個重要的類:
Application類:Application類包含有關一個Flash Media Server應用程式執行個體的資訊,它會一直維持這些資訊直到這個應用程式執行個體被解除安裝。
Client類:Client類讓你處理連接配接到一個Flash Media Server應用程式執行個體的每一個使用者或說client。
Application類有幾個重要事件如下:
Application.onAppStart 當這個應用程式被伺服器裝載時調用。
Application.onAppStop 當這個應用程式被伺服器解除安裝時調用。
Application.onConnect 當一個客戶機連接配接到這個應用程式時調用。
Application.onDisconnect 當一個客戶機從這個應用程式斷開連接配接時調用。
Application類有幾個重要方法如下:
Application.acceptConnection() 接受一個來自客戶機的至一個應用程式的連接配接。
Application.broadcastMsg() 向所有連接配接的客戶機廣播一條消息。
Application.disconnect() 從伺服器斷開一個客戶機的連接配接。
Application.rejectConnection() 拒絕至一個應用程式的連接配接。
Client類有1重要方法如下:
Client.call() 在Flash客戶機上異步的執行一個方法,并把值從Flash客戶機傳回到伺服器。
4.先編寫asc檔案,打開寫字闆,鍵入下面代碼,并儲存為test_video2.asc,然後copy此檔案到test_video2檔案夾(asc檔案要求和檔案夾同名或者叫main.asc)
userList=[];
application.onAppStart=function()
{
trace("fms伺服器啟動......");
}
application.onConnect = function(currentClient)
application.acceptConnection(currentClient);
if (userList.length>=3)
{
currentClient.call("showServerMsg",null,"已經達到最大使用者數");
application.rejectConnection(currentClient);
}
else
{
currentClient.communicateServer= function(value)
{
currentClient.username=value;
trace(currentClient.username+"加入聊天室");
userList.push(value);
trace("目前使用者清單"+userList);
application.broadcastMsg("playOtherVideo",userList);
}
application.onDisconnect=function(currentClient)
trace("使用者"+currentClient.username+"離開聊天室");
for(j=0;j<userList.length;j++)
if ( userList[j]==currentClient.username )
userList.splice(j,1);
trace("目前使用者清單"+userList);
application.broadcastMsg("playOtherVideo",userList);
代碼說明:
(1)application.broadcastMsg ("用戶端方法名",參數..);是asc中一個比較重要的方法,他的作用是向所有連接配接着的用戶端進行廣播,調用用戶端的函數。這個方法相當于循環周遊Application.clients數組并在每一個獨立的客戶機上調用Client.call(),但這個方法的效率更高(尤其是當連接配接的客戶機數量很大時)。唯一的不同是當你調用broadcastMsg()時你不能指定一個響應對象,除此以外,兩種文法是一樣的。
(2)userList.splice(a,b)這個函數,它的作用是從a位置開始移除數組中的b個元素(asc用的是as1文法)
(3)代碼中做了限制,隻允許最多3人連接配接fms
5.打開Fb3,建立一個項目
6.在主mxml中拖動控件,界面如下:
具體代碼如下:
<mx:Label x="10" y="10" text="你的畫面"/>
<mx:VideoDisplay x="10" y="38" width="120" height="90" id="vd_myVideo"/>
<mx:TextInput x="152" y="38" text="輸入你的名字" id="txt_username" width="116" focusIn="txt_username.text=''"/>
<mx:Button x="288" y="38" label="進入聊天室" id="btn_start"/>
<mx:VBox x="10" y="161" width="120" id="vb_otherVideo">
</mx:VBox>
7.導入包和定義變量如下:
import mx.controls.Label;
import mx.controls.Alert;
private var netConnection:NetConnection;
private var outNetStream:NetStream;
private var camera:Camera;
private var microphone:Microphone;
private var responder:Responder;
private var appServer:String="rtmp://192.168.0.249/test_video2";
private var username:String="";
outNetStream就是你要釋出給fms的視訊流,通俗的說就是你的畫面
responder 如果client端調用server端as1代碼中的某個方法需要有回調函數的話就要定義這個responder,後面會有具體說明
username 每個使用者的使用者名,也就是釋出時候給視訊取得名字
8.creationComplete="init()",頁面初始化代碼
private function init():void
netConnection = new NetConnection();
netConnection.addEventListener(NetStatusEvent.NET_STATUS,netStatusHandler);
netConnection.connect(appServer);
netConnection.client=this;
initMedia();
private function initMedia():void
camera = Camera.getCamera();
camera.setMode(120,90,15);
camera.setQuality(0,90);
vd_myVideo.attachCamera(camera);
microphone=Microphone.getMicrophone();
private function netStatusHandler(evt:NetStatusEvent):void
trace(evt.info.code);
if ( evt.info.code=="NetConnection.Connect.Success" )
btn_start.addEventListener(MouseEvent.CLICK,startCommunicate);
Alert.show("fms連接配接失敗"+evt.info.code);
代碼比較簡單,不明白可以看我上篇
9.實作按鈕事件
private function startCommunicate(evt:MouseEvent):void
username=txt_username.text;
responder=new Responder(communicateStataHandler);
netConnection.call("communicateServer",responder,username);
private function communicateStataHandler(str:String):void
outMyVideo();
btn_start.enabled=false;
private function outMyVideo():void
/* 釋出視訊 */
outNetStream = new NetStream(netConnection);
outNetStream.attachCamera(camera);
outNetStream.attachAudio(microphone);
outNetStream.publish(username,"live");
Responder 類提供了一個對象,該對象在 NetConnection.call() 中使用以處理來自與特定操作成功或失敗相關的伺服器的傳回值。
netConnection.call調用asc檔案中的communicateServer,調用成功後,回調communicateStataHandler方法
10.showServerMsg方法實作
public function showServerMsg(msg:String):void
Alert.show(msg);
供asc檔案中調用
11.playOtherVideo方法實作:
public function playOtherVideo(newUserList:Array):void
vb_otherVideo.removeAllChildren();
for(var i:int=0;i<newUserList.length;i++)
if ( newUserList[i]!=username )
var vd:VideoDisplay = new VideoDisplay();
var video:Video = new Video();
video.width=120;
video.height=90;
var inNetStream:NetStream= new NetStream(netConnection);
video.attachNetStream(inNetStream);
inNetStream.play(newUserList[i]);
var label:Label= new Label();
label.text=newUserList[i]+"的畫面";
vd.addChild(video);
vd.width=120;
vd.height=90;
vb_otherVideo.addChild(label);
vb_otherVideo.addChild(vd);
asc檔案中application.broadcastMsg方法調用,向所有連接配接的客戶機廣播
12.運作程式,圖檔如下,其中有一人沒視訊攝像頭
13.代碼下載下傳
<a href="http://files.cnblogs.com/aierong/Video2.rar">http://files.cnblogs.com/aierong/Video2.rar</a>
您收到代碼後,請回到文章下面留言告之一下!要是沒收到,我可以再發!
提供代碼是為了互相學習,一起探讨!請大家多交流!
1.要是對代碼有什麼疑問,可以在文章的評論區留言,我會盡我所能答複您!
2.要是您在運作代碼的過程中發現bug,或者是您有什麼好的建議和意見,也可以在文章的評論區留言給我,我會及時更正!
評論區使用提示:
評論區留言(使用進階評論)是可以貼圖檔的,要是有難以描述的問題,可以貼圖檔和文字一起說明
謝謝!
本文轉自農夫山泉别墅部落格園部落格,原文連結:http://www.cnblogs.com/yaowen/p/4151463.html,如需轉載請自行聯系原作者