织梦CMS - 轻松建站从此开始!

罗索

Flash Media Server(FMS)应用一例

jackyhwei 发布于 2010-11-06 21:46 点击:次 
Flash多媒体服务器,用于把直接存放在服务器上的多媒体文件以流的方式广播出去,这些多媒体文件可以是FLV、MP3等格式,FMS另外一个功能就是实现直播流的接收和同步广播。当然,通过了解还知道它有很多配置选项,用于控制服务的行为。
TAG:

一、需求是这样的

现有一个游戏,服务器端管理员要通过摄像头把游戏演示实况记录下来,客户端网友可以通过浏览器观看游戏直播,服务器端还提供一个小窗口查看客户端看 到直播视频的模样(以免出错),同时可以暂停一下录像(作假用^-^),客户端网友以为只是网络卡了一下,不知情者并不知道怎么回事!服务器端的 Flash如下图:

Flash概貌

二、所需软件

(1)Macromedia Flash

按需设计Flash程序或UI的IDE,因为本文讨论程序简单,无须下载专门的ActionScript开发工具,真有需求的话当然选择官方的Flex Builder。

(2)Macromedia Flash Media Server(FMS)

Flash多媒体服务器,用于把直接存放在服务器上的多媒体文件以流的方式广播出去,这些多媒体文件可以是FLV、MP3等格式,FMS另外一个功能就是实现直播流的接收和同步广播。当然,通过了解还知道它有很多配置选项,用于控制服务的行为。

(3)IIS(可选)

如果你开发了一套在线视频聊天系统,你要把整个程序部署成功,除了上面的FMS还是不够的,当然根据你系统的开发语言,也许可能不是IIS,而是Apache,或者是其它的服务器软件。

小提示:Macromedia早已被Adobe(Photoshop公司)收购了,更多使用方法可以到Adobe官方网站获得。

三、所需硬件

一部充当服务器和客户端双重角色的电脑、一个摄像头、一个麦克风(可选,大不了看无声视频,反正只是测试用)。

本人摄像头是用手机摄像头代替的,我用的是Symbian系统智能手机,然后用Mobiola Web Camera USB软件把手机摄像头变成视频摄像头并测试成功(下图),QQ视频聊天一样适用。另外提示一下,如果你也没有独立的摄像头,但有一部可以摄影的手机,虽 然不是智能手机,也许本身是可以当视频摄像头用的,具体的你可以回去详细看一下说明书。

把手机摄像头变成视频摄像头并测试成功

四、具体实施

具体实施的思路描述应该是这样的:要有两个Flash文件,一个部署在客户端(网友查看那一端),这一端的Flash文件只要接收FMS上指定的一 个直播文件流并播放就行了。而服务器端则稍微复杂点,这一端要启动本地摄像头,并把录制的视频以直播流的方式存到FMS服务器上(直播流的方式不会在 FMS上一直存储录制的视频文件,这对长时间直播而服务器又没有足够大的硬盘空间情况下适用,当然这些视频流无须备份,不同于银行或小区的摄像录影),同 时因为服务器端还要看一下客户端实际看到的视频样子,所以还要有一个视频控件实例用于显示从服务器上即时取回的视频流,另外还要有一个控制按钮,用于控制 停止和开始录制视频。如下图,没有开始录制时,因为客户端用户请求的视频源还没有,所以VideoSystemC.swf显示空白。开始录制后,服务器端 的VideoSystemS.swf大窗口和左上角小窗口看到的视频将是一样的,几乎是同步的,因为我测试的摄影与FMS都在同一部电脑,所以较快,真正 部署应用后,网友那一端可能会比这里的小窗口显示的画面稍微滞后一点。

开始录制前

开始录制后

两个Flash文件代码:

其中loadtxt.load("VideoMsg.txt");语句用于从同级目录下加载VideoMsg.txt文件中的变量。我没有直接写在 FLA文件里是为了以后部署的方便,到时只要改一下这个记事本文件就行,不用修改这个动画的源文件。VideoMsg.txt里面存的内容是 ServerUrl=rtmp://localhost/chat&PlayFileName=temVideo,这里的“chat”是自己在 FMS安装目录的applications目录下新建的一个应用目录名,“temVideo”是用于在FMS服务器上存储直播流的标 识,“localhost”当然是服务器地址,这个地址按实际情况修改。

(1)客户端VideoSystemC.swf

Stage.scaleMode = "noScale";
Stage.showMenu 
= false;
var loadtxt = new LoadVars();
loadtxt.load(
"VideoMsg.txt");
loadtxt.onLoad 
= function(Success) {
    
if (Success) {
        nc 
= new NetConnection();
        nc.connect(loadtxt.ServerUrl);
        nc.onStatus 
= function(info) {
            
if (info.code != "NetConnection.Connect.Success") {
                
if (info.code == "NetConnection.Connect.Failed") {
                    _root.msg.text 
= "视频连接失败···";
                } 
else if (info.code == "NetConnection.Connect.Rejected ") {
                    _root.msg.text 
= "视频连接被服务器拒绝···";
                } 
else {
                    _root.msg.text 
= "视频正在连接中···";
                }
            } 
else {
                _root.msg.text 
= "";
            }
        };
        res 
= new NetStream(nc);
        view.attachVideo(res);
        view.attachAudio(res);
        res.play(loadtxt.PlayFileName);
    }
};

