开发工具及环境:

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. 项目管理10000 hours – 瞎扯谈系列

    本系列会 zz 网上现有的文章,套句经典的话就是死磕自己,娱乐大众. 项目能否按时完成是项目管理的重要目标,将会面临的问题有团队的稳定性,冲突,会议以及压力. 团队中适度的人员流动是可以理解的,如何减 ...

  2. Win10 创建应用程序包及部署

    https://msdn.microsoft.com/zh-cn/library/windows/apps/xaml/hh454036.aspx https://msdn.microsoft.com/ ...

  3. wp8 入门到精通 聊天控件

    <Grid > <Grid x:Name="bubble_right" VerticalAlignment="Center" RenderTr ...

  4. Entity Framework Code First for SQL Compact

    这篇博客将介绍EF Code First中如何使用SQL Compact.SQL Compact是微软推出的免费的关系型数据库,目前最新版本是SQL Compact 4.0.微软的开发工具VS 201 ...

  5. RTP、RTCP及媒体流同步

    转自:http://blog.163.com/liu_nongfu/blog/static/19079414220139169225333/ 一.流媒体简介 流媒体是指在internet中使用流媒体技 ...

  6. windbg的高级玩法

    详见附件  jpg改zip

  7. UNIX索引技术访问文件初阶

    背景: 软考里面,多次碰到一道题: 过程 以前对于这样的题,仅仅知道: 在文件系统中,文件的存储设备通常划分为若干个大小相等的物理块,每块长为512或1024字节.文件的理结构是指文件在存储设备上的存 ...

  8. HDU 4162 Shape Number (最小表示法)

    题意:给你一串n个数,求出循环来看一阶差的最小字典序:数字串看成一个顺时针的环,从某一点开始顺时针循环整个环,保证字典序最小就是答案 例如给你 2 1 3 就会得到(1-2+8 注意题意负数需要加8) ...

  9. LoadRunner测试场景中添加负载生成器

    如何在LoadRunner测试场景中添加负载生成器 本文对如何在LoadRunner的测试场景中添加负载生成器,如何使用负载生成器的方法,总结形成操作指导手册,以指导测试人员指导开展相关工作. 1.什 ...

  10. MFC MSBDutyTable下载地址

    点击此处跳转到下载地址 简明教程: 对于非制表人,只需要添加空余时间-新建,然后点星期和节数有课的那个按钮,勾选自己有课的周数.全部勾好后,生成空余时间表.然后查看自己的空余时间表,并导出,发给制表人 ...