开发工具及环境:

1)flash builder4

2)flash cs4

3)flash media server3.5

fms部分

fms是adobe的流媒体服务器,不过是收费的,价格大概是oracle的一半,不过还是觉得挺贵的。adobe提供控制连接数的开发人员版,除了这点具体和完全版一样。服务器的配置网上很多,大家一搜就一大把。

其中关键的是:

由于需求是不仅要提供直播,而且还能点播历史音视频。而as的NetStream的publish方法提供的录制功能是将录制的视频放在直播的同一个文件夹下,所以要需要改一下fms配置。

1)fms的dvr默认是关闭的,需要修改C:/Program Files/Adobe/Flash Media Server 3.5/applications/live/main.far里的Application.xml,将文件中的
<StreamManager>
<StreamRecord override="no">false</StreamRecord>
</StreamManager>

改为
<StreamManager>
<StreamRecord override="yes">true</StreamRecord>
</StreamManager>

修改后重新加入main.far中

2)fms默认是将直播与点播文件目录分开的(live和vod),但是视频录制是在live文件加下,所以我们要修改点播目录

C:/Program Files/Adobe/Flash Media Server 3.5/conf/fms.ini文件中将
VOD_DIR 设置为 C:/Program Files/Adobe/Flash Media Server 3.5/applications/live
这样就可以实现直播点播同文件夹共存了

3)配置虚拟目录

打开C:/Program Files/Adobe/Flash Media Server 3.5/applications/live/Application.xml在<VirtualDirectory>中加入
<Streams>/;${VOD_COMMON_DIR}</Streams>
<Streams>/;${VOD_DIR}</Streams>

补充:如果在flex中直播视频时抛出noAccess错误,请在服务器上给录制机分配写入的权限。
通过以上配置fms就完成了

flex部分

<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" width="" height=""
creationComplete="init_creationCompleteHandler(event)"
closing="unonload()">
<s:layout>
<s:BasicLayout/>
</s:layout>
<fx:Style source="media.css"/> <fx:Script>
<!--[CDATA[
import flash.events.NetStatusEvent;
import flash.net.NetConnection;
import flash.net.NetStream; import mx.collections.ArrayCollection;
import mx.controls.Alert;
import mx.controls.Text;
import mx.events.FlexEvent; private var nc:NetConnection;
private var ns:NetStream;
private var vi:Video;
private var cam:Camera;
private var microphone:Microphone;
private var fmsArr:ArrayCollection=new ArrayCollection([]);
private var sharedObject:SharedObject=SharedObject.getLocal("com.ue"); /**
* 初始化
*/
protected function init_creationCompleteHandler(event:FlexEvent):void{
var loader:URLLoader = new URLLoader();
loader.dataFormat=URLLoaderDataFormat.VARIABLES;
loader.addEventListener(Event.COMPLETE, loader_complete);
loader.load(new URLRequest("global.txt")); function loader_complete(e:Event):void {
var variables:URLVariables=new URLVariables(loader.data);
trace(variables["servers"]); var serversArr:Array = variables["servers"].toString().split("@#@");
for(var i:int=;i<serversArr.length;i++){
var server:String = serversArr[i];
var sArr:Array = server.toString().split("$#$"); fmsArr.addItem({label:sArr[], value:sArr[]});
}
} getCookie();
} public function getCookie():void{
if(sharedObject.data["pmhidh"]!=null){
pmhID.text = sharedObject.data["pmhidh"];
}
if(sharedObject.data["spfwq"]!=null){
trace(sharedObject.data["spfwq"]);
fms.selectedItem = sharedObject.data["spfwq"];
}
if(sharedObject.data["yl"]!=null){
slider.value = sharedObject.data["yl"];
} } /**
* 开始直播
*/
protected function startButton_clickHandler(event:MouseEvent):void{ startButton.enabled=false;
stopButton.enabled=true;
nc = new NetConnection();
nc.addEventListener(NetStatusEvent.NET_STATUS,connectServerHander);
nc.client = this; trace(fms.selectedItem.label);
nc.connect(fms.selectedItem.value); slider.enabled=true;
}
/**
* 回调函数
*/
public function connectServerHander(evt:NetStatusEvent):void{
cam = Camera.getCamera();
microphone = Microphone.getMicrophone(); if(microphone!=null){
microphone.setSilenceLevel();//总是收集音频
microphone.rate=;
}else{
Alert.show("无法链接到麦克风!");
} if(cam != null){
cam.setMode(,,);
cam.setQuality(,);
ns = new NetStream(nc);
ns.attachCamera(cam);
ns.attachAudio(microphone);
ns.publish(pmhID.text,"append"); vi = new Video();
vi.width = player.width;
vi.height = player.height;
vi.attachCamera(cam);
player.addChild(vi); }else{
Alert.show("无法链接到摄像头!");
}
}
/**
* NetConnection回调函数
*/
public function onBWDone():void{} /**
* 保存音视频文件
*/
// protected function browse_clickHandler(event:MouseEvent):void{
// var file:File = new File();
// file.addEventListener(Event.SELECT,dirSelected);
// file.browseForSave("另存为");
// function dirSelected(e:Event):void {
// trace(file.nativePath);
// filefilePath.text = file.nativePath;
// }
// } /**
* 音量控制
*/
protected function slider_changeHandler(event:Event):void{
microphone.gain = slider.value;
} /**
* 停止发布
*/
protected function stopButton_clickHandler(event:MouseEvent):void{
ns.close();
vi.visible=false;
startButton.enabled=true;
stopButton.enabled=false;
} /**
* 关闭窗口触发事件,保存配置
*/
public function unonload():void{
if(sharedObject!=null){
sharedObject.clear();
}
if(sharedObject.data["pmhidh"]==null){
sharedObject.data["pmhidh"] = pmhID.text;
}
if(sharedObject.data["spfwq"]==null){
sharedObject.data["spfwq"] = fms.selectedItem;
}
if(sharedObject.data["yl"]==null){
sharedObject.data["yl"] = slider.value;
}
sharedObject.flush();
} ]]-->
</fx:Script> <fx:Declarations>
<!-- 将非可视元素(例如服务、值对象)放在此处 -->
</fx:Declarations>
<s:Panel width="100%" height="100%" x="" y="" id="panel1">
<s:layout>
<s:VerticalLayout paddingLeft="" paddingRight="" paddingBottom="" paddingTop="" requestedRowCount=""/>
</s:layout>
<s:VGroup width="" height="" paddingTop="" paddingBottom="" paddingRight="" paddingLeft="">
<s:HGroup width="" height="" paddingLeft="" paddingTop="" paddingBottom="" paddingRight="">
<s:BorderContainer width="" height="">
<s:VideoDisplay width="" height="" scaleMode="letterbox" id="player" x="" y=""/>
</s:BorderContainer>
<s:BorderContainer width="" height="">
<s:VGroup width="" height="" paddingLeft="" paddingTop="" paddingBottom="" paddingRight="" gap="" x="" y="">
<s:Label text="拍卖会ID号:" height="" id="pmhIDLabel"/>
<s:TextInput id="pmhID"/>
<s:Label text="视频服务器:" height=""/>
<s:ComboBox id="fms" dataProvider="{fmsArr}"/>
<s:Label text="音量" height=""/>
<s:HSlider id="slider" enabled="false" change="slider_changeHandler(event)" minimum="" maximum="" stepSize=""/>
</s:VGroup>
</s:BorderContainer>
</s:HGroup>
<s:HGroup width="" height="" paddingTop="" paddingBottom="" paddingRight="" paddingLeft="" verticalAlign="middle" textAlign="center">
<s:Button id="startButton" label="开始发布" click="startButton_clickHandler(event)"/>
<s:Button label="停止发布" id="stopButton" enabled="false" click="stopButton_clickHandler(event)"/>
</s:HGroup>
</s:VGroup>
</s:Panel>
</s:WindowedApplication>

