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

FMS3系列(三):创建基于FMS的流媒体播放程序,看山寨帮的山寨传奇

     本文主要介绍怎么去创建基于FMS的流媒体播放程序,Flash客户端通过网络加载FMS服务器上的视频流文件(.flv,.mp4等),实现视频流的播放。

     要实现媒体流文件的播放是非常简单的,只要在FMS服务器上提供好流媒体文件,Flash客户端通过NetConnection连接到FMS服务器,然后通过NetStream加载就OK。关于怎么连接FMS在本系列的前两篇已有详细介绍,首先得在fms上建立好服务器应用并部署好媒体文件,如下图示:

           

 

     下面是在Flash中开发的流媒体文件播放示例程序:

 1 import flash.display.*;
 2 import flash.events.*;
 3 import flash.net.*;
 4 
 5 var nc:NetConnection = new NetConnection();
 6 var ns:NetStream;
 7 var video:Video;
 8 
 9 nc.connect("rtmp://localhost/PlayStreams");
10 nc.addEventListener(NetStatusEvent.NET_STATUS,onStatusHandler);
11 
12 function onStatusHandler(evt:NetStatusEvent):void
13 {
14     trace(evt.info.code);
15     if(evt.info.code=="NetConnection.Connect.Success")
16     {
17         ns=new NetStream(nc);
18         ns.addEventListener(NetStatusEvent.NET_STATUS,onStatusHandler);
19         ns.client=new CustomClient();
20         video=new Video();
21         video.attachNetStream(ns);
22         ns.play("2009031301",0);
23         addChild(video);
24     }
25 }


     看看上面的程序代码是不是非常简单,现在我对上面的代码进行详细的分析。程序从上到下思路很清晰,首先将程序中需要的相关包导入,然后定义了连接对象(NetConnection),流对象(NetStream)和视频对象(Video)。

     通过NetConnection的connect方法连接到fms服务器(rtmp://localhost/PlayStreams),并添加网络连接的事件处理函数,在此函数内判断网络连接状态,如果连接成功(连接状态:NetConnection.Connect.Success)则通过NetStream建立视频流,调用NetStream的play方法播放指定的流媒体文件,然后将流附加到视频对象并显示在flash界面上。如下图示:

          

     OK,我们已经实现了流媒体文件的播放,下面我们来扩展程序的功能,为前面的视频播放程序加上播放、暂停、停止以及重新播放等功能。这时可以在界面上放置几个按扭来驱动这些功能,添加按扭代码如下(当然也可以直接拖拽Botton组件):

 1 var btnPlay:Button=new Button();
 2 btnPlay.x=10;
 3 btnPlay.y=250;
 4 btnPlay.width=50;
 5 btnPlay.label="播放";
 6 btnPlay.addEventListener(MouseEvent.CLICK,onPlayHandler);
 7 addChild(btnPlay);
 8 
 9 var btnPause:Button=new Button();
10 btnPause.x=80;
11 btnPause.y=250;
12 btnPause.width=50;
13 btnPause.label="暂停";
14 btnPause.addEventListener(MouseEvent.CLICK,onPauseHandler);
15 addChild(btnPause);
16 
17 var btnStop:Button=new Button();
18 btnStop.x=150;
19 btnStop.y=250;
20 btnStop.width=50;
21 btnStop.label="停止";
22 btnStop.addEventListener(MouseEvent.CLICK,onStopHandler);
23 addChild(btnStop);
24 
25 var btnReplay:Button=new Button();
26 btnReplay.x=220;
27 btnReplay.y=250;
28 btnReplay.width=80;
29 btnReplay.label="重新播放";
30 btnReplay.addEventListener(MouseEvent.CLICK,onReplayHandler);
31 addChild(btnReplay);
32 
33 function onPlayHandler(evt:MouseEvent):void
34 {}
35 
36 function onPauseHandler(evt:MouseEvent):void
37 {}
38 
39 function onStopHandler(evt:MouseEvent):void
40 {}
41 
42 function onReplayHandler(evt:MouseEvent):void
43 {}

 

     这里我们需要对上面的代码进行一下重构,将流和控制视频播放的代码重构为方法,以便在重新播放的时候直接调用。

 

 1 function playStream():void
 2 {
 3     ns=new NetStream(nc);
 4     ns.addEventListener(NetStatusEvent.NET_STATUS,onStatusHandler);
 5     ns.client=new CustomClient();
 6     video=new Video();
 7     video.attachNetStream(ns);
 8     ns.play("2009031302",0);
 9     addChild(video);
10 }

 

     上面我们已经将控制视频播放、暂停、停止和重新播放的按扭构造在了flash界面上,现在只需要完成这些按扭的功能就是,要实现视频的播放、暂停、停止和重新播放同样是非常简单的,NetStream为我们提供了可直接调用的API。详细如下:

 1 function onPlayHandler(evt:MouseEvent):void
 2 {
 3     ns.resume();
 4 }
 5 
 6 function onPauseHandler(evt:MouseEvent):void
 7 {
 8     ns.pause();
 9 }
10 
11 function onStopHandler(evt:MouseEvent):void
12 {
13     ns.close();
14 }
15 
16 function onReplayHandler(evt:MouseEvent):void
17 {
18     ns.close();
19     playStream();
20 }

 

     一切搞定 ,可以按下Ctrl+Enter测试了,看到了flash已经成功的加载到了fms上的视频文件(.flv)。打开FMS管理控制台就会看到,在应用"PlayStreams"下有一个NetStream的连接,代表当前应用有一个网络流正在传输,如下图:

 

完整示例代码

 

     如果在Flex环境下开发,更方便实现,详细本文就不做介绍了,核心代码和Flash里开发是一样的。

版权说明

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

  作      者:Beniao

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

 

posted on 2009-03-14 01:40 Bēniaǒ 阅读(4076) 评论(20) 编辑 收藏

评论:
#1楼 2009-03-14 09:00 | Dreampuf      
flash作为client连接这些资源其实很方便...只是这些服务端程序的配置以及设置才是难点..而且这东西很贵...
 回复 引用 查看   
#2楼 2009-03-14 09:34 | 大漠枭狼      
你好,楼主兄,我也做这方面的东西,是和.net交互的,你能提供给我你的技术QQ群,或者电子邮件地址吗,不胜感激!
 回复 引用 查看   
#3楼[楼主] 2009-03-15 19:26 | Bēniaǒ      
@Dreampuf
呵呵,确实有点贵.

 回复 引用 查看   
#4楼[楼主] 2009-03-15 19:28 | Bēniaǒ      
@大漠枭狼
如果你是使用的Flex开发,与.NET交互我写过一系列文章.你可以看看。
http://www.cnblogs.com/beniao/archive/2009/02/13/1385996.html

 回复 引用 查看   
#5楼 2009-04-06 12:36 | 小新地方[未注册用户]
我用flex做 没图像 有声音 ns.client=new CustomClient();这句报错
没有CustomClient类 楼主怎么解决呀
谢谢

 回复 引用   
#6楼[楼主] 2009-04-13 09:54 | Bēniaǒ      
@小新地方
你需要建立一个CustomClient类。

 回复 引用 查看   
#7楼 2009-04-27 08:31 | aierong      
ding
 回复 引用 查看   
#8楼 2009-06-05 12:50 | ??[未注册用户]
--引用--------------------------------------------------
Bēniaǒ: @小新地方
你需要建立一个CustomClient类。
--------------------------------------------------------
具体CustomClient类代码

 回复 引用   
#9楼[楼主] 2009-06-05 13:04 | Bēniaǒ      
@??
CustomClient类不写代码都可以的,如果你是用的flash开发,它就会报错误“找不到onMetaData属性或方法”,你可以如下定义CustomClient类。
public class CustomClient
{
public function onMetaData(info:Object):void
{
}
public function onCuePoint(info:Object):void
{
}
}
如果你要给视频添加其他的属性就通过自定义的这个类去完成。

 回复 引用 查看   
#10楼 2009-06-22 13:21 | allpass[未注册用户]
对于flex下,不能直接把Video加到Application下,必须先添加
UIComponent,然后把Video加到UIComponent下,然后,再把UIComponent加到Application下,如下:
private function playStream():void
{
ns=new NetStream(nc);
ns.addEventListener(NetStatusEvent.NET_STATUS,onStatusHandler);
ns.client=new CustomClient();
video=new Video();
video.attachNetStream(ns);
//这儿需要注意,需要把Video加入一个UIComponent里才可以addChild
var screen:UIComponent=new UIComponent();
screen.setActualSize(200,200);
screen.addChild(video);

ns.play("sample",0);
addChild(screen);
}

 回复 引用   
#11楼[楼主] 2009-06-22 17:46 | Bēniaǒ      
@allpass
这样做也是可以的,flex中只有显示对象才能够addChild()到舞台上.
除了UIComponent还有更简单的做法,flex中有<mx:VideoDisplay>组件,你可以直接将一个Video对象addChild()给VideoDisplay.

界面上放置一个VideoDisplay组件,取个id,如myVD:
myVD.addChild(video);

 回复 引用 查看   
#12楼 2009-07-07 15:18 | Jason_Yuan      
ns.client=new CustomClient();
1180: 调用的方法 CustomClient 可能未定义。
???

 回复 引用 查看   
#13楼 2009-07-07 15:32 | Jason_Yuan      
哦 明白 。。刚有看上面的评论。
 回复 引用 查看   
#14楼[楼主] 2009-07-07 17:45 | Bēniaǒ      
@Jason_Yuan
......

 回复 引用 查看   
#15楼 2009-09-25 21:08 | licun[未注册用户]
博主,我按文中的步骤,FLV可以,SWF的就不行,服务器是FMS3.5,FLEX3,而且输出到客户端的VideoDisplay上时,显示在播放窗体里只有不到10X10的尺寸,就是播放画面里只有左上角一点在显示(影片内容缩小,而不是截取一部份),而播放窗体没有缩小,本地文件就没问题,难道FMS输出流时要重新编码?
 回复 引用   
#16楼 2009-09-26 10:30 | licun[未注册用户]
问题解决了,NetStream是只能用流,或渐进式的FLV,swf这个要下完才放的不支持,视频尺寸,使用UIComponent,而不是VideoDisplay,Video的构造方法使用有参的那个,把显示大小传进去,就没问题了,不知道为什么,若是使用VideoDisplay,那么Video设了也没用,怪啊。
 回复 引用   
#17楼 2010-01-21 22:04 | 大灰狠      
楼主 flv文件一定要放到streams/_definst_目录下吗?
 回复 引用 查看   
#18楼[楼主] 2010-01-22 17:02 | Bēniaǒ      
@大灰狠
这个是FMS默认目录,应该是可以改的,你查看API文档。

 回复 引用 查看   
#19楼 2010-08-01 09:32 | lover's      
博主:
你所说的api文档是什么啊?能否发一份呢?我的邮箱是:
meiyizeng@yeah.net

 回复 引用 查看   
#20楼[楼主] 2010-08-01 10:56 | Bēniaǒ      
@lover's
FMS安装后在安装目录下就有相关的API手册。或者你网上下载本FMS的电子书看看呢。

 回复 引用 查看   
发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

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

0 1410969 sRBIutv4hPE=
微软最有价值专家(MVP)

微软技术社区精英(CNTAC)

2010年IT博客大赛50强

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


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

随笔分类(285)

文章分类(14)

积分与排名

  • 积分 - 760874
  • 排名 - 60

最新评论