Flex与.NET互操作(十三):FluorineFx.Net实现视频录制与视频回放
通过它我们可以非常方便的实现在线视频录制、视频直播、视频聊天以及视频会议等类似应用程序的开发。
在《FMS3系列(四):在线视频录制、视频回放 》这篇文章里我写了通过FMS来实现在线视频录制和视频回放的功能,客户端的开发和这篇文章是相同的,不同的是本文将使用Flex来开发。
首先我们来看看使用FluorineFx服务端是如何开发的,建立ApplicationAdapter是必然的,这里我们为本文中的示例程序建立的ApplicationAdapter为VideoApplication,并为其添加RemotingServiceAttribute 如下代码块:
namespace Fx.Adapter
{
/// <summary>
/// 视频应用
/// </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模板所提供的方法在实际项目开发中根据自己的需求去重写,这里不作过多介绍。光是这样还是不能实现视频的录制和回放的功能,这只是实现了基本的启动应用程序和客户端连接等基本功能,要想实现视频录制和回放,我们还得让 VideoApplication实现IStreamService接口,该接口提供了实现视频发布和播放的相应功能,其定义如下:
namespace FluorineFx.Messaging.Api.Stream
{
[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,有了应用处理器接下来在FluorineFx网站的apps中添加应用程序(VideoApp),并配置好由此处理器来处理视频录制和回放。
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<application-handler type="Fx.Adapter.VideoApplication"/>
</configuration>
要使用RTMP协议,那么配置RTMP通信信道肯定是不能少的,在配置文件WEB-INF/flex/service-config.xml中配置使用RTMP协议的通信信道。
?xml version="1.0" encoding="utf-8" ?>
<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服务器端“基本”算是完成了。下面转到客户端的开发,建立Flex项目并设计好界面,如下图:
建立与FluorineFx服务器上应用程序的连接,连接成功则将自己的视频数据显示到界面上,如下实现代码:
private function connectionServer(event:MouseEvent):void
{
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("没有检测到视频摄像头","系统提示");
}
}
}
录制视频也就是将自己本机的视频摄像头获取的视频数据以及音频设备的数据附加到网络流(NetStream),使用网络流的publish()方法将流发布到服务器上,这和使用FMS是相同的。
private function onRecordVideo(event:MouseEvent):void
{
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;
}
}
停止视频录制的功能就更加简单了,直接断开当前客户端与服务器端的连接就可以,使用网络连接(NetConnection)的close()方法。
录制好的视频将会保存在网站下的apps/VideoApp/stream目录中,如下图:
实现录制的视频回放实际上就是播放服务器上的一个.flv视频文件,同样需要先建立与服务器端的网络连接,通过网络流去加载指定的视频文件,最后将其显示到应用界面上。
private function onPlayVideo(event:MouseEvent):void
{
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来实现视频录制和回放的功能,接下来我们来看看FluorineFx对发布录制视频流以及实况视频流的安全方面是怎么处理的。FluorineFx.Messaging.Api.Stream.IStreamPublishSecurity 接口就是专门用来处理发布流是的安全处理的,如果要对发布流进行安全方面的处理,那么就自定义一个实现该接口的安全策略类,在策略类里根据自己的实际情况来处理安全设置。
通过该安全策略类可以很方便的判断发布流的类型、流的名称以及对发布流进行授权等相关操作。如下安全策略类:
namespace Fx.Adapter
{
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;
}
}
}
在应用处理程序里通过ApplicationAdapter提供的RegisterStreamPublishSecurity()方法注册安全策略,该方法的定义如下所示:
public void RegisterStreamPublishSecurity(IStreamPublishSecurity handler);
要注册发布流的安全策略,通常都是在应用程序启动中注册,如下代码块:
public override bool AppStart(IScope application)
{
RegisterStreamPublishSecurity(new PublishSecurity());
return base.AppStart(application);
}
通过RegisterStreamPublishSecurity()方法注册好发布流的安全策略后,每次发布流都会通过自定义的安全策略来检测当前发布流是否符合自定义的安全规则。这样一方便可以保证别人恶意连接到你的应用程序进行流的发布,消耗网络带宽等多中不利现象,更多的好处还待研究。
本文示例程序下载