本文主要介绍使用FluorineFx.Net来实现视频录制与视频回放,FluorineFx如同FMS一样,除了有AMF通信,RTMP协议,RPC和远程共享对象外,它同样具备视频流服务的功能。通过它我们可以非常方便的实现在线视频录制、视频直播、视频聊天以及视频会议等类似应用程序的开发。
在《 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()方法注册好发布流的安全策略后,每次发布流都会通过自定义的安全策略来检测当前发布流是否符合自定义的安全规则。这样一方便可以保证别人恶意连接到你的应用程序进行流的发布,消耗网络带宽等多中不利现象,更多的好处还待研究。
本文示例程序下载:
FluorineFxVideo.rar