(2)服务器端VideoSystemS.swf

Stage.scaleMode = "noScale";
Stage.showMenu 
= false;
var loadtxt = new LoadVars();
loadtxt.load(
"VideoMsg.txt");
loadtxt.onLoad 
= function(Success) {
    
if (Success) {
        viewS.attachVideo(Camera.get());
        viewS.attachAudio(Microphone.get());
        nc 
= new NetConnection();
        nc.connect(loadtxt.ServerUrl);
        nc.onStatus 
= function(info) {
            
if (info.code != "NetConnection.Connect.Success") {
                
if (info.code == "NetConnection.Connect.Failed") {
                    _root.msg.text 
= "视频连接失败···";
                } 
else {
                    _root.msg.text 
= "视频正在连接中···";
                }
            } 
else {
                _root.msg.text 
= "";
            }
        };
        nsOut 
= new NetStream(nc);
        _root.btn.label 
= "开始录像";
        
var flag = true;
        _root.btn.onRelease 
= function() {
            
if (flag) {
                flag 
= false;
                _root.btn.label 
= "停止录像";
                nsOut.attachVideo(Camera.get());
                nsOut.attachAudio(Microphone.get());
                nsOut.publish(loadtxt.PlayFileName, 
"live");
            } 
else {
                flag 
= true;
                _root.btn.label 
= "开始录像";
                nsOut.attachVideo(
null);
                nsOut.attachAudio(
null);
            }
        };
        res 
= new NetStream(nc);
        viewC.attachVideo(res);
        viewC.attachAudio(res);
        res.play(loadtxt.PlayFileName);
    }
};

五、注意事项

1、安装完FMS,用正确的管理员帐号和密码无法通过Management Console登录服务器控制台,总是提示“尝试登录失败”,这很可能是你的防火墙或杀毒软件引起的。拿本人安装环境来说,我的电脑上安装了“卡巴斯基” 和“360安全卫士”,一开始也是发现登录失败的,后来我逐步退出“卡巴斯基”和“360安全卫士”,退出“卡巴斯基”后还是登录不成功,最终退出 “360安全卫士”就成功登录了,这表明是“360安全卫士”在搞鬼。

2、你发布的Flash文件(SWF文件)如果要与服务器或外网通信,直接运行是不行的,这是为了安全起见,我们可以把它部署到服务器上,或者根据提示直接设置一下。

通信限制

通过设置解除限制

3、如果你访问的Flash文件要启动本地摄像头,它会出现一个提示框,问你是否允许连接,当然要选择允许,因为我们是知情的,不存在被偷拍的可 能。据说有QQ强制视频软件,对方可以在你不知情的情况下通过启动你的摄像头看到你的样子。而Flash上面的限制就是为了防止此类事情的发生。

摄像头请求连接

六、话题延伸

下面谈谈视频其它几种应用场合的实现原理:

(1)在线美女直播:美女直播自己的视频给广大网友,这个美女看不到网友的视频。这就与本文讨论的实例类似,此 时美女充当了服务端的管理员。本文讨论的FMS也是在同一部电脑上的,但是这里的美女直播应用,FMS是不能在这个美女机子上的,她是通过FMS服务器的 IP地址或域名来访问远程服务器。同时,我们不希望同一时间只有一个美女在上面发布视频,多美女发布视频的时候,为每个人分配一个视频存储标识(通常你可 能会用这个美女会员的ID帐号),然后把这些视频标识存在数据库,网页中读出这些在线美女直播列表就行了,用户爱看哪个就点击查看哪个。

(2)双向互动视频:网友和美女可以互相视频,这就类似QQ的常用视频功能。此时应该是一对一关系了,此时客户端与服务器端都要启动摄像头,并把自己的视频直播到FMS服务器,双方回调视频的时候把Flash文件视频源请求到对方的源上就可以。

(3)网络会议:网络会议通常是超过两个人的了,而且每个人都要能看到其他人的样子,所以可以这样理解,呈现在 每个会议成员面前的Flash画面应该是由很多小画面组成的,每个小画面对应一个会议成员,每个人的机子都要有摄像头和麦克风,都要把自己的视频流直播到 FMS上,然后每个人访问的那个Flash文件要一次请求所有会议成员的视频源到本地显示。很显然,这对网速或带宽有了更高的要求。其实视频服务本来就不 是一个小站长都能玩的,成本比较高,想想看现在人都喜欢看高清的,你搞出来的视频服务不高清,人们不爱看,这样你除了买昂贵的FMS服务器及支付高额带宽 费,还要去买高级视频采集卡之类的硬件。

(webflash)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201011/10422.html]
本文出处:博客园 作者:webflash
顶一下
(0)
0%
踩一下
(1)
100%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容