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的连接,代表当前应用有一个网络流正在传输,如下图:

ContractedBlock.gifExpandedBlockStart.gif

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

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

转自:http://www.cnblogs.com/beniao/archive/2009/03/14/1410969.html

转载于:https://www.cnblogs.com/AndySong/archive/2009/05/17/1458596.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/476312.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

kakfa怎么看消息是否堆积_纯种哈士奇多少钱一只,怎么看是否是纯种哈士奇

纯种哈士奇多少钱一只,怎么看是否是纯种哈士奇哈士奇之前是一种生存在高寒地带的工作犬,近些年迅速占领了家庭宠物的市场,成为最受欢迎的宠物犬之一,由于它精力过于旺盛而且服从性极地因此也让很多人头痛。但是这并不能让人们减少…

论文阅读笔记(二)【ACL2021】知识抽取NER

学习内容 由于刚刚进入知识图谱领域,对该领域的研究热点不是很了解,所以本文直接翻译ACL2021中关于知识抽取NER中各个论文的摘要和共享;并且适时在最后写出自己的理解;同时自己也会在了解完全部后给出各个论文的研究分类。 1. 题…

SQL Server 2000中的数据转换服务 (DTS)

SQL Server 2000中的数据转换服务 (DTS) 更新日期: 2004年06月15日发布者 Diane LarsenEuan Garden, 投稿人 Microsoft Corporation 2000 年 9 月 摘要: 为了完成数据合并、存档和分析等任务;为了进行应用程序开发;为了进行数据库…

LeetCode 599. 两个列表的最小索引总和(哈希map)

1. 题目 假设Andy和Doris想在晚餐时选择一家餐厅,并且他们都有一个表示最喜爱餐厅的列表,每个餐厅的名字用字符串表示。 你需要帮助他们用最少的索引和找出他们共同喜爱的餐厅。 如果答案不止一个,则输出所有答案并且不考虑顺序。 你可以假…

python odoo_odoo python 使用缓存

from tools.com_cache import cache, ctime, timeblock# 使用SQL来取得指定商品在指定仓库的库存数量def get_warehouse_stock_qty(self,warehouse_id):self.ensure_one()# 从缓存中查询,如有cache_data cache.warehouse_stock_qty.get([self.id,warehouse_id])if …

项目经理(project manager)刘小备的一天

背景介绍说明:人物:部门经理:汉小帝刘正系统实施部经理:陶小谦项目经理(project manager):刘小备软件Software工程师:关小羽张小飞赵小云马小超黄小忠任务:为江东通信公司开发套管理平台软件Software江东通信公司接口人:鲁小肃时间:2007年某某月某某天当前状态:项目在编码阶段进…

李宏毅机器学习(一)基本概念介绍

学习内容 这是第二次看机器学习的内容,所以这里主要记录的是让我印象深刻的知识点; 但是有两个问题: deep? 为什么不是越深越好?fat? 为什么要套娃,我们只需要将多个sigmoid并排不就好了吗&am…

灰色关联分析_灰色关联分析模型研究综述

灰色关联分析模型研究小结1 引言灰色关联分析是灰色系统理论中十分活跃的一个分支, 其基本思想是根据序列曲线几何形状来判断不同序列之间的联系是否紧密. 基本思路是通过线性插值的方法将系统因素的离散行为观测值转化为分段连续的折线, 进而根据折线的几何特征构造测度关联程…

LeetCode 622. 设计循环队列

1. 题目 设计你的循环队列实现。 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。 它也被称为“环形缓冲器”。 循环队列的一个好处是我们可以利用这个队列之前用过的空间。 在一个…

solidworks模板_工程师实用高级操作,Solidworks自定义属性链接到工程图模板

下面,我以一个非常简单的零件为例,为大家介绍如何在工程图中链接这些属性。来达到减少工作量节省工作时间的目的。1.这是1个简单的零件,零件的自定义零件属性都已经填写完成。2.制作该零件的工程图文件,这里我以SolidWorks中默认的…

