flex4+fms3.5+cs4开发实时音视频直播及点播详解
开发工具及环境:
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开发实时音视频直播及点播详解的更多相关文章
- 音视频入门-11-PNG文件格式详解
* 音视频入门文章目录 * PNG 文件格式解析 PNG 图像格式文件由一个 8 字节的 PNG 文件署名域和 3 个以上的后续数据块(IHDR.IDAT.IEND)组成. PNG 文件包括 8 字节 ...
- 音视频入门-14-JPEG文件格式详解
* 音视频入门文章目录 * JPEG 文件格式解析 JPEG 文件使用的数据存储方式有多种.最常用的格式称为 JPEG 文件交换格式(JPEG File Interchange Format,JFIF ...
- 各种音视频编解码学习详解 h264 ,mpeg4 ,aac 等所有音视频格式
编解码学习笔记(一):基本概念 媒体业务是网络的主要业务之间.尤其移动互联网业务的兴起,在运营商和应用开发商中,媒体业务份量极重,其中媒体的编解码服务涉及需求分析.应用开发.释放 license收费等 ...
- 集显也能硬件编码:Intel SDK && 各种音视频编解码学习详解
http://blog.sina.com.cn/s/blog_4155bb1d0100soq9.html INTEL MEDIA SDK是INTEL推出的基于其内建显示核心的编解码技术,我们在播放高清 ...
- 【miscellaneous】各种音视频编解码学习详解
编解码学习笔记(一):基本概念 媒体业务是网络的主要业务之间.尤其移动互联网业务的兴起,在运营商和应用开发商中,媒体业务份量极重,其中媒体的编解码服务涉及需求分析.应用开发.释放license收费等等 ...
- 【FFMPEG】各种音视频编解码学习详解 h264 ,mpeg4 ,aac 等所有音视频格式
目录(?)[-] 编解码学习笔记二codec类型 编解码学习笔记三Mpeg系列Mpeg 1和Mpeg 2 编解码学习笔记四Mpeg系列Mpeg 4 编解码学习笔记五Mpeg系列AAC音频 编解码学习笔 ...
- 了不起的WebRTC:生态日趋完善,或将实时音视频技术白菜化
本文原文由声网WebRTC技术专家毛玉杰分享. 1.前言 有人说 2017 年是 WebRTC 的转折之年,2018 年将是 WebRTC 的爆发之年,这并非没有根据.就在去年(2017年),WebR ...
- 从零到一,使用实时音视频 SDK 一起开发一款 Zoom 吧
zoom(zoom.us) 是一款受到广泛使用的在线会议软件.相信各位一定在办公.会议.聊天等各种场景下体验或者使用过,作为一款成熟的商业软件,zoom 提供了稳定的实时音视频通话质量,以及白板.聊天 ...
- 实时音视频互动系列(下):基于 WebRTC 技术的实战解析
在 WebRTC 项目中,又拍云团队做到了覆盖系统全局,保证项目进程流畅.这牵涉到主要三大块技术点: 网络端.服务端的开发和传输算法 WebRTC 协议中牵扯到服务端的应用协议和信令服务 客户端iOS ...
随机推荐
- c++ 子类调用父类构造方法 调用父类方法 类声明与实现分离
Person.h #pragma once #include "stdafx.h" #include<iostream> class Person { private: ...
- hdu 5294 最短路+最大流 ***
处理处最短路径图,这个比较巧妙 链接:点我
- 初探数位DP-hdu2089
一开始刷dp就遇到了数位dp,以前程序设计艺术上看过一点,基本没懂,于是趁今天遇到题目,想把它搞会,但就目前状态来看仍然是似懂非懂啊,以后还要反复搞 统计区间[l,r]的满足题意的数的个数,可以转换成 ...
- POJ 3241 Object Clustering 曼哈顿最小生成树
Object Clustering Description We have N (N ≤ 10000) objects, and wish to classify them into severa ...
- HDU 1561 The more, The Better 树形DP
The more, The Better Problem Description ACboy很喜欢玩一种战略游戏,在一个地图上,有N座城堡,每座城堡都有一定的宝物,在每次游戏中ACboy允许攻克M ...
- Codeforces Beta Round #77 (Div. 1 Only) C. Volleyball (最短路)
题目链接:http://codeforces.com/contest/95/problem/C 思路:首先dijkstra预处理出每个顶点到其他顶点的最短距离,然后如果该出租车到某个顶点的距离小于等于 ...
- Codeforces Beta Round #95 (Div. 2) D.Subway
题目链接:http://codeforces.com/problemset/problem/131/D 思路: 题目的意思是说给定一个无向图,求图中的顶点到环上顶点的最短距离(有且仅有一个环,并且环上 ...
- 如果 if - 迈克.杰克逊的墓志铭
引用http://www.duwenzhang.com/wenzhang/yingyuwenzhang/20110215/171059.html IF you can keep your head w ...
- ASP.NET MVC使用过滤器进行权限控制
1.新建MVC项目 2.找到Models文件夹,新建 LoginCheckFilterAttribute 类 public class LoginCheckFilterAttribute : Acti ...
- MapReduce中的分区方法Partitioner
在进行MapReduce计算时,有时候需要把最终的输出数据分到不同的文件中,比如按照省份划分的话,需要把同一省份的数据放到一个文件中:按照性别划分的话,需要把同一性别的数据放到一个文件中.我们知道最终 ...