随笔-254  评论-3298  文章-48  trackbacks-74

FMS3系列(四):在线视频录制、视频回放

      使用Flash/Flex+FMS实现在线视频录制、视频回放的很简单的。通过阅读API文档后基本都可以实现这个功能,本文也意在抛砖引玉,希望对刚入手这块的朋友有所帮助。

      首先建立好Flash(ActionScript 3.0)文件,从组件(可使用Ctrl+F7打开)库中拖拽相应的组件到Flash舞台上,如下图:

            

      界面布局好后我们通过程序设置组见的显示文本以及为按扭添加事件监听,新建一个ActionScript类文件,编写代码如下:

 1         public function PublishPlay():void
 2         {
 3             lbName.text="请输入视频文件名:";
 4             btnPublish.label="开始录制";
 5             btnPublish.addEventListener(MouseEvent.CLICK,onPublishClick);
 6             btnStop.label="停止录制";
 7             btnStop.addEventListener(MouseEvent.CLICK,onStopHandler);
 8             btnPlay.label="视频回放";
 9             btnPlay.addEventListener(MouseEvent.CLICK,onPlayHandler);
10             
11             video=new Video();
12             cam = Camera.getCamera();
13             mic = Microphone.getMicrophone();
14             if(cam==null)
15             {
16                 trace("没检测到视频摄像头");
17             }
18             else
19             {
20                 video.attachCamera(cam);
21             }
22             addChild(video);
23         }

 

      以上代码同时实现了将视频显示到flash界面上,通过Camera的静态方法getCamrea()方法可以直接获取到视频摄像头的数据。其中用到的video,cam和mic变量为预先定义好的,如下:

1     private var nc:NetConnection;
2     private var ns:NetStream;
3     private var video:Video;
4     private var cam:Camera;
5     private var mic:Microphone;

 

      接下来就需要连接到FMS服务器实现视频录制功能了,通过NetConnection类实现与FMS服务器的连接,并通过流将视频数据发布到FMS服务器。

 1         private function onPublishClick(evt:MouseEvent):void
 2         {
 3             nc=new NetConnection();
 4             nc.addEventListener(NetStatusEvent.NET_STATUS,onPublishStatusHandler);
 5             nc.connect("rtmp://localhost/PulishedStreams");
 6         }
 7         
 8         private function onPublishStatusHandler(evt:NetStatusEvent):void
 9         {
10             if(evt.info.code=="NetConnection.Connect.Success")
11             {
12                 ns=new NetStream(nc);
13                 ns.addEventListener(NetStatusEvent.NET_STATUS,onPublishStatusHandler);
14                 ns.client=new CustomClient();
15                 ns.attachCamera(cam);
16                 ns.attachAudio(mic);
17                 ns.publish(tbName.text,"record");
18             }
19         }

 

      在录制视频的时候视频命名是取的文本输入框的值作为视频名,OK,现在测试Flash(Ctrl+Enter),通过点击 按扭开始录制视频。通过查看FMS服务器的文件目录可以看到,刚刚测试录制的视频存放于FMS服务器应用下的streams/_definst_目录下。详见下图所示:

            

      录制功能完成了,通过测试也可以成功的录制视频。最后我们通过程序来播放刚刚录制是视频。关于播放视频在上一篇文章《FMS3系列(三):创建基于FMS的流媒体播放程序,看山寨帮的山寨传奇》中已介绍怎么实现,这里就直接帖出代码不做解释。

 1 private function onPlayHandler(evt:MouseEvent):void
 2         {
 3             nc=new NetConnection();
 4             nc.addEventListener(NetStatusEvent.NET_STATUS,onPlayStatusHandler);
 5             nc.connect("rtmp://localhost/PulishedStreams");
 6         }
 7         
 8         private function onPlayStatusHandler(evt:NetStatusEvent):void
 9         {
10             if(evt.info.code=="NetConnection.Connect.Success")
11             {
12                 ns=new NetStream(nc);
13                 ns.addEventListener(NetStatusEvent.NET_STATUS,onPlayStatusHandler);
14                 ns.client=new CustomClient();
15                 
16                 video = new Video();
17                 video.attachNetStream(ns);
18                 ns.play(tbName.text,0);
19                 addChild(video);
20             }
21         }

 

      通过本文的基础上可以很方便的扩展出在线拍照等多种应用,有兴趣的朋友可以去试验下。下面是本文完整的示例代码。

本文完整示例代码

 

版权说明

  本文属原创文章,欢迎转载,其版权归作者和博客园共有。  

  作      者:Beniao

 文章出处:http://beniao.cnblogs.com/  或  http://www.cnblogs.com/

posted on 2009-04-26 19:00 Bēniaǒ 阅读(3967) 评论(7) 编辑 收藏

评论:
#1楼 2009-04-27 08:30 | aierong      


盟主文章

 回复 引用 查看   
#2楼 2009-04-28 14:51 | 蓝色京广线      
学习!
 回复 引用 查看   
#3楼 2009-04-29 09:25 | 凌风有约      
学习
 回复 引用 查看   