效果如下:

flash部分/点播代码

import flash.net.*;
import flash.events.*; var loader:URLLoader = new URLLoader();
loader.dataFormat=URLLoaderDataFormat.VARIABLES;
loader.addEventListener(Event.COMPLETE, loader_complete);
loader.load(new URLRequest("media2.txt")); function loader_complete(e:Event):void {
var variables:URLVariables=new URLVariables(loader.data); myVideo2.source=variables["source"];
}
myVideo2.isLive=false;

效果如下:

flash部分/直播代码

import flash.net.*;
import flash.events.*; var loader:URLLoader = new URLLoader();
loader.dataFormat=URLLoaderDataFormat.VARIABLES;
loader.addEventListener(Event.COMPLETE, loader_complete);
loader.load(new URLRequest("media.txt")); function loader_complete(e:Event):void {
var variables:URLVariables=new URLVariables(loader.data); myVideo.source=variables["source"];
} myVideo.isLive=true;

效果如下:

flex4+fms3.5+cs4开发实时音视频直播及点播详解的更多相关文章

  1. 音视频入门-11-PNG文件格式详解

    * 音视频入门文章目录 * PNG 文件格式解析 PNG 图像格式文件由一个 8 字节的 PNG 文件署名域和 3 个以上的后续数据块(IHDR.IDAT.IEND)组成. PNG 文件包括 8 字节 ...

  2. 音视频入门-14-JPEG文件格式详解

    * 音视频入门文章目录 * JPEG 文件格式解析 JPEG 文件使用的数据存储方式有多种.最常用的格式称为 JPEG 文件交换格式(JPEG File Interchange Format,JFIF ...

  3. 各种音视频编解码学习详解 h264 ,mpeg4 ,aac 等所有音视频格式

    编解码学习笔记(一):基本概念 媒体业务是网络的主要业务之间.尤其移动互联网业务的兴起,在运营商和应用开发商中,媒体业务份量极重,其中媒体的编解码服务涉及需求分析.应用开发.释放 license收费等 ...

  4. 集显也能硬件编码:Intel SDK && 各种音视频编解码学习详解

    http://blog.sina.com.cn/s/blog_4155bb1d0100soq9.html INTEL MEDIA SDK是INTEL推出的基于其内建显示核心的编解码技术,我们在播放高清 ...

  5. 【miscellaneous】各种音视频编解码学习详解

    编解码学习笔记(一):基本概念 媒体业务是网络的主要业务之间.尤其移动互联网业务的兴起,在运营商和应用开发商中,媒体业务份量极重,其中媒体的编解码服务涉及需求分析.应用开发.释放license收费等等 ...

  6. 【FFMPEG】各种音视频编解码学习详解 h264 ,mpeg4 ,aac 等所有音视频格式

    目录(?)[-] 编解码学习笔记二codec类型 编解码学习笔记三Mpeg系列Mpeg 1和Mpeg 2 编解码学习笔记四Mpeg系列Mpeg 4 编解码学习笔记五Mpeg系列AAC音频 编解码学习笔 ...

  7. 了不起的WebRTC:生态日趋完善,或将实时音视频技术白菜化

    本文原文由声网WebRTC技术专家毛玉杰分享. 1.前言 有人说 2017 年是 WebRTC 的转折之年,2018 年将是 WebRTC 的爆发之年,这并非没有根据.就在去年(2017年),WebR ...

  8. 从零到一,使用实时音视频 SDK 一起开发一款 Zoom 吧

    zoom(zoom.us) 是一款受到广泛使用的在线会议软件.相信各位一定在办公.会议.聊天等各种场景下体验或者使用过,作为一款成熟的商业软件,zoom 提供了稳定的实时音视频通话质量,以及白板.聊天 ...

  9. 实时音视频互动系列(下):基于 WebRTC 技术的实战解析

    在 WebRTC 项目中,又拍云团队做到了覆盖系统全局,保证项目进程流畅.这牵涉到主要三大块技术点: 网络端.服务端的开发和传输算法 WebRTC 协议中牵扯到服务端的应用协议和信令服务 客户端iOS ...

随机推荐

  1. Code Review for SSIS package

    以下是我对SSIS包进行code review的一些建议,如果有其他更好的方案欢迎拍砖. A. 查看是否使用了最优的解决方案 1. 最优的结构视图 2. 解决方案,包,任务,组建,参数的命名使用了易读 ...

  2. HDU4008 Parent and son(树形DP LCA)

    先记录以1为根时每个节点子树儿子节点的最大与次小值,询问x, y时,先判断x在不在y的子树范围内,若不在,结果为y的儿子结点,后继的最小值. 若x在y的子树范围内,若y儿子最小值是x的前驱,从次小值与 ...

  3. Linq To Sql中实现Left Join与Inner Join使用Linq语法与lambda表达式

    当前有两个表,sgroup与sgroupuser,两者通过gKey关联,而sgroup表记录的是组,而sgroupuser记录是组中的用户,因此在sgroupuser中不一定有数据.需要使用Left ...

  4. AOP常用术语

    1.连接点(Joinpoint) 程序执行的某个特定位置:如类开始初始化前,类初始化后,类某个方法调用前,调用后,方法跑出异常后.一个类或一段程序代码拥有一些具有边界性质的特定点.这些代码中的特定点就 ...

  5. PHP利用jquery生成各种验证码和Ajax验证

    PHP生成验证码图片 PHP生成验证码的原理:使用PHP的GD库,生成一张带验证码的图片,并将验证码保存在Session中.PHP 生成验证码的大致流程有: .产生一张png的图片: .为图片设置背景 ...

  6. [JavaCore]JAVA中的泛型

    JAVA中的泛型 [更新总结] 泛型就是定义在类里面的一个类型,这个类型在编写类的时候是不确定的,而在初始化对象时,必须确定该类型:这个类型可以在一个在里定义多个:在一旦使用某种类型,在类方法中,那么 ...

  7. c中malloc的用法

    转自:http://blog.sina.com.cn/s/blog_966f8e8501010if7.html Malloc 向系统申请分配指定size个字节的内存空间.返回类型是 void* 类型. ...

  8. Vector[C++]

    //    vector<int> vec; //    for(int i = 0; i < 10; i++) //    { //        vec.push_back(5) ...

  9. Java学习笔记(五)——数组

    一.数组使用方法 1. 声明数组 语法: 数据类型[ ] 数组名: 或者   数据类型 数组名[ ]: 其中,数组名可以是任意合法的变量名 2. 分配空间 简单地说,就是指定数组中最多可存储多少个元素 ...

  10. mysql 怎样清空一个数据库中的所有表

    转自:http://blog.csdn.net/zhangzhizhen1988/article/details/8432146 MySQL清空表是很重要的操作,也是最常见的操作之一,下面就为您详细介 ...