本文主要介绍怎么去创建基于FMS的流媒体播放程序,Flash客户端通过网络加载FMS服务器上的视频流文件(.flv,.mp4等),实现视频流的播放。
看看上面的程序代码是不是非常简单,现在我对上面的代码进行详细的分析。程序从上到下思路很清晰,首先将程序中需要的相关包导入,然后定义了连接对象(NetConnection),流对象(NetStream)和视频对象(Video)。
要实现媒体流文件的播放是非常简单的,只要在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 }
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 {}
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 }
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 }
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的连接,代表当前应用有一个网络流正在传输,如下图:

完整示例代码
1
import flash.display.*;
2
import flash.events.*;
3
import flash.net.*;
4
import fl.controls.*;
5
6
var nc:NetConnection = new NetConnection();
7
var ns:NetStream;
8
var video:Video;
9
10
var btnPlay:Button=new Button();
11
btnPlay.x=10;
12
btnPlay.y=250;
13
btnPlay.width=50;
14
btnPlay.label="播放";
15
btnPlay.addEventListener(MouseEvent.CLICK,onPlayHandler);
16
addChild(btnPlay);
17
18
var btnPause:Button=new Button();
19
btnPause.x=80;
20
btnPause.y=250;
21
btnPause.width=50;
22
btnPause.label="暂停";
23
btnPause.addEventListener(MouseEvent.CLICK,onPauseHandler);
24
addChild(btnPause);
25
26
var btnStop:Button=new Button();
27
btnStop.x=150;
28
btnStop.y=250;
29
btnStop.width=50;
30
btnStop.label="停止";
31
btnStop.addEventListener(MouseEvent.CLICK,onStopHandler);
32
addChild(btnStop);
33
34
var btnReplay:Button=new Button();
35
btnReplay.x=220;
36
btnReplay.y=250;
37
btnReplay.width=80;
38
btnReplay.label="重新播放";
39
btnReplay.addEventListener(MouseEvent.CLICK,onReplayHandler);
40
addChild(btnReplay);
41
42
nc.connect("rtmp://192.168.1.103/PlayStreams");
43
nc.addEventListener(NetStatusEvent.NET_STATUS,onStatusHandler);
44
45
function onStatusHandler(evt:NetStatusEvent):void
46
{
47
trace(evt.info.code);
48
if(evt.info.code=="NetConnection.Connect.Success")
49
{
50
playStream();
51
}
52
}
53
54
function playStream():void
55
{
56
ns=new NetStream(nc);
57
ns.addEventListener(NetStatusEvent.NET_STATUS,onStatusHandler);
58
ns.client=new CustomClient();
59
video=new Video();
60
video.attachNetStream(ns);
61
ns.play("2009031302",0);
62
addChild(video);
63
}
64
65
function onPlayHandler(evt:MouseEvent):void
66
{
67
ns.resume();
68
}
69
70
function onPauseHandler(evt:MouseEvent):void
71
{
72
ns.pause();
73
}
74
75
function onStopHandler(evt:MouseEvent):void
76
{
77
ns.close();
78
}
79
80
function onReplayHandler(evt:MouseEvent):void
81
{
82
ns.close();
83
playStream();
84
}
85
86
1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

如果在Flex环境下开发,更方便实现,详细本文就不做介绍了,核心代码和Flash里开发是一样的。
本文转自 beniao 51CTO博客,原文链接:http://blog.51cto.com/beniao/139285,如需转载请自行联系原作者