#4楼 2009-05-29 00:32 | cici1712
楼主,我按你的代码改写了个录制音频的文件:下面是我的代码
package
{
import flash.net.NetConnection;
import flash.net.NetStream;
import flash.media.Microphone;
import flash.net.ObjectEncoding;
import flash.net.NetStream;
import flash.events.MouseEvent;
import flash.events.NetStatusEvent;
import fl.controls.Button;
import fl.controls.TextInput;
import flash.display.Sprite;
import flash.media.Sound;
import flash.media.SoundChannel;
import fl.controls.Label;
import flash.display.SimpleButton;
import flash.text.TextField;
import flash.display.Sprite;
public class record extends Sprite
{
private var my_nc = new NetConnection();
private var my_mic:Microphone;
private var my_ns:NetStream;
private var RecordInterval;
private var my_sound:Sound ;
private var my_soundstop:SoundChannel;
private var position:int;
private var msg:Boolean;
private var VideoName:String;
private var timeNum:Number=0;
public function record()
{
// my_mic=Microphone.getMicrophone(0);
// my_mic.setSilenceLevel(0,0);
record_bt.label="开始录制";
record_bt.addEventListener(MouseEvent.CLICK,startRecord);
finished_bt.label="停止录制";
finished_bt.addEventListener(MouseEvent.CLICK,stopRecord);
play_bt.label="回放";
play_bt.addEventListener(MouseEvent.CLICK,playRecord);
}


private function startRecord (evt:MouseEvent):void
{
my_nc=new NetConnection();
my_nc.client=new Client();
my_nc.addEventListener(NetStatusEvent.NET_STATUS,onPublishStatusHandler);
my_nc.connect("rtmp:/record");
}
private function onPublishStatusHandler(evt:NetStatusEvent):void
{
if(txt_name.text.length==0)
{
lab_alert.text="请输入文件名";
}
else
{
var timeNum:Number = 0;
if(evt.info.code=="NetConnection.Connect.Success")
{
my_mic=Microphone.getMicrophone();
my_mic.setSilenceLevel(0,0);
my_ns=new NetStream(my_nc);
my_ns.addEventListener(NetStatusEvent.NET_STATUS,onPublishStatusHandler);
my_ns.attachAudio(my_mic);
my_ns.publish(txt_name.text,"record");
lab_alert.text="";
timeNum ++;
txt_time.text ="正在录制" + " " + "时间:" + Math.floor (timeNum / 60) + "分" + (timeNum % 60) + "秒";
}
}
}

private function stopRecord (evt:MouseEvent):void
{
my_ns.close();
}
private function playRecord(evt:MouseEvent):void
{
my_nc=new NetConnection();
my_nc.client=new Client();
my_nc.addEventListener(NetStatusEvent.NET_STATUS,onPlayStatusHandler);
my_nc.connect("rtmp:/record");
}
private function onPlayStatusHandler(evt:NetStatusEvent):void
{
if(evt.info.code=="NetConnection.Connect.Success")
{
my_ns=new NetStream(my_nc);
my_ns.addEventListener(NetStatusEvent.NET_STATUS,onPlayStatusHandler);
my_ns.play(txt_name.text,0);
}
}
}

}
class Client {
public function onBWCheck(... rest):Number {
return 0;
}
public function onBWDone(... rest):void {
var p_bw:Number;
if (rest.length > 0)
p_bw = rest[0];
trace("bandwidth = " + p_bw);
}
}
但是每次运行时总是出现Write access denied for stream AA.网上查了下,好像是没有授权,不知道是什么原因,能不能帮解答下。多谢



 回复 引用   
#5楼 2009-07-28 11:02 | kuemacn      
write access denied for stream xx,写入失败。
查了帮助,
NetStream.onStatus()
ns.onStatus = function(info:Object){}Invoked every time a status change or error occurs in a NetStream object. The remote server can accept or reject a call to NetStream.publish().

但是在flash cs3中
ns.onStatus = function(info:Object){}
总是报错。
1119: 访问可能未定义的属性 netStatus (通过 static 类型 flash.net:NetStream 引用)。
或是权限的问题???
请赐教。谢谢。

 回复 引用 查看   
#6楼 2009-07-28 11:58 | kuemacn      
知道了。问题出在默认的文件中。。。
之前就是把VOD中的文件都拷贝过来了。
所以一直不成功。
现在只有一个main。asc,就可以了。很好用。
谢谢楼主的例子。

 回复 引用 查看   
#7楼[楼主] 2009-07-28 17:21 | Bēniaǒ      
@kuemacn
^.^

 回复 引用 查看   
发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 1415342 HM03qtk9qKc=
微软最有价值专家(MVP)

微软技术社区精英(CNTAC)

2010年IT博客大赛50强

微软最有影响力开发者(GDI)


Bing Maps开发一群:75662563
微软技术群-重庆站:97035589
RIA技术联盟QQ群:26917590
昵称:Bēniaǒ
园龄:4年6个月
荣誉:推荐博客
粉丝:408
关注:26

随笔分类(285)

文章分类(14)

积分与排名

  • 积分 - 760874
  • 排名 - 60

最新评论