Flex與.NET互操作(十三):FluorineFx.Net實(shí)現(xiàn)視頻錄制與視頻回放
在《FMS3系列(四):在線視頻錄制、視頻回放 》這篇文章里我寫了通過FMS來實(shí)現(xiàn)在線視頻錄制和視頻回放的功能,客戶端的開發(fā)和這篇文章是相同的,不同的是本文將使用Flex來開發(fā)。
首先我們來看看使用FluorineFx服務(wù)端是如何開發(fā)的,建立ApplicationAdapter是必然的,這里我們?yōu)楸疚闹械氖纠绦蚪⒌腁pplicationAdapter為VideoApplication,并為其添加RemotingServiceAttribute 如下代碼塊:
{
/// <summary>
/// 視頻應(yīng)用
/// </summary>
[RemotingService]
public class VideoApplication : ApplicationAdapter
{
public override bool AppStart(IScope application)
{
return base.AppStart(application);
}
public override bool AppConnect(IConnection connection, object[] parameters)
{
return base.AppConnect(connection, parameters);
}
}
}
ApplicationAdapter模板所提供的方法在實(shí)際項(xiàng)目開發(fā)中根據(jù)自己的需求去重寫,這里不作過多介紹。光是這樣還是不能實(shí)現(xiàn)視頻的錄制和回放的功能,這只是實(shí)現(xiàn)了基本的啟動應(yīng)用程序和客戶端連接等基本功能,要想實(shí)現(xiàn)視頻錄制和回放,我們還得讓 VideoApplication實(shí)現(xiàn)IStreamService接口,該接口提供了實(shí)現(xiàn)視頻發(fā)布和播放的相應(yīng)功能,其定義如下:
{
[CLSCompliant(false)]
public interface IStreamService : IScopeService, IService
{
void closeStream();
int createStream();
void deleteStream(int streamId);
void deleteStream(IStreamCapableConnection connection, int streamId);
void pause(bool pausePlayback, double position);
void play(bool dontStop);
void play(string name);
void play(string name, double start);
void play(string name, double start, double length);
void play(string name, double start, double length, bool flushPlaylist);
void publish(bool dontStop);
void publish(string name);
void publish(string name, string mode);
void receiveAudio(bool receive);
void receiveVideo(bool receive);
void releaseStream(string streamName);
void seek(double position);
}
}
OK,有了應(yīng)用處理器接下來在FluorineFx網(wǎng)站的apps中添加應(yīng)用程序(VideoApp),并配置好由此處理器來處理視頻錄制和回放。
<configuration>
<application-handler type="Fx.Adapter.VideoApplication"/>
</configuration>
要使用RTMP協(xié)議,那么配置RTMP通信信道肯定是不能少的,在配置文件WEB-INF/flex/service-config.xml中配置使用RTMP協(xié)議的通信信道。
<services-config>
<channels>
<channel-definition id="my-rtmp" class="mx.messaging.channels.RTMPChannel">
<endpoint uri="rtmp://{server.name}:1617" class="flex.messaging.endpoints.RTMPEndpoint"/>
</channel-definition>
</channels>
</services-config>
于此FluorineFx服務(wù)器端“基本”算是完成了。下面轉(zhuǎn)到客戶端的開發(fā),建立Flex項(xiàng)目并設(shè)計(jì)好界面,如下圖:
建立與FluorineFx服務(wù)器上應(yīng)用程序的連接,連接成功則將自己的視頻數(shù)據(jù)顯示到界面上,如下實(shí)現(xiàn)代碼:
{
nc = new NetConnection();
nc.connect("rtmp://localhost:1617/VideoRecord","beniao","123456");
nc.addEventListener(NetStatusEvent.NET_STATUS,onNetStautsHandler);
nc.client = this;
}
private function onNetStautsHandler(event:NetStatusEvent):void
{
if(event.info.code == "NetConnection.Connect.Success")
{
cam = Camera.getCamera();
if(cam != null)
{
this.myVideo.attachCamera(cam);
}
else
{
Alert.yesLabel = "確定";
Alert.show("沒有檢測到視頻攝像頭","系統(tǒng)提示");
}
}
}
錄制視頻也就是將自己本機(jī)的視頻攝像頭獲取的視頻數(shù)據(jù)以及音頻設(shè)備的數(shù)據(jù)附加到網(wǎng)絡(luò)流(NetStream),使用網(wǎng)絡(luò)流的publish()方法將流發(fā)布到服務(wù)器上,這和使用FMS是相同的。
{
if(this.nc)
{
var mic:Microphone = Microphone.getMicrophone();
ns = new NetStream(this.nc);
ns.attachCamera(cam);
ns.attachAudio(mic);
ns.client = this;
ns.publish(this.videoName.text,"record");
this.btnStart.enabled = false;
this.btnEnd.enabled = true;
}
}
private function onStopRecord(event:MouseEvent):void
{
if(this.nc)
{
this.nc.close();
this.btnStart.enabled = true;
this.btnEnd.enabled = false;
this.btnPlay.enabled = true;
}
}
停止視頻錄制的功能就更加簡單了,直接斷開當(dāng)前客戶端與服務(wù)器端的連接就可以,使用網(wǎng)絡(luò)連接(NetConnection)的close()方法。
錄制好的視頻將會保存在網(wǎng)站下的apps/VideoApp/stream目錄中,如下圖:
實(shí)現(xiàn)錄制的視頻回放實(shí)際上就是播放服務(wù)器上的一個.flv視頻文件,同樣需要先建立與服務(wù)器端的網(wǎng)絡(luò)連接,通過網(wǎng)絡(luò)流去加載指定的視頻文件,最后將其顯示到應(yīng)用界面上。
{
nc = new NetConnection();
nc.connect("rtmp://localhost:1617/VideoRecord","beniao","123456");
nc.addEventListener(NetStatusEvent.NET_STATUS,onPlayNetStautsHandler);
nc.client = this;
}
private function onPlayNetStautsHandler(event:NetStatusEvent):void
{
if(event.info.code == "NetConnection.Connect.Success")
{
ns = new NetStream(this.nc);
ns.client = this;
var video:Video = new Video();
video.width = 320;
video.height = 240;
video.attachNetStream(this.ns);
this.myVideo.addChild(video);
this.ns.play(this.videoName.text);
}
}
到此就完成了使用FluorineFx.Net來實(shí)現(xiàn)視頻錄制和回放的功能,接下來我們來看看FluorineFx對發(fā)布錄制視頻流以及實(shí)況視頻流的安全方面是怎么處理的。FluorineFx.Messaging.Api.Stream.IStreamPublishSecurity 接口就是專門用來處理發(fā)布流是的安全處理的,如果要對發(fā)布流進(jìn)行安全方面的處理,那么就自定義一個實(shí)現(xiàn)該接口的安全策略類,在策略類里根據(jù)自己的實(shí)際情況來處理安全設(shè)置。
通過該安全策略類可以很方便的判斷發(fā)布流的類型、流的名稱以及對發(fā)布流進(jìn)行授權(quán)等相關(guān)操作。如下安全策略類:
{
public class PublishSecurity : IStreamPublishSecurity
{
public bool IsPublishAllowed(IScope scope, string name, string mode)
{
//是否為錄制流
if (!"record".Equals(mode))
{
return false;
}
//文件名是否以test開頭
if (!name.StartsWith("test"))
return false;
else
return true;
}
}
}
在應(yīng)用處理程序里通過ApplicationAdapter提供的RegisterStreamPublishSecurity()方法注冊安全策略,該方法的定義如下所示:
要注冊發(fā)布流的安全策略,通常都是在應(yīng)用程序啟動中注冊,如下代碼塊:
{
RegisterStreamPublishSecurity(new PublishSecurity());
return base.AppStart(application);
}
通過RegisterStreamPublishSecurity()方法注冊好發(fā)布流的安全策略后,每次發(fā)布流都會通過自定義的安全策略來檢測當(dāng)前發(fā)布流是否符合自定義的安全規(guī)則。這樣一方便可以保證別人惡意連接到你的應(yīng)用程序進(jìn)行流的發(fā)布,消耗網(wǎng)絡(luò)帶寬等多中不利現(xiàn)象,更多的好處還待研究。
本文示例程序下載
相關(guān)文章
Flex與.NET互操作(十三):FluorineFx.Net實(shí)現(xiàn)視頻錄制與視頻回放
本文主要介紹使用FluorineFx.Net來實(shí)現(xiàn)視頻錄制與視頻回放,F(xiàn)luorineFx如同F(xiàn)MS一樣,除了有AMF通信,RTMP協(xié)議,RPC 和遠(yuǎn)程共享對象外,它同樣具備視頻流服務(wù)的功能。2009-06-06Flex Gumbo 通過textJustify樣式設(shè)置TextBox文字對齊的例子
接下來的例子演示了Flex Gumbo中如何通過textJustify樣式,設(shè)置TextBox文字對齊。2009-06-06Flex Gumbo中通過baseColor樣式 設(shè)置FxHScrollBar背景顏色
Gumbo中通過baseColor樣式 設(shè)置FxHScrollBar背景顏色的實(shí)現(xiàn)代碼。需要的朋友可以參考下。2009-08-08基于WebService的數(shù)據(jù)訪問(下) Flex與.NET互操作(三)
在上一篇文章《Flex與.NET互操作(二):基于WebService的數(shù)據(jù)訪問(上) 》中介紹了通過<mx:WebService>標(biāo)簽來訪問Webservice。實(shí)際上我們也可以通過編程的方式動態(tài)的訪問WebService,F(xiàn)lex SDK為我們提供了WebService類。2009-06-06在flex中執(zhí)行一個javascript方法的簡單方式
說明:這里巧妙的運(yùn)用了JavaScript中的eval全局函數(shù),非常好,省的在嵌入flash的網(wǎng)頁文件中寫JavaScript函數(shù)。2009-05-05Flex結(jié)合JavaScript讀取本地路徑的方法
鑒于adobe并沒有提供FileReference對瀏覽的文件的完整路徑的接口。只能采用JS和fileinput控件來獲取本地路徑了。2009-02-02