简单的脚本控制面试题

版面上有一个button,一个div,单击button,div中显示当前日期 答案: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns"http://www.w3.org/1999/xht…

知识图谱入门知识(二)事件抽取(EE)详细介绍

学习内容 本文主要详细介绍事件抽取EE的概念&#xff1b; 装载自&#xff1a;李景鹏 啥是事件抽取(Event Extraction)&#xff1f; 同时这里关于事件抽取的介绍也可以作为补充&#xff1a; 分层网络用于事件参数抽取 事件抽取 事件提取&#xff08;Event Extraction EE&…

post和get传值

//post传值send.aspx: if (e.CommandName "ChaXun") { LinkButton Lik(LinkButton)e.Item.FindControl("LinkButton1"); Context.Items["username"] Lik.CommandArgument.ToString(); Server.Transfer…

交通流元胞自动机模拟仿真 matlab源码_元胞自动机中的时间反演

1.引言——生命游戏1970年&#xff0c;英国数学家约翰何顿康威提出了生命游戏&#xff08;Life Game&#xff09;。生命游戏本质是一个元胞自动机模型&#xff0c;每个元胞可以看作是一个细胞&#xff0c;细胞的产生、繁衍和死亡拥有3条演化规则。1&#xff0e; 如果一个细胞周…

李宏毅机器学习(二)自注意力机制

学习内容 本文以NLP为基础来介绍自注意力机制&#xff0c;而没有用图像为基础&#xff0c;但是其实两者都是相同的。 在图像中我们可以将图像切块&#xff08;块的划分是自定义的&#xff09;&#xff0c;然后计算块与块之间的关系&#xff1b; 这里介绍了self-attention 的由…

LeetCode 643. 子数组最大平均数 I

1. 题目 给定 n 个整数&#xff0c;找出平均数最大且长度为 k 的连续子数组&#xff0c;并输出该最大平均数。 示例 1: 输入: [1,12,-5,-6,50,3], k 4 输出: 12.75 解释: 最大平均数 (12-5-650)/4 51/4 12.75注意: 1 < k < n < 30,000。 所给数据范围 [-10,000&a…

技术交流论坛_研发部第四次技术交流论坛

炎热的七月&#xff0c;由研发部举办的第四次技术交流论坛顺利召开&#xff0c;这是知识的激烈碰撞&#xff0c;也是一次头脑风暴。出席本次交流活动的有柯明宏副总、郑正部长、权大有副部长、向民龙副部长等公司管理层领导和公司骨干成员。首先由柯明宏副总、郑正部长给这一次…

LeetCode 661. 图片平滑器

1. 题目 包含整数的二维矩阵 M 表示一个图片的灰度。 你需要设计一个平滑器来让每一个单元的灰度成为平均灰度 (向下舍入) &#xff0c; 平均灰度的计算是周围的8个单元和它本身的值求平均&#xff0c;如果周围的单元格不足八个&#xff0c;则尽可能多的利用它们。 示例 1: 输…

论文阅读笔记(三)【ACL 2021】Locate and Label: A Two-stage Identifier for Nested Named Entity

论文标题&#xff1a; Locate and Label: A Two-stage Identifier for Nested Named Entity Recognition 论文链接&#xff1a; https://arxiv.org/abs/2105.06804 代码链接&#xff1a; https://github.com/tricktreat/locate-and-label 摘要 &#xff08;1&#xff09;过…

WDK中出现的特殊代码

WDK中出现的特殊代码 我们用本章的最后一个小节来介绍一些在WDK示例代码中见到的特殊形式编码。这些代码在Win32应用程序的编程中很少见到&#xff0c;读者需要首先熟悉一下。 首先是参数说明宏。参数说明宏一般都是空宏&#xff0c;最常见的是IN和OUT。其实定义很简单&…